diff --git a/packages/opencode/src/provider/models.ts b/packages/opencode/src/provider/models.ts index 34640706..57555c54 100644 --- a/packages/opencode/src/provider/models.ts +++ b/packages/opencode/src/provider/models.ts @@ -35,7 +35,7 @@ export namespace ModelsDev { }) .optional(), experimental: z.boolean().optional(), - status: z.enum(["alpha", "beta"]).optional(), + status: z.enum(["alpha", "beta", "deprecated"]).optional(), options: z.record(z.string(), z.any()), headers: z.record(z.string(), z.string()).optional(), provider: z.object({ npm: z.string() }).optional(), diff --git a/packages/opencode/src/provider/provider.ts b/packages/opencode/src/provider/provider.ts index 9bcff4b4..730ba396 100644 --- a/packages/opencode/src/provider/provider.ts +++ b/packages/opencode/src/provider/provider.ts @@ -78,12 +78,18 @@ export namespace Provider { } }, "amazon-bedrock": async () => { - if (!process.env["AWS_PROFILE"] && !process.env["AWS_ACCESS_KEY_ID"] && !process.env["AWS_BEARER_TOKEN_BEDROCK"]) + if ( + !process.env["AWS_PROFILE"] && + !process.env["AWS_ACCESS_KEY_ID"] && + !process.env["AWS_BEARER_TOKEN_BEDROCK"] + ) return { autoload: false } const region = process.env["AWS_REGION"] ?? "us-east-1" - const { fromNodeProviderChain } = await import(await BunProc.install("@aws-sdk/credential-providers")) + const { fromNodeProviderChain } = await import( + await BunProc.install("@aws-sdk/credential-providers") + ) return { autoload: true, options: { @@ -118,9 +124,13 @@ export namespace Provider { "eu-south-1", "eu-south-2", ].some((r) => region.includes(r)) - const modelRequiresPrefix = ["claude", "nova-lite", "nova-micro", "llama3", "pixtral"].some((m) => - modelID.includes(m), - ) + const modelRequiresPrefix = [ + "claude", + "nova-lite", + "nova-micro", + "llama3", + "pixtral", + ].some((m) => modelID.includes(m)) if (regionRequiresPrefix && modelRequiresPrefix) { modelID = `${regionPrefix}.${modelID}` } @@ -130,13 +140,15 @@ export namespace Provider { const isAustraliaRegion = ["ap-southeast-2", "ap-southeast-4"].includes(region) if ( isAustraliaRegion && - ["anthropic.claude-sonnet-4-5", "anthropic.claude-haiku"].some((m) => modelID.includes(m)) + ["anthropic.claude-sonnet-4-5", "anthropic.claude-haiku"].some((m) => + modelID.includes(m), + ) ) { regionPrefix = "au" modelID = `${regionPrefix}.${modelID}` } else { - const modelRequiresPrefix = ["claude", "nova-lite", "nova-micro", "nova-pro"].some((m) => - modelID.includes(m), + const modelRequiresPrefix = ["claude", "nova-lite", "nova-micro", "nova-pro"].some( + (m) => modelID.includes(m), ) if (modelRequiresPrefix) { regionPrefix = "apac" @@ -174,8 +186,12 @@ export namespace Provider { } }, "google-vertex": async () => { - const project = process.env["GOOGLE_CLOUD_PROJECT"] ?? process.env["GCP_PROJECT"] ?? process.env["GCLOUD_PROJECT"] - const location = process.env["GOOGLE_CLOUD_LOCATION"] ?? process.env["VERTEX_LOCATION"] ?? "us-east5" + const project = + process.env["GOOGLE_CLOUD_PROJECT"] ?? + process.env["GCP_PROJECT"] ?? + process.env["GCLOUD_PROJECT"] + const location = + process.env["GOOGLE_CLOUD_LOCATION"] ?? process.env["VERTEX_LOCATION"] ?? "us-east5" const autoload = Boolean(project) if (!autoload) return { autoload: false } return { @@ -191,8 +207,12 @@ export namespace Provider { } }, "google-vertex-anthropic": async () => { - const project = process.env["GOOGLE_CLOUD_PROJECT"] ?? process.env["GCP_PROJECT"] ?? process.env["GCLOUD_PROJECT"] - const location = process.env["GOOGLE_CLOUD_LOCATION"] ?? process.env["VERTEX_LOCATION"] ?? "us-east5" + const project = + process.env["GOOGLE_CLOUD_PROJECT"] ?? + process.env["GCP_PROJECT"] ?? + process.env["GCLOUD_PROJECT"] + const location = + process.env["GOOGLE_CLOUD_LOCATION"] ?? process.env["VERTEX_LOCATION"] ?? "us-east5" const autoload = Boolean(project) if (!autoload) return { autoload: false } return { @@ -223,7 +243,13 @@ export namespace Provider { } = {} const models = new Map< string, - { providerID: string; modelID: string; info: ModelsDev.Model; language: LanguageModel; npm?: string } + { + providerID: string + modelID: string + info: ModelsDev.Model + language: LanguageModel + npm?: string + } >() const sdk = new Map() // Maps `${provider}/${key}` to the provider’s actual model ID for custom aliases. @@ -355,7 +381,10 @@ export namespace Provider { const auth = await Auth.get(providerID) if (!auth) continue if (!plugin.auth.loader) continue - const options = await plugin.auth.loader(() => Auth.get(providerID) as any, database[plugin.auth.provider]) + const options = await plugin.auth.loader( + () => Auth.get(providerID) as any, + database[plugin.auth.provider], + ) mergeProvider(plugin.auth.provider, options ?? {}, "custom") } @@ -370,12 +399,15 @@ export namespace Provider { // Filter out blacklisted models .filter( ([modelID]) => - modelID !== "gpt-5-chat-latest" && !(providerID === "openrouter" && modelID === "openai/gpt-5-chat"), + modelID !== "gpt-5-chat-latest" && + !(providerID === "openrouter" && modelID === "openai/gpt-5-chat"), ) // Filter out experimental models .filter( ([, model]) => - (!model.experimental && model.status !== "alpha") || Flag.OPENCODE_ENABLE_EXPERIMENTAL_MODELS, + ((!model.experimental && model.status !== "alpha") || + Flag.OPENCODE_ENABLE_EXPERIMENTAL_MODELS) && + model.status !== "deprecated", ), ) provider.info.models = filteredModels @@ -421,7 +453,9 @@ export namespace Provider { // In addition, Bun's dynamic import logic does not support subpath imports, // so we patch the import path to load directly from `dist`. const modPath = - provider.id === "google-vertex-anthropic" ? `${installedPath}/dist/anthropic/index.mjs` : installedPath + provider.id === "google-vertex-anthropic" + ? `${installedPath}/dist/anthropic/index.mjs` + : installedPath const mod = await import(modPath) if (options["timeout"] !== undefined && options["timeout"] !== null) { // Only override fetch if user explicitly sets timeout @@ -518,7 +552,14 @@ export namespace Provider { const provider = await state().then((state) => state.providers[providerID]) if (!provider) return - let priority = ["claude-haiku-4-5", "claude-haiku-4.5", "3-5-haiku", "3.5-haiku", "gemini-2.5-flash", "gpt-5-nano"] + let priority = [ + "claude-haiku-4-5", + "claude-haiku-4.5", + "3-5-haiku", + "3.5-haiku", + "gemini-2.5-flash", + "gpt-5-nano", + ] // claude-haiku-4.5 is considered a premium model in github copilot, we shouldn't use premium requests for title gen if (providerID === "github-copilot") { priority = priority.filter((m) => m !== "claude-haiku-4.5") diff --git a/packages/sdk/js/src/gen/types.gen.ts b/packages/sdk/js/src/gen/types.gen.ts index df110326..ae492c9a 100644 --- a/packages/sdk/js/src/gen/types.gen.ts +++ b/packages/sdk/js/src/gen/types.gen.ts @@ -426,7 +426,7 @@ export type Config = { output: Array<"text" | "audio" | "image" | "video" | "pdf"> } experimental?: boolean - status?: "alpha" | "beta" + status?: "alpha" | "beta" | "deprecated" options?: { [key: string]: unknown } @@ -990,7 +990,7 @@ export type Model = { output: Array<"text" | "audio" | "image" | "video" | "pdf"> } experimental?: boolean - status?: "alpha" | "beta" + status?: "alpha" | "beta" | "deprecated" options: { [key: string]: unknown }