Vercel Voice Agents PR - #324
Conversation
Codex reviewThe PR adds a Vercel voice-agent cookbook, but the new runtime route and CI/package metadata introduce regressions that can break the demo or future merges/releases. Findings not on changed lines:
The PR adds an AI SDK 7 cookbook ( |
| // Storing the promise means search requests block until ready, or fail fast if it rejects. | ||
| const indexReady = client.loadIndex(process.env.MOSS_INDEX_NAME!) | ||
| .then(() => console.log('[MOSS] index loaded locally')) | ||
| .catch((err: unknown) => { console.error('[MOSS] loadIndex failed:', err); throw err; }); |
There was a problem hiding this comment.
BLOCKING ```ts
.catch((err: unknown) => { console.error('[MOSS] loadIndex failed:', err); throw err; });
`indexReady` is created at module load, so if `loadIndex()` rejects before any search request awaits it, this rethrow leaves the stored promise rejected without a handler and can terminate the Node/Next process instead of returning the intended 503. Keep the startup promise fulfilled with status, then branch in the handler:
```ts
const indexReady = client.loadIndex(indexName)
.then(() => true)
.catch((err) => { console.error('[MOSS] loadIndex failed:', err); return false; });
if (!(await indexReady)) return new Response('Search index unavailable', { status: 503 });
| headers: { 'Content-Type': 'application/json' }, | ||
| body: JSON.stringify({ query, topK: topK ?? 5 }), | ||
| }); | ||
| const text = await res.text(); |
There was a problem hiding this comment.
CONSIDER ```ts
const text = await res.text();
`/api/token` deliberately returns non-2xx responses for auth and index-load failures, but this handler treats every response body as a successful tool result and returns it to the model. Check `res.ok` before counting hits or returning text so the UI surfaces failures instead of letting the assistant answer from `Unauthorized`, `Search index unavailable`, or an HTML error page:
```ts
if (!res.ok) {
const message = await res.text();
setError(message || `Search failed (${res.status})`);
throw new Error(message || `Search failed (${res.status})`);
}
const text = await res.text();
There was a problem hiding this comment.
Pull request overview
Adds a new Next.js cookbook example (examples/cookbook/vercel-voice-agent/) demonstrating a realtime browser voice agent using Vercel AI Gateway with MOSS as the knowledge base (token minting + tool-call search via a single /api/token route).
Changes:
- Introduces a Next.js app UI (client-side realtime voice + search lookup log) and a server route to mint gateway tokens and serve MOSS search results.
- Adds project scaffolding/configuration for TypeScript + Next (tsconfig, next config, env example, npm deps + lockfile).
- Documents setup and architecture for running the demo locally.
Reviewed changes
Copilot reviewed 8 out of 12 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| examples/cookbook/vercel-voice-agent/tsconfig.json | TypeScript/Next compiler configuration for the cookbook app. |
| examples/cookbook/vercel-voice-agent/README.md | Setup + architecture documentation for the voice agent demo. |
| examples/cookbook/vercel-voice-agent/package.json | Declares Next/AI Gateway/MOSS dependencies and Node engine requirement. |
| examples/cookbook/vercel-voice-agent/package-lock.json | Locks dependency versions for reproducible installs. |
| examples/cookbook/vercel-voice-agent/next.config.ts | Next.js config to externalize MOSS server packages. |
| examples/cookbook/vercel-voice-agent/next-env.d.ts | Next.js TS type references for the app. |
| examples/cookbook/vercel-voice-agent/app/page.tsx | Client UI + realtime session/tool-call wiring to /api/token. |
| examples/cookbook/vercel-voice-agent/app/layout.tsx | App shell metadata + basic styling/font. |
| examples/cookbook/vercel-voice-agent/app/api/token/route.ts | Server route to mint gateway tokens and execute MOSS search tool calls. |
| examples/cookbook/vercel-voice-agent/.env.example | Environment variable template for credentials and demo gating. |
Files not reviewed (1)
- examples/cookbook/vercel-voice-agent/package-lock.json: Generated file
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
I'll work on these changes |
|
I've addressed the outstanding Codex and Copilot review findings in #390 (targets this PR's |
…dling (#390) ## Summary Addresses the outstanding Codex and Copilot review findings on #324. Targets the `vercel-ai` branch so these fixes land inside that PR when merged. ## Blocking findings (Codex) - **Restored `.github/workflows/` to main's state** — brings back `python-test.yml` (a required status check that would otherwise hang protected-branch merges forever) and `codex-review.yml`, and reverts the unrelated edits to `ci.yml` / `vercel-sdk-release.yml`. - **Restored `packages/vercel-sdk/` to main's state** — the PR had rolled the package back to `0.1.0` with AI-6-only support (`"ai": "^6.0.0"`) while the new cookbook depends on `ai@^7`. It's back to `0.1.1` with `"ai": "^6.0.0 || ^7.0.0"`. ## Cookbook fixes (`examples/cookbook/vercel-voice-agent/`) - **`app/api/token/route.ts`** — the `indexReady` startup promise no longer rethrows in `.catch()`; it resolves to `true`/`false` and the handler returns 503 on failure, so a `loadIndex` error can't kill the process as an unhandled rejection (Codex, blocking). - **`app/page.tsx`** — the tool-call fetch now checks `res.ok`; non-2xx responses surface via `setError` and throw instead of being returned to the model as search results (Copilot/Codex). - **`.env.example`** — removed the unused `DEMO_SECRET` / `NEXT_PUBLIC_DEMO_SECRET` vars and corrected the comment to describe the actual `ALLOW_UNAUTHENTICATED_DEMO` gate (Copilot). - **`README.md`** — security note now matches the fail-closed 401 behavior (Copilot). - **`package.json`** — `@moss-dev/moss` pinned to `^1.3.1` instead of `latest`, with the lockfile mirror entry synced (Copilot). - **`tsconfig.json`** — added `.next/dev/types/**/*.ts` to `include`, matching `apps/moss-llamaindex/frontend` (Copilot). ## Additional fix required to compile - **`route.ts`** — `searchTool.execute` now passes `context: {}`: with the installed AI SDK 7, `context` is a required field on `ToolExecutionOptions`, so the example did not typecheck without it. No reviewer flagged this; `next build`'s type check did. ## Verification `npm install && npm run build` — compiles and the type check passes. (The subsequent page-data collection step fails on my machine only because the `@moss-dev/moss-core` native binding needs GLIBC 2.38 and my Debian host has 2.36 — unrelated to these changes.) --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - uses: actions/setup-python@v5 | ||
| with: | ||
| python-version: '3.12' | ||
| - name: Smoke check | ||
| run: python -c "print('python-test ok')" |
Voice agents with vercel ai sdk package.