From 3ef72fe8f6c54a31e9709e6dff82dc609df8e453 Mon Sep 17 00:00:00 2001 From: Charlie Gleason Date: Mon, 24 Aug 2026 22:01:17 -0500 Subject: [PATCH] fix(provider): route non-native Cloudflare AI Gateway providers via the REST API (#44828) Co-authored-by: Claude Opus 4.8 --- packages/opencode/src/provider/provider.ts | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/packages/opencode/src/provider/provider.ts b/packages/opencode/src/provider/provider.ts index 32e01512fbe..0f8cbd23f77 100644 --- a/packages/opencode/src/provider/provider.ts +++ b/packages/opencode/src/provider/provider.ts @@ -809,6 +809,7 @@ function custom(dep: CustomDep): Record { const { createUnified } = yield* Effect.promise(() => import("ai-gateway-provider/providers/unified")) const { createOpenAI } = yield* Effect.promise(() => import("ai-gateway-provider/providers/openai")) const { createAnthropic } = yield* Effect.promise(() => import("ai-gateway-provider/providers/anthropic")) + const { createOpenAICompatible } = yield* Effect.promise(() => import("@ai-sdk/openai-compatible")) const metadata = iife(() => { if (input.options?.metadata) return input.options.metadata @@ -855,9 +856,23 @@ function custom(dep: CustomDep): Record { // The Unified API addresses Workers AI both with the explicit "workers-ai/" prefix and as // bare "@cf/..." ids. Third-party providers must not receive the token; they rely on the // gateway's stored/BYOK keys instead. + // Workers AI is Cloudflare's own upstream, so it rides the unified compat route with the + // Cloudflare token as its upstream Authorization header. const isWorkersAi = modelID.startsWith("workers-ai/") || modelID.startsWith("@cf/") - const unified = createUnified(isWorkersAi ? { apiKey: apiToken } : {}) - return aigateway(unified(modelID)) + if (isWorkersAi) return aigateway(createUnified({ apiKey: apiToken })(modelID)) + + // Every other third-party provider (google, xai, alibaba, deepseek, moonshotai, …) is only + // served by Cloudflare's catalog-aware REST API. The universal/compat gateway route rejects + // them with "Invalid provider" (the gateway's compat endpoint doesn't front those upstreams), + // so point an OpenAI-compatible client at the REST endpoint and bind it to the gateway with + // cf-aig-gateway-id — that keeps requests gateway-routed (analytics/caching/BYOK), not a + // bypass. models.dev ids (provider/model, dotted) pass through unchanged. + return createOpenAICompatible({ + name: "cloudflare-ai-gateway", + baseURL: `https://api.cloudflare.com/client/v4/accounts/${accountId}/ai/v1`, + apiKey: apiToken, + headers: { "cf-aig-gateway-id": gateway }, + })(modelID) }, options: {}, }