From 96d6fb78da2b75806ffd94ec87c913c412db8896 Mon Sep 17 00:00:00 2001 From: Ryan Skidmore Date: Mon, 2 Mar 2026 21:53:03 -0600 Subject: [PATCH] fix(provider): forward metadata options to cloudflare-ai-gateway provider (#15619) --- packages/opencode/src/provider/provider.ts | 20 +++++- .../opencode/test/provider/provider.test.ts | 61 +++++++++++++++++++ 2 files changed, 80 insertions(+), 1 deletion(-) diff --git a/packages/opencode/src/provider/provider.ts b/packages/opencode/src/provider/provider.ts index 022ec3167..b480a91ea 100644 --- a/packages/opencode/src/provider/provider.ts +++ b/packages/opencode/src/provider/provider.ts @@ -555,7 +555,25 @@ export namespace Provider { const { createAiGateway } = await import("ai-gateway-provider") const { createUnified } = await import("ai-gateway-provider/providers/unified") - const aigateway = createAiGateway({ accountId, gateway, apiKey: apiToken }) + const metadata = iife(() => { + if (input.options?.metadata) return input.options.metadata + try { return JSON.parse(input.options?.headers?.["cf-aig-metadata"]) } + catch { return undefined } + }) + const opts = { + metadata, + cacheTtl: input.options?.cacheTtl, + cacheKey: input.options?.cacheKey, + skipCache: input.options?.skipCache, + collectLog: input.options?.collectLog, + } + + const aigateway = createAiGateway({ + accountId, + gateway, + apiKey: apiToken, + ...(Object.values(opts).some(v => v !== undefined) ? { options: opts } : {}), + }) const unified = createUnified() return { diff --git a/packages/opencode/test/provider/provider.test.ts b/packages/opencode/test/provider/provider.test.ts index 0a5aa4151..11c943db6 100644 --- a/packages/opencode/test/provider/provider.test.ts +++ b/packages/opencode/test/provider/provider.test.ts @@ -2218,3 +2218,64 @@ test("Google Vertex: supports OpenAI compatible models", async () => { }, }) }) + +test("cloudflare-ai-gateway loads with env variables", async () => { + await using tmp = await tmpdir({ + init: async (dir) => { + await Bun.write( + path.join(dir, "opencode.json"), + JSON.stringify({ + $schema: "https://opencode.ai/config.json", + }), + ) + }, + }) + await Instance.provide({ + directory: tmp.path, + init: async () => { + Env.set("CLOUDFLARE_ACCOUNT_ID", "test-account") + Env.set("CLOUDFLARE_GATEWAY_ID", "test-gateway") + Env.set("CLOUDFLARE_API_TOKEN", "test-token") + }, + fn: async () => { + const providers = await Provider.list() + expect(providers["cloudflare-ai-gateway"]).toBeDefined() + }, + }) +}) + +test("cloudflare-ai-gateway forwards config metadata options", async () => { + await using tmp = await tmpdir({ + init: async (dir) => { + await Bun.write( + path.join(dir, "opencode.json"), + JSON.stringify({ + $schema: "https://opencode.ai/config.json", + provider: { + "cloudflare-ai-gateway": { + options: { + metadata: { invoked_by: "test", project: "opencode" }, + }, + }, + }, + }), + ) + }, + }) + await Instance.provide({ + directory: tmp.path, + init: async () => { + Env.set("CLOUDFLARE_ACCOUNT_ID", "test-account") + Env.set("CLOUDFLARE_GATEWAY_ID", "test-gateway") + Env.set("CLOUDFLARE_API_TOKEN", "test-token") + }, + fn: async () => { + const providers = await Provider.list() + expect(providers["cloudflare-ai-gateway"]).toBeDefined() + expect(providers["cloudflare-ai-gateway"].options.metadata).toEqual({ + invoked_by: "test", + project: "opencode", + }) + }, + }) +})