New Project
Three forms use Jev and AI SDK to route submissions by context.

Three forms use Jev to route submissions by context, with openai/gpt-5.6-luna-fast handling uncertain or failed evaluations. Includes editable samples, routing details, and optional email delivery.
| Technology | Purpose |
|---|---|
| Next.js 16 and React 19 | App Router, shared form UI, and Server Actions |
| AI SDK 7 and Vercel AI Gateway | Typed model calls and provider access |
| shadcn/ui, Base UI, and Tailwind CSS 4 | Components and styling |
| React Email and Resend | Email previews and optional delivery |
git clone https://github.com/vercel-labs/jev-ai-sdk-form-router.gitcd jev-ai-sdk-form-routerpnpm install
Routing a submission, including a sample, makes live model calls and requires AI Gateway access to both typesafe-ai/jev and openai/gpt-5.6-luna-fast. Choose one of the authentication options below, or skip this step to explore the forms and load sample inputs without generating routing results.
API Key
Copy the environment example:
cp .env.example .env.local
Create a Vercel AI Gateway key and set AI_GATEWAY_API_KEY in .env.local.
Vercel OIDC
Vercel deployments use automatic OIDC authentication through the SDK, without an API key. To use OIDC locally, install the Vercel CLI if needed, then link the project and pull its environment variables:
npm install --global vercelvercel linkvercel env pull .env.local
pnpm dev
Open localhost:3000. The home page redirects to /leads.
| Example | Route | Routes to |
|---|---|---|
| Lead | /leads | Startup, growth, enterprise, or sales teams |
| Contact | /contact | Billing, support, or general inquiries |
| Issue Report | /issues | Frontend, platform, infrastructure, identity, or engineering teams |
experimental_evaluate and selects an allowed team/specialty combination.openai/gpt-5.6-luna-fast independently evaluates the same submission and criteria using generateText and Output.object. Its choice becomes final.Confidence and selected-option probability are separate metrics. The threshold uses the unrounded value of providerMetadata.typesafe.confidence.destination. Jev’s displayed statistics remain attached to its original evaluation when the fallback model makes the final decision.
Provider calls have bounded timeouts and one transient retry. If both models fail, the app returns a retryable error and sends no email.
Set up Resend through Vercel Marketplace
The Resend Marketplace integration creates a Resend account and connects it to your Vercel project. During setup, you can select an existing Vercel domain or purchase one.
If you haven't already, install the Vercel CLI and link the project:
npm install --global vercelvercel link
Start the integration setup:
vercel i resend
Select an existing domain or purchase one through Vercel, then choose a plan and connect your project. Complete onboarding in Resend, choose Auto configure to add the DNS records, and wait for domain verification.
Pull the integration's environment variables for local development:
vercel env pull .env.local
Confirm RESEND_API_KEY is present and set RESEND_FROM in .env.local to a sender address on your verified domain.
If you already have a Resend account, you can instead set RESEND_API_KEY and RESEND_FROM directly using your existing API key and a verified domain.
Configure receiving inboxes
In lib/recipients.ts, replace null with a valid inbox for every destination on the form you want to enable. Multiple destinations can share an inbox.
An unchecked Email the receiving team checkbox appears on configured forms.
Recipient keys are derived from the destination registry and checked by TypeScript. Addresses stay server-side. The validated submitter email becomes replyTo. Forms with unconfigured inboxes continue to provide previews.
Email failures preserve the routing result. Resend acceptance does not confirm inbox delivery. If a connection drops after an opted-in submission, check Resend before resubmitting.
| File | What to change |
|---|---|
| lib/examples.ts | Form fields, samples, destinations, and routing criteria |
| lib/router.ts | Models, confidence threshold, timeouts, and fallback policy |
| lib/recipients.ts | Receiving inboxes |
| lib/submission.ts | Validation, email rendering, and delivery workflow |
| components/router-form.tsx and components/routing-result.tsx | Shared form and result UI |
| emails/routed-submission.tsx | Email design |
Keep the experimental AI SDK version pinned and rerun the checks when upgrading it.
pnpm fix # Format and apply lint fixespnpm validate # Lint, type check, Knip, and testspnpm build # Production build
Tests mock the model providers and Resend. They make no external calls. Coverage includes confidence thresholds, fallback decisions, validation, recipient configuration, and delivery retries.