mirror of
https://github.com/anomalyco/opencode.git
synced 2026-09-28 05:23:19 +08:00
fix(opencode): let config opt out of Anthropic thinking blockBinding (#46820)
Co-authored-by: Aiden Cline <aidenpcline@gmail.com>
This commit is contained in:
co-authored by
Aiden Cline
parent
ef2792511d
commit
68abdce1a0
@@ -706,17 +706,29 @@ function anthropicBindsThinking(apiId: string) {
|
||||
const ANTHROPIC_BLOCK_BINDING = { prefixMismatchBehavior: "drop_block" }
|
||||
|
||||
function anthropicBlockBinding(model: Provider.Model, options: { [x: string]: any }) {
|
||||
const sdk = sdkKey(model.api.npm)
|
||||
const key = sdk === "bedrock" ? "reasoningConfig" : sdk === "anthropic" ? "thinking" : undefined
|
||||
// Consume the OpenCode-only opt-out even on models outside the default scope.
|
||||
if (key && options[key]?.blockBinding === false) {
|
||||
const result = { ...options, [key]: { ...options[key] } }
|
||||
delete result[key].blockBinding
|
||||
if (Object.keys(result[key]).length === 0) delete result[key]
|
||||
return result
|
||||
}
|
||||
|
||||
if (!anthropicBindsThinking(model.api.id)) return options
|
||||
switch (model.api.npm) {
|
||||
case "@ai-sdk/anthropic":
|
||||
case "@ai-sdk/google-vertex/anthropic": {
|
||||
const thinking = options.thinking ?? { type: "adaptive" }
|
||||
if (thinking.type !== "adaptive" && thinking.type !== "enabled") return options
|
||||
if (thinking.blockBinding !== undefined) return options
|
||||
return { ...options, thinking: { ...thinking, blockBinding: ANTHROPIC_BLOCK_BINDING } }
|
||||
}
|
||||
case "@ai-sdk/amazon-bedrock": {
|
||||
const reasoningConfig = options.reasoningConfig ?? { type: "adaptive" }
|
||||
if (reasoningConfig.type !== "adaptive" && reasoningConfig.type !== "enabled") return options
|
||||
if (reasoningConfig.blockBinding !== undefined) return options
|
||||
return { ...options, reasoningConfig: { ...reasoningConfig, blockBinding: ANTHROPIC_BLOCK_BINDING } }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -938,6 +938,21 @@ describe("ProviderTransform.providerOptions", () => {
|
||||
).toEqual({ [sdk.key]: { [sdk.option]: { type: "enabled", budgetTokens: 4000 } } })
|
||||
})
|
||||
|
||||
test.each(["claude-fable-5-1", "claude-opus-5"])("honors explicit binding controls for %s", (id) => {
|
||||
const model = claude(sdk.npm, id)
|
||||
const options = Object.freeze({
|
||||
[sdk.option]: Object.freeze({ type: "adaptive", blockBinding: false }),
|
||||
})
|
||||
expect(ProviderTransform.providerOptions(model, options)).toEqual({
|
||||
[sdk.key]: { [sdk.option]: { type: "adaptive" } },
|
||||
})
|
||||
expect(ProviderTransform.providerOptions(model, { [sdk.option]: { blockBinding: false } })).toEqual({
|
||||
[sdk.key]: {},
|
||||
})
|
||||
const custom = { [sdk.option]: { type: "adaptive", blockBinding: { prefixMismatchBehavior: "error" } } }
|
||||
expect(ProviderTransform.providerOptions(model, custom)).toEqual({ [sdk.key]: custom })
|
||||
})
|
||||
|
||||
test.each([
|
||||
["claude-opus-5", "default"],
|
||||
["claude-opus-5", "high"],
|
||||
|
||||
Reference in New Issue
Block a user