AI Gateway mode, controlled by the CF_AI_GATEWAY env var, routes all AI inference through Cloudflare's shared gateway using server-managed provider credentials, eliminating the need for user API keys. Configuration determines routing: CF_AI_GATEWAY_WAI_DIRECT bypasses the gateway for Workers AI; CF_AI_GATEWAY_PROVIDERS filters which models are available; and credential validation ensures required gateway auth tokens are present. The "developer" role is supported by Cloudflare and OpenAI backends but is not a universal AI provider concept — local and third-party backends such as Ollama do not recognize it.
AI Gateway mode is enabled by setting the CF_AI_GATEWAY env var to a gateway name; when set, supported AI providers are routed through Cloudflare AI Gateway with server-managed keys, so users do not need their own API keys.[1] getAiGatewayConfig() in packages/workshop-backend/src/ai-gateway.ts returns null when CF_AI_GATEWAY is not set, indicating AI Gateway mode is disabled.[2] Outside AI Gateway mode, Workers AI (provider cloudflare) is BYOK — the account ID and API token live in the user's model config, not in the Worker's environment.[1] Gadget AI providers were switched to route all inference through the shared AI Gateway rather than calling provider APIs directly.[3] The workshop backend's AI Gateway support is implemented in packages/workshop-backend/src/ai-gateway.ts and packages/workshop-backend/src/ai-models.ts, wired into the agent and environment binding layer via env.d.ts.
docs/ai-gateway-billing.md describes billing implications of AI Gateway mode; docs/public-server.md describes public server configuration for AI features.
CF_AI_GATEWAY_ACCOUNT_ID and CF_AI_GATEWAY_API_TOKEN (a Run + Read token) are required whenever CF_AI_GATEWAY is set; AiGatewayConfig construction in packages/workshop-backend/src/ai-gateway.ts throws if either is missing.[2]
Setting CF_AI_GATEWAY_WAI_DIRECT to "true" routes Workers AI to its plain REST endpoint — no gateway, no cost logs — instead of a named Gateway.[1] Setting both CF_AI_GATEWAY_WAI and CF_AI_GATEWAY_WAI_DIRECT=true simultaneously throws a configuration error; the two options are mutually exclusive.[2] When CF_AI_GATEWAY_WAI_DIRECT is "true", AiGatewayConfig.workersAiGateway is set to undefined, disabling the Workers AI binding route; otherwise it falls back to CF_AI_GATEWAY_WAI and then to the main CF_AI_GATEWAY gateway.[2]
AiGatewayConfig.providers is parsed from CF_AI_GATEWAY_PROVIDERS, a comma-separated string; empty entries are stripped.[2] AiGatewayConfig.getModelList() returns only models whose provider is listed in CF_AI_GATEWAY_PROVIDERS; models from unlisted providers are silently excluded.[2] AiGatewayConfig.resolveModel() populates apiToken and apiUrl as empty strings in the returned UserAiModelRecord, because real credentials are read from env at inference time — not stored in the record.[2] AiGatewayConfig.getQuickModelConfig() always uses the cloudflare (Workers AI) provider for the quick model, regardless of which gateway providers are configured.[2] In ai-models.ts, the "developer" role is excluded from the Ollama code path; passing it to Ollama caused failures and has been removed. The pi dependency in packages/workshop-backend/package.json includes Workers AI model definitions for the DeepSeek V4 family; without it, the backend cannot resolve DeepSeek V4 model identifiers at runtime. DeepSeek V4 Pro 0813 is available as a selectable model in the Workshop; packages/workshop-shared/src/api.ts adds it to the suggested models list exposed over the public API. packages/workshop-shared/src/api.ts is the source of truth for the available model catalogue; the model registry is synchronized with the AI model test suite in packages/workshop-backend/__tests__/ai-models.test.ts. GLM 5.3 Flash is available as a selectable model in the Workshop; packages/workshop-shared/src/api.ts adds it to the suggested models list exposed over the public API.
getAiGatewayLogCost() in packages/workshop-backend/src/ai-gateway.ts uses two retrieval paths: if the route has no accountId, it uses the Workers AI binding (env.WORKERS_AI.gateway(...).getLog()); otherwise it calls the REST API at api.cloudflare.com, applying a 10-second timeout via AbortSignal.timeout(10_000).[2] AiGatewayLogRetryableError signals transient failures in AI Gateway log lookups — including network errors, 404/408/429/5xx responses, and unreadable response bodies — that the caller should retry.[2] A cost value of undefined or null from an AI Gateway log record also throws AiGatewayLogRetryableError ("not available yet"), indicating the log exists but cost has not yet been computed.[2]
Sources