Cloudflare scaffold recommends the keyless cloudflare/... model but never declares the AI binding it requires
Describe the Bug
flue init --target cloudflare --deploy scaffolds a starter whose own comment recommends switching to a keyless Workers AI model, but the AI binding that model needs is never declared — not by the scaffold, and not by flueWorkerConfig(). Following the scaffold's advice leaves env.AI undefined.
The generated src/agents/hello.ts says:
// Cloudflare's built-in models need no API key — swap in e.g.
// useModel('cloudflare/@cf/moonshotai/kimi-k2.6') to go keyless.
useModel('anthropic/claude-haiku-4-5');The cloudflare provider resolves through the Workers AI binding (cloudflareBindingProvider({ binding: env.AI, ... })), so cloudflare/... specifiers require an AI binding to exist. The Models guide says so explicitly and tells the user to declare it by hand:
{ "ai": { "binding": "AI" } }Nothing fills that gap automatically. flueWorkerConfig() documents its exact contributions — main, one Durable Object binding per scanned agent, the nodejs_compat flag, and compatibility_date validation — and ai is not among them. The generated wrangler.jsonc declares none either.
Directly observed, by inspecting the emitted deploy config dist/<worker>/wrangler.json from two builds of the same scaffolded project:
wrangler.jsonc |
ai in emitted config |
durable_objects in emitted config |
|---|---|---|
exactly as flue init wrote it |
null |
{"bindings":[{"name":"FLUE_HELLO_AGENT","class_name":"FlueHelloAgent"}]} |
with "ai": { "binding": "AI" } added |
{"binding":"AI"} |
identical |
The Durable Object binding is auto-injected in both cases, which confirms the customizer runs and contributes what it owns — ai is simply not part of that set, so the omission is structural rather than a resolution failure.
Expected Behavior
For the Cloudflare target, either:
- the scaffold writes
"ai": { "binding": "AI" }intowrangler.jsonc, so the keyless path its own starter comment advertises works on a fresh project; or - the starter comment shouldn't recommend a model whose binding the scaffold doesn't declare.
The first seems preferable, since "zero API key on Cloudflare" is otherwise a real property of the target.
Steps to Reproduce
npx @flue/[email protected] init my-app --target cloudflare --deploycd my-app && npm installnpx vite build, then inspectdist/<worker>/wrangler.json—aiisnulland noAIbinding is declared anywhere in the project- Take the starter's own suggestion and use
useModel('cloudflare/@cf/moonshotai/kimi-k2.6')—env.AIis undefined at runtime
Environment: @flue/cli 2.1.0, npm 10.9.2, Node v24.14.0, Windows 11.
Scope note: I did not execute the deployed Worker (no Cloudflare credentials in this environment), so the runtime failure itself is inferred from the missing binding in the emitted deploy config plus the documented requirement. The emitted-config comparison above is directly observed.
Source: withastro/flue