Skip to content

Add gemini demo#62

Open
czerwiukk wants to merge 1 commit intomainfrom
FCE-2914/gemini-demo
Open

Add gemini demo#62
czerwiukk wants to merge 1 commit intomainfrom
FCE-2914/gemini-demo

Conversation

@czerwiukk
Copy link
Copy Markdown
Member

No description provided.

@czerwiukk czerwiukk self-assigned this Mar 27, 2026
Copilot AI review requested due to automatic review settings March 27, 2026 12:40
@linear
Copy link
Copy Markdown

linear bot commented Mar 27, 2026

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a new gemini-demo workspace that provides a minimal end-to-end demo of a Fishjam video call with a Gemini Live voice agent, including a React (Vite) frontend, a Fastify+tRPC backend, and containerized deployment via Docker Compose + Nginx.

Changes:

  • Add a Yarn-workspaces-based demo project with backend (Fastify + tRPC + Fishjam SDK + Gemini Live) and web (React + Vite) apps.
  • Add Dockerfiles and docker-compose.yml + nginx.conf to run the demo as three services (backend/web/nginx).
  • Add TypeScript configs, Vite config, and lockfile for reproducible installs.

Reviewed changes

Copilot reviewed 34 out of 37 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
gemini-demo/yarn.lock Adds the dependency lockfile for the demo workspace.
gemini-demo/package.json Defines the Yarn workspace layout and build/typecheck scripts.
gemini-demo/.yarnrc.yml Configures Yarn node-modules linker for the demo workspace.
gemini-demo/.gitignore Ignores node_modules, dist, env, logs for the demo.
gemini-demo/.env.example Example environment variables for backend + Vite.
gemini-demo/.dockerignore Reduces Docker build context for the demo.
gemini-demo/README.md Documents demo purpose, setup, and architecture.
gemini-demo/docker-compose.yml Defines backend, web, and nginx services for the demo.
gemini-demo/nginx.conf Reverse-proxy config for /api and frontend.
gemini-demo/backend/.yarnrc.yml Yarn config for backend workspace.
gemini-demo/backend/package.json Backend dependencies/scripts and type export for AppRouter.
gemini-demo/backend/tsconfig.json Backend TS compiler settings for Node ESM build output.
gemini-demo/backend/Dockerfile Multi-stage backend build/run container setup.
gemini-demo/backend/src/main.ts Fastify server startup + tRPC HTTP + WS setup.
gemini-demo/backend/src/router.ts tRPC router with getPeerToken and createAgent procedures.
gemini-demo/backend/src/config.ts Env loading and validation for required backend config.
gemini-demo/backend/src/clients.ts Initializes Fishjam and Gemini clients from config.
gemini-demo/backend/src/peers.ts Room creation/lookup and peer token issuance.
gemini-demo/backend/src/agents.ts Gemini Live session wiring to Fishjam agent tracks + tools.
gemini-demo/web/package.json Web app dependencies and Vite/TS build scripts.
gemini-demo/web/index.html Vite entry HTML for the web app.
gemini-demo/web/vite.config.ts Vite config with dev proxy to backend under /api.
gemini-demo/web/tsconfig.json TS project references for app + node configs.
gemini-demo/web/tsconfig.app.json Web app TS compiler options and include paths.
gemini-demo/web/tsconfig.node.json TS config for Vite config build/typechecking.
gemini-demo/web/Dockerfile Multi-stage static build and runtime serving for web.
gemini-demo/web/src/vite-env.d.ts Declares VITE_FISHJAM_ID env typing.
gemini-demo/web/src/trpc.ts Sets up tRPC client with HTTP batch + WS split link.
gemini-demo/web/src/main.tsx React entry point wiring FishjamProvider.
gemini-demo/web/src/App.tsx Simple lobby/call view routing and leave handling.
gemini-demo/web/src/components/Lobby.tsx UI for room/name input, peer token fetch, device init, join.
gemini-demo/web/src/components/CallView.tsx In-call UI with peer tiles, controls, agent start modal.
gemini-demo/web/src/components/PeerTile.tsx Video/audio tile for a peer.
gemini-demo/web/src/components/AgentTile.tsx Agent tile rendering + audio playback and animation.
gemini-demo/web/src/components/SystemPromptModal.tsx Modal to set agent system prompt.
gemini-demo/web/src/components/Toolbar.tsx Header bar with room info and agent/leave actions.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +11 to +18
"dependencies": {
"@fishjam-cloud/react-client": "^0.22.0",
"@trpc/client": "^11.6.0",
"@trpc/server": "^11.6.0",
"gemini-demo-backend": "workspace:*",
"react": "^19.1.1",
"react-dom": "^19.1.1"
},
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@trpc/server is listed as a dependency but doesn’t appear to be used anywhere in the web app. Removing unused deps reduces install size and avoids accidentally bundling server-only code.

