From 2b4a2e7262b477d426d08254b18065ea71b414a6 Mon Sep 17 00:00:00 2001 From: Aiden Cline Date: Tue, 3 Feb 2026 23:19:04 -0600 Subject: [PATCH 1/4] wip --- packages/opencode/src/provider/provider.ts | 56 ++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/packages/opencode/src/provider/provider.ts b/packages/opencode/src/provider/provider.ts index fc90571fefdc..fba7814609e3 100644 --- a/packages/opencode/src/provider/provider.ts +++ b/packages/opencode/src/provider/provider.ts @@ -455,6 +455,47 @@ export namespace Provider { }, } }, + // Cloudflare + // data: {"id":"id-1770181099419","created":1770181099,"model":"@cf/openai/gpt-oss-120b","object":"chat.completion.chunk","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"tool_calls","stop_reason":200012,"token_ids":null}]} + // data: {"id":"id-1770181099419","object":"chat.completion.chunk","created":1770181099,"model":"@cf/openai/gpt-oss-120b","choices":[{"index":0,"delta":{},"finish_reason":"stop"}],"usage":{"prompt_tokens":13200,"total_tokens":13272,"completion_tokens":72}} + // data: {"id":"id-1770181099419","object":"chat.completion.chunk","created":1770181099,"model":"@cf/openai/gpt-oss-120b","choices":[{"index":0,"delta":{},"finish_reason":"stop"}],"usage":{"prompt_tokens":13200,"completion_tokens":72,"total_tokens":13272}} + + // Vercel + // data: {"type":"reasoning-end","id":"reasoning-0"} + // data: {"type":"text-end","id":"txt-0"} + // data: {"type":"finish","finishReason":"stop","usage":{"inputTokens":23070,"outputTokens":1323,"totalTokens":24393,"cachedInputTokens":20736},"providerMetadata":{"gateway":{"routing":{"originalModelId":"openai/gpt-oss-safeguard-20b","resolvedProvider":"groq","resolvedProviderApiModelId":"openai/gpt-oss-safeguard-20b","internalResolvedModelId":"groq:openai/gpt-oss-safeguard-20b","fallbacksAvailable":[],"internalReasoning":"Selected groq as preferred provider for gpt-oss-safeguard-20b. 0 fallback(s) available: ","planningReasoning":"System credentials planned for: groq. Total execution order: groq(system)","canonicalSlug":"openai/gpt-oss-safeguard-20b","finalProvider":"groq","attempts":[{"provider":"groq","internalModelId":"groq:openai:gpt-oss-safeguard-20b","providerApiModelId":"openai/gpt-oss-safeguard-20b","credentialType":"system","success":true,"startTime":1745804.194121,"endTime":1745980.755015,"statusCode":200}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"openai/gpt-oss-safeguard-20b","canonicalSlug":"openai/gpt-oss-safeguard-20b","success":true,"providerAttemptCount":1,"providerAttempts":[{"provider":"groq","internalModelId":"groq:openai:gpt-oss-safeguard-20b","providerApiModelId":"openai/gpt-oss-safeguard-20b","credentialType":"system","success":true,"startTime":1745804.194121,"endTime":1745980.755015,"statusCode":200}]}],"totalProviderAttemptCount":1},"cost":"0.002894382","marketCost":"0.002894382","generationId":"gen_01KGKGB62XAAEFB44Z0FYXRDGJ","billableWebSearchCalls":0}}} + + // openrouter + // data: {"id":"gen-1770181425-2H1N7QXzh0rwkVi4x447","provider":"OpenAI","model":"openai/gpt-4.1","object":"chat.completion.chunk","created":1770181425,"choices":[{"index":0,"delta":{"role":"assistant","content":"!"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]} + // data: {"id":"gen-1770181425-2H1N7QXzh0rwkVi4x447","provider":"OpenAI","model":"openai/gpt-4.1","object":"chat.completion.chunk","created":1770181425,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":"stop","native_finish_reason":"completed","logprobs":null}]} + // data: {"id":"gen-1770181425-2H1N7QXzh0rwkVi4x447","provider":"OpenAI","model":"openai/gpt-4.1","object":"chat.completion.chunk","created":1770181425,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":36599,"completion_tokens":1146,"total_tokens":37745,"cost":0.027838,"is_byok":false,"prompt_tokens_details":{"cached_tokens":36352},"cost_details":{"upstream_inference_cost":0.027838,"upstream_inference_prompt_cost":0.01867,"upstream_inference_completions_cost":0.009168},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}} + // data: [DONE] + + "cloudflare-workers-ai": async (input) => { + const accountId = process.env.CLOUDFLARE_ACCOUNT_ID ?? Env.get("CLOUDFLARE_ACCOUNT_ID") + const token = + process.env.CLOUDFLARE_API_TOKEN ?? + process.env.CLOUDFLARE_API_KEY ?? + Env.get("CLOUDFLARE_API_TOKEN") ?? + Env.get("CLOUDFLARE_API_KEY") + const auth = await Auth.get(input.id) + const key = (token ?? (auth?.type === "api" ? auth.key : undefined))?.trim() + if (!accountId) return { autoload: false } + // createOpenAICompatible(). + + return { + autoload: true, + options: { + baseURL: `https://api.cloudflare.com/client/v4/accounts/${accountId}/ai/v1`, + // apiKey + ...(key ? { apiKey: key } : {}), + headers: {}, + }, + async getModel(sdk: any, modelID: string) { + return sdk.languageModel(modelID) + }, + } + }, "cloudflare-ai-gateway": async (input) => { const accountId = Env.get("CLOUDFLARE_ACCOUNT_ID") const gateway = Env.get("CLOUDFLARE_GATEWAY_ID") @@ -708,6 +749,21 @@ export namespace Provider { })), } } + if (database["cloudflare-workers-ai"]) { + const cfworkersai = database["cloudflare-workers-ai"] + database["cloudflare-workers-ai"] = { + ...cfworkersai, + models: mapValues(cfworkersai.models, (model) => { + return { + ...model, + api: { + ...model.api, + npm: "@ai-sdk/openai-compatible", + }, + } + }), + } + } function mergeProvider(providerID: string, provider: Partial) { const existing = providers[providerID] From dfef8bcb9b4a2eb72e7b26e6f0de95bd0874ee2f Mon Sep 17 00:00:00 2001 From: Aiden Cline Date: Wed, 4 Feb 2026 11:24:00 -0600 Subject: [PATCH 2/4] fix --- packages/opencode/src/bun/index.ts | 10 ++---- packages/opencode/src/config/config.ts | 25 +++++++++++--- packages/opencode/src/provider/provider.ts | 40 ++++++---------------- packages/opencode/src/util/proxied.ts | 3 ++ 4 files changed, 37 insertions(+), 41 deletions(-) create mode 100644 packages/opencode/src/util/proxied.ts diff --git a/packages/opencode/src/bun/index.ts b/packages/opencode/src/bun/index.ts index 19edb6eec4b0..bdb7cff78e25 100644 --- a/packages/opencode/src/bun/index.ts +++ b/packages/opencode/src/bun/index.ts @@ -7,6 +7,7 @@ import { NamedError } from "@opencode-ai/util/error" import { readableStreamToText } from "bun" import { Lock } from "../util/lock" import { PackageRegistry } from "./registry" +import { proxied } from "@/util/proxied" export namespace BunProc { const log = Log.create({ service: "bun" }) @@ -86,20 +87,13 @@ export namespace BunProc { log.info("Cached version is outdated, proceeding with install", { pkg, cachedVersion }) } - const proxied = !!( - process.env.HTTP_PROXY || - process.env.HTTPS_PROXY || - process.env.http_proxy || - process.env.https_proxy - ) - // Build command arguments const args = [ "add", "--force", "--exact", // TODO: get rid of this case (see: https://github.com/oven-sh/bun/issues/19936) - ...(proxied ? ["--no-cache"] : []), + ...(proxied() ? ["--no-cache"] : []), "--cwd", Global.Path.cache, pkg + "@" + version, diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts index 91816a00fcc3..5fde2aed87d1 100644 --- a/packages/opencode/src/config/config.ts +++ b/packages/opencode/src/config/config.ts @@ -29,6 +29,7 @@ import { Bus } from "@/bus" import { GlobalBus } from "@/bus/global" import { Event } from "../server/event" import { PackageRegistry } from "@/bun/registry" +import { proxied } from "@/util/proxied" export namespace Config { const log = Log.create({ service: "config" }) @@ -247,13 +248,29 @@ export namespace Config { const hasGitIgnore = await Bun.file(gitignore).exists() if (!hasGitIgnore) await Bun.write(gitignore, ["node_modules", "package.json", "bun.lock", ".gitignore"].join("\n")) - await BunProc.run(["add", `@opencode-ai/plugin@${targetVersion}`, "--exact"], { - cwd: dir, - }).catch(() => {}) + await BunProc.run( + [ + "add", + `@opencode-ai/plugin@${targetVersion}`, + "--exact", + // TODO: get rid of this case (see: https://github.com/oven-sh/bun/issues/19936) + ...(proxied() ? ["--no-cache"] : []), + ], + { + cwd: dir, + }, + ).catch(() => {}) // Install any additional dependencies defined in the package.json // This allows local plugins and custom tools to use external packages - await BunProc.run(["install"], { cwd: dir }).catch(() => {}) + await BunProc.run( + [ + "install", + // TODO: get rid of this case (see: https://github.com/oven-sh/bun/issues/19936) + ...(proxied() ? ["--no-cache"] : []), + ], + { cwd: dir }, + ).catch(() => {}) } async function needsInstall(dir: string) { diff --git a/packages/opencode/src/provider/provider.ts b/packages/opencode/src/provider/provider.ts index d79a95946e24..4b8277b0307f 100644 --- a/packages/opencode/src/provider/provider.ts +++ b/packages/opencode/src/provider/provider.ts @@ -457,41 +457,23 @@ export namespace Provider { }, } }, - // Cloudflare - // data: {"id":"id-1770181099419","created":1770181099,"model":"@cf/openai/gpt-oss-120b","object":"chat.completion.chunk","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"tool_calls","stop_reason":200012,"token_ids":null}]} - // data: {"id":"id-1770181099419","object":"chat.completion.chunk","created":1770181099,"model":"@cf/openai/gpt-oss-120b","choices":[{"index":0,"delta":{},"finish_reason":"stop"}],"usage":{"prompt_tokens":13200,"total_tokens":13272,"completion_tokens":72}} - // data: {"id":"id-1770181099419","object":"chat.completion.chunk","created":1770181099,"model":"@cf/openai/gpt-oss-120b","choices":[{"index":0,"delta":{},"finish_reason":"stop"}],"usage":{"prompt_tokens":13200,"completion_tokens":72,"total_tokens":13272}} - - // Vercel - // data: {"type":"reasoning-end","id":"reasoning-0"} - // data: {"type":"text-end","id":"txt-0"} - // data: {"type":"finish","finishReason":"stop","usage":{"inputTokens":23070,"outputTokens":1323,"totalTokens":24393,"cachedInputTokens":20736},"providerMetadata":{"gateway":{"routing":{"originalModelId":"openai/gpt-oss-safeguard-20b","resolvedProvider":"groq","resolvedProviderApiModelId":"openai/gpt-oss-safeguard-20b","internalResolvedModelId":"groq:openai/gpt-oss-safeguard-20b","fallbacksAvailable":[],"internalReasoning":"Selected groq as preferred provider for gpt-oss-safeguard-20b. 0 fallback(s) available: ","planningReasoning":"System credentials planned for: groq. Total execution order: groq(system)","canonicalSlug":"openai/gpt-oss-safeguard-20b","finalProvider":"groq","attempts":[{"provider":"groq","internalModelId":"groq:openai:gpt-oss-safeguard-20b","providerApiModelId":"openai/gpt-oss-safeguard-20b","credentialType":"system","success":true,"startTime":1745804.194121,"endTime":1745980.755015,"statusCode":200}],"modelAttemptCount":1,"modelAttempts":[{"modelId":"openai/gpt-oss-safeguard-20b","canonicalSlug":"openai/gpt-oss-safeguard-20b","success":true,"providerAttemptCount":1,"providerAttempts":[{"provider":"groq","internalModelId":"groq:openai:gpt-oss-safeguard-20b","providerApiModelId":"openai/gpt-oss-safeguard-20b","credentialType":"system","success":true,"startTime":1745804.194121,"endTime":1745980.755015,"statusCode":200}]}],"totalProviderAttemptCount":1},"cost":"0.002894382","marketCost":"0.002894382","generationId":"gen_01KGKGB62XAAEFB44Z0FYXRDGJ","billableWebSearchCalls":0}}} - - // openrouter - // data: {"id":"gen-1770181425-2H1N7QXzh0rwkVi4x447","provider":"OpenAI","model":"openai/gpt-4.1","object":"chat.completion.chunk","created":1770181425,"choices":[{"index":0,"delta":{"role":"assistant","content":"!"},"finish_reason":null,"native_finish_reason":null,"logprobs":null}]} - // data: {"id":"gen-1770181425-2H1N7QXzh0rwkVi4x447","provider":"OpenAI","model":"openai/gpt-4.1","object":"chat.completion.chunk","created":1770181425,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":"stop","native_finish_reason":"completed","logprobs":null}]} - // data: {"id":"gen-1770181425-2H1N7QXzh0rwkVi4x447","provider":"OpenAI","model":"openai/gpt-4.1","object":"chat.completion.chunk","created":1770181425,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"native_finish_reason":null,"logprobs":null}],"usage":{"prompt_tokens":36599,"completion_tokens":1146,"total_tokens":37745,"cost":0.027838,"is_byok":false,"prompt_tokens_details":{"cached_tokens":36352},"cost_details":{"upstream_inference_cost":0.027838,"upstream_inference_prompt_cost":0.01867,"upstream_inference_completions_cost":0.009168},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0}}} - // data: [DONE] - "cloudflare-workers-ai": async (input) => { - const accountId = process.env.CLOUDFLARE_ACCOUNT_ID ?? Env.get("CLOUDFLARE_ACCOUNT_ID") - const token = - process.env.CLOUDFLARE_API_TOKEN ?? - process.env.CLOUDFLARE_API_KEY ?? - Env.get("CLOUDFLARE_API_TOKEN") ?? - Env.get("CLOUDFLARE_API_KEY") - const auth = await Auth.get(input.id) - const key = (token ?? (auth?.type === "api" ? auth.key : undefined))?.trim() + const accountId = Env.get("CLOUDFLARE_ACCOUNT_ID") if (!accountId) return { autoload: false } - // createOpenAICompatible(). + + const apiKey = await iife(async () => { + const envToken = Env.get("CLOUDFLARE_API_KEY") ?? Env.get("CLOUDFLARE_API_TOKEN") + if (envToken) return envToken + const auth = await Auth.get(input.id) + if (auth?.type === "api") return auth.key + return undefined + }) return { - autoload: true, + autoload: !!apiKey, options: { + apiKey, baseURL: `https://api.cloudflare.com/client/v4/accounts/${accountId}/ai/v1`, - // apiKey - ...(key ? { apiKey: key } : {}), - headers: {}, }, async getModel(sdk: any, modelID: string) { return sdk.languageModel(modelID) diff --git a/packages/opencode/src/util/proxied.ts b/packages/opencode/src/util/proxied.ts new file mode 100644 index 000000000000..440a9cccedb6 --- /dev/null +++ b/packages/opencode/src/util/proxied.ts @@ -0,0 +1,3 @@ +export function proxied() { + return !!(process.env.HTTP_PROXY || process.env.HTTPS_PROXY || process.env.http_proxy || process.env.https_proxy) +} From b75b608985e42533c0e22b5c593f9640c2e651ea Mon Sep 17 00:00:00 2001 From: Aiden Cline Date: Wed, 4 Feb 2026 11:26:08 -0600 Subject: [PATCH 3/4] tweak --- packages/opencode/src/provider/provider.ts | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/packages/opencode/src/provider/provider.ts b/packages/opencode/src/provider/provider.ts index 4b8277b0307f..614d4ec14439 100644 --- a/packages/opencode/src/provider/provider.ts +++ b/packages/opencode/src/provider/provider.ts @@ -462,7 +462,7 @@ export namespace Provider { if (!accountId) return { autoload: false } const apiKey = await iife(async () => { - const envToken = Env.get("CLOUDFLARE_API_KEY") ?? Env.get("CLOUDFLARE_API_TOKEN") + const envToken = Env.get("CLOUDFLARE_API_KEY") if (envToken) return envToken const auth = await Auth.get(input.id) if (auth?.type === "api") return auth.key @@ -733,21 +733,6 @@ export namespace Provider { })), } } - if (database["cloudflare-workers-ai"]) { - const cfworkersai = database["cloudflare-workers-ai"] - database["cloudflare-workers-ai"] = { - ...cfworkersai, - models: mapValues(cfworkersai.models, (model) => { - return { - ...model, - api: { - ...model.api, - npm: "@ai-sdk/openai-compatible", - }, - } - }), - } - } function mergeProvider(providerID: string, provider: Partial) { const existing = providers[providerID] From 86495adaa309c8516b72898a5e78c965798739b6 Mon Sep 17 00:00:00 2001 From: Aiden Cline Date: Wed, 4 Feb 2026 12:03:25 -0600 Subject: [PATCH 4/4] revert unrelated changes --- packages/opencode/src/bun/index.ts | 10 ++++++++-- packages/opencode/src/config/config.ts | 25 ++++--------------------- packages/opencode/src/util/proxied.ts | 3 --- 3 files changed, 12 insertions(+), 26 deletions(-) delete mode 100644 packages/opencode/src/util/proxied.ts diff --git a/packages/opencode/src/bun/index.ts b/packages/opencode/src/bun/index.ts index bdb7cff78e25..19edb6eec4b0 100644 --- a/packages/opencode/src/bun/index.ts +++ b/packages/opencode/src/bun/index.ts @@ -7,7 +7,6 @@ import { NamedError } from "@opencode-ai/util/error" import { readableStreamToText } from "bun" import { Lock } from "../util/lock" import { PackageRegistry } from "./registry" -import { proxied } from "@/util/proxied" export namespace BunProc { const log = Log.create({ service: "bun" }) @@ -87,13 +86,20 @@ export namespace BunProc { log.info("Cached version is outdated, proceeding with install", { pkg, cachedVersion }) } + const proxied = !!( + process.env.HTTP_PROXY || + process.env.HTTPS_PROXY || + process.env.http_proxy || + process.env.https_proxy + ) + // Build command arguments const args = [ "add", "--force", "--exact", // TODO: get rid of this case (see: https://github.com/oven-sh/bun/issues/19936) - ...(proxied() ? ["--no-cache"] : []), + ...(proxied ? ["--no-cache"] : []), "--cwd", Global.Path.cache, pkg + "@" + version, diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts index 5fde2aed87d1..91816a00fcc3 100644 --- a/packages/opencode/src/config/config.ts +++ b/packages/opencode/src/config/config.ts @@ -29,7 +29,6 @@ import { Bus } from "@/bus" import { GlobalBus } from "@/bus/global" import { Event } from "../server/event" import { PackageRegistry } from "@/bun/registry" -import { proxied } from "@/util/proxied" export namespace Config { const log = Log.create({ service: "config" }) @@ -248,29 +247,13 @@ export namespace Config { const hasGitIgnore = await Bun.file(gitignore).exists() if (!hasGitIgnore) await Bun.write(gitignore, ["node_modules", "package.json", "bun.lock", ".gitignore"].join("\n")) - await BunProc.run( - [ - "add", - `@opencode-ai/plugin@${targetVersion}`, - "--exact", - // TODO: get rid of this case (see: https://github.com/oven-sh/bun/issues/19936) - ...(proxied() ? ["--no-cache"] : []), - ], - { - cwd: dir, - }, - ).catch(() => {}) + await BunProc.run(["add", `@opencode-ai/plugin@${targetVersion}`, "--exact"], { + cwd: dir, + }).catch(() => {}) // Install any additional dependencies defined in the package.json // This allows local plugins and custom tools to use external packages - await BunProc.run( - [ - "install", - // TODO: get rid of this case (see: https://github.com/oven-sh/bun/issues/19936) - ...(proxied() ? ["--no-cache"] : []), - ], - { cwd: dir }, - ).catch(() => {}) + await BunProc.run(["install"], { cwd: dir }).catch(() => {}) } async function needsInstall(dir: string) { diff --git a/packages/opencode/src/util/proxied.ts b/packages/opencode/src/util/proxied.ts deleted file mode 100644 index 440a9cccedb6..000000000000 --- a/packages/opencode/src/util/proxied.ts +++ /dev/null @@ -1,3 +0,0 @@ -export function proxied() { - return !!(process.env.HTTP_PROXY || process.env.HTTPS_PROXY || process.env.http_proxy || process.env.https_proxy) -}