diff --git a/packages/console/app/src/lib/inference-proxy.ts b/packages/console/app/src/lib/inference-proxy.ts index d6515c3386d9..d9014986d315 100644 --- a/packages/console/app/src/lib/inference-proxy.ts +++ b/packages/console/app/src/lib/inference-proxy.ts @@ -24,6 +24,8 @@ export async function proxyInference( provider?: "openai" | "anthropic" | "google" /** The provider's native model ID, not the public Zen alias. */ model?: string + /** Forward keyless requests for this model anonymously instead of serving them here. */ + anonymous?: boolean body: (model?: string) => ReadableStream }, ): Promise { @@ -41,10 +43,11 @@ export async function proxyInference( : path.startsWith("/google/") ? request.headers.get("x-goog-api-key") : request.headers.get("authorization")?.split(" ")[1] - if (!key || key === "public") return undefined + const anonymous = !key || key === "public" + if (anonymous && !generation?.anonymous) return undefined // New Console keys are never in the legacy key table; every legacy key is `sk-`. - const legacy = !key.startsWith("oc_sk_") + const legacy = !anonymous && !key.startsWith("oc_sk_") const workspace = legacy ? await migratedWorkspace(key, generation?.provider) : undefined if (legacy && !workspace) return undefined const model = workspace?.provider ? generation?.model : undefined @@ -80,7 +83,9 @@ export async function proxyInference( "content-length", ]) forwarded.headers.delete(name) - forwarded.headers.set("authorization", `Bearer ${key}`) + // Keyless requests must reach new inference without credentials; `public` is not an API key there. + if (anonymous) for (const name of ["authorization", "x-api-key", "x-goog-api-key"]) forwarded.headers.delete(name) + if (!anonymous) forwarded.headers.set("authorization", `Bearer ${key}`) forwarded.headers.set("CF-Access-Client-Id", Resource.CLOUDFLARE_ACCESS_CLIENT_ID.value) const ip = request.headers.get("cf-connecting-ip") if (ip) forwarded.headers.set("x-zen-ip", ip) diff --git a/packages/console/app/src/routes/zen/util/handler.ts b/packages/console/app/src/routes/zen/util/handler.ts index 269821e0e7e6..5583d15266b9 100644 --- a/packages/console/app/src/routes/zen/util/handler.ts +++ b/packages/console/app/src/routes/zen/util/handler.ts @@ -57,6 +57,9 @@ type ZenData = Awaited> type PreparedBody = Awaited> type BillingSource = "anonymous" | "free" | "byok" | "subscription" | "lite" | "balance" +// Free models whose keyless requests skip legacy checks and go straight to new inference. +const ANONYMOUS_PROXY_MODELS = new Set(["ling-3.1-flash-free", "nemotron-3.5-lightning-free"]) + function resolve(text: string, params?: Record) { if (!params) return text return text.replace(/\{\{(\w+)\}\}/g, (raw, key) => { @@ -115,6 +118,7 @@ export async function handler( opts.modelList === "full" ? entry?.providers.find((provider) => provider.id === entry.byokProvider)?.model : undefined, + anonymous: opts.modelList === "full" && ANONYMOUS_PROXY_MODELS.has(model), body: (providerModel) => requestBody?.stream(providerModel ?? model, false) ?? body, }).catch(() => { void (requestBody ? requestBody.cancel() : body.cancel()).catch(() => {})