Flue + Jev through Cloudflare AI Gateway
September 18, 2026 · View on GitHub
A standalone Cloudflare-targeted Flue example. Application AI requests go through the Worker's AI binding and its default AI Gateway:
- Flue chat turns use
cloudflare/openai/gpt-4o-mini. - Typed routing uses TypeSafe Jev (
typesafe/jev). - There are no application API keys or account-ID environment variables.
This project uses the published npm packages @flue/runtime@2.0.8 and @flue/vite@2.0.8; it is not part of the Flue monorepo.
The agent
useJevRouter() turns a typed question map into a validated route_with_jev Flue tool. The agent can call Jev and receive structured choices, probabilities, and confidence without treating Jev as its chat model:
'use agent';
import { useModel } from '@flue/runtime';
import { type JevQuestion, useJevRouter } from '../flue-jev.ts';
const supportQuestions = {
intent: {
type: 'choice',
instructions: 'Which support team should handle this request?',
criteria: {
billing: 'Charges, refunds, subscriptions, invoices, and payment methods',
technical: 'Bugs, outages, errors, configuration, and integrations',
human: 'Ambiguous, sensitive, abusive, or explicitly asks for a person',
},
},
isUrgent: {
type: 'noul',
instructions: 'Does this request need immediate attention?',
criteria: {
true: 'The customer is blocked, losing money, or reporting an active outage',
false: 'The request can safely follow the normal support queue',
},
},
} as const satisfies Record<string, JevQuestion>;
export function SupportAgent() {
useModel('cloudflare/openai/gpt-4o-mini');
useJevRouter(supportQuestions);
return `
Route incoming support requests.
Call route_with_jev with the user's request as state.
Report the selected team, urgency, confidence, and Jev model.
`;
}
See the complete SupportAgent and useJevRouter() implementation.
Install and run
cd flue-jev-demo
pnpm install
pnpm dev
That is all the application configuration required. Wrangler uses your normal Cloudflare login and provides env.AI from wrangler.jsonc:
{
"ai": {
"binding": "AI"
}
}
If this machine has never authenticated Wrangler, run pnpm exec wrangler login once. The selected Cloudflare account needs AI Gateway credits for the third-party models.
If Wrangler belongs to more than one account, add that account's non-secret account_id to wrangler.jsonc before starting Vite. The server starts at the URL Vite prints, normally http://localhost:5173.
Try Jev directly
Run one authenticated Jev request and print the result with one command. This uses Wrangler's existing login, so it does not persist or require an API-token environment variable. When multiple accounts are available, the first run asks which account to use and saves the choice in the gitignored .wrangler-account file:
pnpm demo
Pass a different request as an argument:
pnpm demo -- "The app has been down for an hour and production is blocked."
The underlying route can also be called directly:
curl -sS http://localhost:5173/api/route \
-H 'content-type: application/json' \
-d '{"state":"I was charged twice for order A-123 and need the money back today."}'
Internally it runs:
await env.AI.run('typesafe/jev', { state, questions });
The response contains the typed intent, urgency, probabilities, confidence, Jev version, and usage.
Run the complete Flue agent
Submit a message:
curl -X POST http://localhost:5173/agents/support/demo-1 \
-H 'content-type: application/json' \
-d '{"kind":"user","body":"I was charged twice for order A-123 and need the money back today."}'
Then stream the durable conversation:
curl -N http://localhost:5173/agents/support/demo-1
Flue automatically registers its Cloudflare binding provider because vite.config.ts selects only the cloudflare provider. The chat model and the route_with_jev tool both call env.AI.run(...) with the default gateway, so both appear in the AI Gateway logs.
Verify
The tests mock the Worker binding and make no paid calls:
pnpm test
pnpm check:types
pnpm build
Credential-free health check while dev is running:
curl http://localhost:5173/api/health
Deploy with:
pnpm deploy
Files
wrangler.jsonc— Worker configuration, AI binding, and Flue Durable Object migration.vite.config.ts— Flue plus the official Cloudflare Vite plugin; only thecloudflareprovider is bundled.src/flue-jev.ts— typedenv.AI.run('typesafe/jev', ...)client, Flue tool factory, anduseJevRouter()hook.src/agents/support.ts— support-routing agent usingcloudflare/openai/gpt-4o-mini.src/app.ts— explicit Hono route map.