diff --git a/packages/core/src/variant.ts b/packages/core/src/variant.ts index 4f3cb4e3cefb..1e35039cb074 100644 --- a/packages/core/src/variant.ts +++ b/packages/core/src/variant.ts @@ -409,7 +409,7 @@ const openrouter: Protocol = (model, support) => { const bedrockConverse: Protocol = (model, support) => { const id = modelID(model) - const claude = id.includes("anthropic") + const claude = id.includes("anthropic") || model.family === "claude" || model.family?.startsWith("claude-") const fields = (fields: Record): Overlay => ({ body: { additionalModelRequestFields: fields } }) switch (support.type) { case "effort": diff --git a/packages/core/test/variant.test.ts b/packages/core/test/variant.test.ts index 8f2367bc7acf..5988ef43e1b3 100644 --- a/packages/core/test/variant.test.ts +++ b/packages/core/test/variant.test.ts @@ -261,6 +261,25 @@ test("spells Chat Completions variants for direct providers", () => { ]) }) +test("recognizes Claude family metadata for Bedrock inference profile ARNs", () => { + for (const family of ["claude-sonnet", "claude"]) { + const input = model("@opencode/ai/providers/amazon-bedrock", "arn:aws:bedrock:us-east-1:123456789012:application-inference-profile/opaque") as Model.MutableInfo + input.family = Model.Family.make(family) + + expect(resolve(Model.Info.make(input), [{ type: "effort", values: ["high"] }])).toEqual([ + { + id: "high", + body: { + additionalModelRequestFields: { + thinking: { type: "adaptive", display: "summarized" }, + output_config: { effort: "high" }, + }, + }, + }, + ]) + } +}) + test("spells Bedrock Converse Claude budgets as a thinking setting", () => { expect( resolve(model("@opencode/ai/providers/amazon-bedrock", "us.anthropic.claude-haiku-4-5-20251001-v1:0", 64_000), [ @@ -288,6 +307,22 @@ test("spells Bedrock Converse effort for Grok and Nova", () => { body: { additionalModelRequestFields: { reasoningConfig: { type: "enabled", maxReasoningEffort: "xhigh" } } }, }, ]) + + const inferenceProfile = model( + "@opencode/ai/providers/amazon-bedrock", + "arn:aws:bedrock:us-east-1:123456789012:application-inference-profile/opaque", + ) as Model.MutableInfo + inferenceProfile.family = Model.Family.make("nova") + expect(resolve(Model.Info.make(inferenceProfile), supports)).toEqual([ + { + id: "low", + body: { additionalModelRequestFields: { reasoningConfig: { type: "enabled", maxReasoningEffort: "low" } } }, + }, + { + id: "xhigh", + body: { additionalModelRequestFields: { reasoningConfig: { type: "enabled", maxReasoningEffort: "xhigh" } } }, + }, + ]) }) test("caps Alibaba thinking budget variants at 64k", () => {