summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAiden Cline <[email protected]>2026-01-26 13:17:59 -0500
committerAiden Cline <[email protected]>2026-01-26 13:18:08 -0500
commitac53a372b0b97fca93f887036f5957eddb88b606 (patch)
treefd7c23b3013848a79bf6bbb515caae8adc26fa0f
parent7795cae0b55c09544dcdcf3051cefa2d473efe86 (diff)
downloadopencode-ac53a372b0b97fca93f887036f5957eddb88b606.tar.gz
opencode-ac53a372b0b97fca93f887036f5957eddb88b606.zip
feat: use anthropic compat messages api for anthropic models through copilot
-rw-r--r--packages/opencode/src/plugin/copilot.ts22
-rw-r--r--packages/opencode/src/provider/provider.ts9
-rw-r--r--packages/opencode/src/session/llm.ts22
3 files changed, 35 insertions, 18 deletions
diff --git a/packages/opencode/src/plugin/copilot.ts b/packages/opencode/src/plugin/copilot.ts
index 369acf800..659090dd3 100644
--- a/packages/opencode/src/plugin/copilot.ts
+++ b/packages/opencode/src/plugin/copilot.ts
@@ -26,6 +26,9 @@ export async function CopilotAuthPlugin(input: PluginInput): Promise<Hooks> {
const info = await getAuth()
if (!info || info.type !== "oauth") return {}
+ const enterpriseUrl = info.enterpriseUrl
+ const baseURL = enterpriseUrl ? `https://copilot-api.${normalizeDomain(enterpriseUrl)}` : undefined
+
if (provider && provider.models) {
for (const model of Object.values(provider.models)) {
model.cost = {
@@ -36,16 +39,23 @@ export async function CopilotAuthPlugin(input: PluginInput): Promise<Hooks> {
write: 0,
},
}
+
+ // TODO: move some of this hacky-ness to models.dev presets once we have better grasp of things here...
+ const base = baseURL ?? model.api.url
+ const claude = model.id.includes("claude")
+ const url = iife(() => {
+ if (!claude) return base
+ if (base.endsWith("/v1")) return base
+ if (base.endsWith("/")) return `${base}v1`
+ return `${base}/v1`
+ })
+
+ model.api.url = url
+ model.api.npm = claude ? "@ai-sdk/anthropic" : "@ai-sdk/github-copilot"
}
}
- const enterpriseUrl = info.enterpriseUrl
- const baseURL = enterpriseUrl
- ? `https://copilot-api.${normalizeDomain(enterpriseUrl)}`
- : "https://api.githubcopilot.com"
-
return {
- baseURL,
apiKey: "",
async fetch(request: RequestInfo | URL, init?: RequestInit) {
const info = await getAuth()
diff --git a/packages/opencode/src/provider/provider.ts b/packages/opencode/src/provider/provider.ts
index f898d3be4..ee7ee75c9 100644
--- a/packages/opencode/src/provider/provider.ts
+++ b/packages/opencode/src/provider/provider.ts
@@ -132,6 +132,7 @@ export namespace Provider {
return {
autoload: false,
async getModel(sdk: any, modelID: string, _options?: Record<string, any>) {
+ if (sdk.responses === undefined && sdk.chat === undefined) return sdk.languageModel(modelID)
return shouldUseCopilotResponsesApi(modelID) ? sdk.responses(modelID) : sdk.chat(modelID)
},
options: {},
@@ -141,6 +142,7 @@ export namespace Provider {
return {
autoload: false,
async getModel(sdk: any, modelID: string, _options?: Record<string, any>) {
+ if (sdk.responses === undefined && sdk.chat === undefined) return sdk.languageModel(modelID)
return shouldUseCopilotResponsesApi(modelID) ? sdk.responses(modelID) : sdk.chat(modelID)
},
options: {},
@@ -601,10 +603,7 @@ export namespace Provider {
api: {
id: model.id,
url: provider.api!,
- npm: iife(() => {
- if (provider.id.startsWith("github-copilot")) return "@ai-sdk/github-copilot"
- return model.provider?.npm ?? provider.npm ?? "@ai-sdk/openai-compatible"
- }),
+ npm: model.provider?.npm ?? provider.npm ?? "@ai-sdk/openai-compatible",
},
status: model.status ?? "active",
headers: model.headers ?? {},
@@ -924,6 +923,8 @@ export namespace Provider {
)
delete provider.models[modelID]
+ model.variants = mapValues(ProviderTransform.variants(model), (v) => v)
+
// Filter out disabled variants from config
const configVariants = configProvider?.models?.[modelID]?.variants
if (configVariants && model.variants) {
diff --git a/packages/opencode/src/session/llm.ts b/packages/opencode/src/session/llm.ts
index 1e409b03f..d65130803 100644
--- a/packages/opencode/src/session/llm.ts
+++ b/packages/opencode/src/session/llm.ts
@@ -150,14 +150,20 @@ export namespace LLM {
},
)
- const maxOutputTokens = isCodex
- ? undefined
- : ProviderTransform.maxOutputTokens(
- input.model.api.npm,
- params.options,
- input.model.limit.output,
- OUTPUT_TOKEN_MAX,
- )
+ const maxOutputTokens = isCodex ? undefined : undefined
+ log.info("max_output_tokens", {
+ tokens: ProviderTransform.maxOutputTokens(
+ input.model.api.npm,
+ params.options,
+ input.model.limit.output,
+ OUTPUT_TOKEN_MAX,
+ ),
+ modelOptions: params.options,
+ outputLimit: input.model.limit.output,
+ })
+ // tokens = 32000
+ // outputLimit = 64000
+ // modelOptions={"reasoningEffort":"minimal"}
const tools = await resolveTools(input)