Copilot uses AI. Check for mistakes.
peerName: trimmedPeerName,
});

props.onJoined(roomId, roomName);
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

onJoined is called with the untrimmed roomName state even though you compute trimmedRoomName. This can lead to displaying a room name with leading/trailing spaces even though the backend uses the trimmed value; pass trimmedRoomName instead.

Suggested change
props.onJoined(roomId, roomName);
props.onJoined(roomId, trimmedRoomName);

Copilot uses AI. Check for mistakes.
@@ -0,0 +1,22 @@
import { initTRPC } from "@trpc/server";
import z from "zod";
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

zod does not provide a default export in v4; import z from "zod" will fail typechecking and likely break at runtime. Switch to a named import (e.g. import { z } from "zod") or a namespace import.

Suggested change
import z from "zod";
import { z } from "zod";

Copilot uses AI. Check for mistakes.
import z from "zod";
import dotenv from "dotenv";

dotenv.config({ path: "../.env", quiet: true });
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dotenv.config options type doesn’t include quiet, so this will fail TypeScript typechecking with strict enabled. Remove quiet (or gate it behind a cast) and rely on dotenv’s standard options (e.g. debug) if needed.

Suggested change
dotenv.config({ path: "../.env", quiet: true });
dotenv.config({ path: "../.env" });

Copilot uses AI. Check for mistakes.
Comment on lines +32 to +33
ENTRYPOINT ["dumb-init", "--"]
CMD ["npx", "serve", "-s", "web/dist", "-l", "tcp://0.0.0.0:3000"]
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This image runs npx serve ... but serve isn’t installed in the image, so startup will download it from the network at runtime (often disallowed in prod) and makes builds non-reproducible. Install serve during the image build (or use a dedicated static server like nginx) and invoke it without npx fetching.

Copilot uses AI. Check for mistakes.
Comment on lines +46 to +52
<input
style={styles.input}
placeholder="Room name"
value={roomName}
onChange={(e) => setRoomName(e.target.value)}
onKeyDown={(e) => e.key === "Enter" && handleSubmit()}
autoFocus
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pressing Enter triggers handleSubmit() even when joining is not allowed (empty fields or already loading). Gate the Enter handler on canJoin and/or add an early if (!canJoin) return; guard inside handleSubmit to prevent invalid backend calls.

Copilot uses AI. Check for mistakes.

export const appRouter = t.router({
getPeerToken: t.procedure
.input(z.object({ roomName: z.string().min(1), peerName: z.string() }))
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Server-side validation currently allows an empty peerName (z.string()), even though the UI blocks empty names. Consider enforcing peerName: z.string().min(1) to prevent creating peers with blank names via direct API calls or Enter-key submission.

Suggested change
.input(z.object({ roomName: z.string().min(1), peerName: z.string() }))
.input(z.object({ roomName: z.string().min(1), peerName: z.string().min(1) }))

Copilot uses AI. Check for mistakes.
@@ -0,0 +1,13 @@
import z from "zod";
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

zod does not provide a default export in v4; import z from "zod" will fail typechecking and likely break at runtime. Use a named import (import { z } from "zod") or namespace import instead.

Suggested change
import z from "zod";
import { z } from "zod";

Copilot uses AI. Check for mistakes.
Comment on lines +5 to +9
"lib": ["ES2023", "DOM", "DOM.Iterable"],
"module": "ESNext",
"types": ["vite/client"],
"skipLibCheck": true,
"moduleResolution": "bundler",
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tsconfig.app.json restricts global type packages to only vite/client via "types", but the code uses the React namespace types (e.g. React.CSSProperties, React.ReactNode). This will cause typecheck/build failures unless you add React types here (e.g. include react/react-dom) or remove the types restriction.

Copilot uses AI. Check for mistakes.
Comment on lines +20 to +37
2. Install dependencies:

```
cd backend && npm install
cd ../web && npm install
```

3. Start the backend:

```
cd backend && npm run start
```

4. Start the frontend (in another terminal):

```
cd web && npm run start
```
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

README setup steps use npm install/npm run, but this demo is configured for Yarn workspaces (packageManager: yarn@4.12.0) and relies on the workspace-level yarn.lock. Update the instructions to use Yarn commands (e.g. yarn install, yarn workspace gemini-demo-backend start, yarn workspace gemini-demo-web start).

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants