Skip to content
This repository was archived by the owner on Feb 25, 2026. It is now read-only.
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion packages/opencode/src/provider/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ export namespace Provider {

const CUSTOM_LOADERS: Record<string, CustomLoader> = {
async anthropic() {
const longContextBeta = "context-1m-2025-08-07"
return {
autoload: false,
options: {
Expand All @@ -103,9 +104,30 @@ export namespace Provider {
// TODO: Add adaptive thinking headers when @ai-sdk/anthropic supports it:
// adaptive-thinking-2026-01-28,effort-2025-11-24,max-effort-2026-01-24
"anthropic-beta":
"claude-code-20250219,interleaved-thinking-2025-05-14,fine-grained-tool-streaming-2025-05-14,context-1m-2025-08-07",
"claude-code-20250219,interleaved-thinking-2025-05-14,fine-grained-tool-streaming-2025-05-14",
},
},
async getModel(_sdk: any, modelID: string, options?: Record<string, any>) {
const input = { ...(options ?? {}) }
const headers = { ...(input["headers"] ?? {}) }
const raw = typeof headers["anthropic-beta"] === "string" ? headers["anthropic-beta"] : ""
const parts = raw
.split(",")
.map((item) => item.trim())
.filter(Boolean)
.filter((item) => item !== longContextBeta)

if (modelID.toLowerCase().includes("1m")) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WARNING: The check modelID.toLowerCase().includes("1m") is fragile. It would match any model ID containing "1m" anywhere (e.g., a hypothetical model like claude-21march or claude-v1mini). Consider a more specific pattern like checking for -1m- or a suffix match to reduce false positives.

parts.push(longContextBeta)
}

headers["anthropic-beta"] = parts.join(",")
const sdk = createAnthropic({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CRITICAL: This creates a brand-new createAnthropic() SDK using only the raw provider.options, discarding the pre-built sdk parameter (renamed _sdk on line 110). Every other getModel implementation in this file (openai, github-copilot, azure, amazon-bedrock, etc.) uses the passed sdk parameter.

The sdk passed to getModel is built by getSDK() which enriches provider.options with apiKey, baseURL, model-specific headers, and a custom fetch wrapper (with timeout logic, OpenAI ID stripping, etc.). By creating a new SDK here, all of those are lost.

This means Anthropic 1M-context models will likely fail or behave incorrectly because the new SDK won't have the API key, base URL, or timeout handling.

Consider modifying the headers on the existing sdk or restructuring so the beta header is applied at the getSDK level based on the model ID, rather than creating a separate SDK instance.

...input,
headers,
})
return sdk.languageModel(modelID)
},
}
},
openai: async () => {
Expand Down
Loading