From b07c7f6ab3e0b09e09f1152ba7ece715c094da8c Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Thu, 30 Apr 2026 03:36:38 +0100 Subject: [PATCH] fix(amazon-bedrock): expose Opus 4.7 thinking profile --- CHANGELOG.md | 1 + extensions/amazon-bedrock/index.test.ts | 30 +++++++++++++++ .../amazon-bedrock/register.sync.runtime.ts | 38 +++++++++++++------ 3 files changed, 57 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 576c3ad93e6..84c71cfa32b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ Docs: https://docs.openclaw.ai ### Fixes - Channels/Feishu: retry file-typed iOS video resource downloads as `media` after a Feishu/Lark HTTP 502 and preserve the original 502 when the fallback also fails. Fixes #49855; carries forward #50164 and #73986. Thanks @alex-xuweilong. +- Providers/Amazon Bedrock: expose the full Claude Opus 4.7 thinking profile (`xhigh`, `adaptive`, and `max`) for Bedrock model refs, while keeping Opus/Sonnet 4.6 on adaptive-by-default, so `/think` menus and validation match the Anthropic transport behavior. Fixes #74701. Thanks @prasad-yashdeep, @sparkleHazard, @Sanjays2402, and @hclsys. - Plugins/tokenjuice: compile the bundled plugin against tokenjuice 0.7.0's published OpenClaw host types instead of a local compatibility shim, so package contract drift fails in OpenClaw validation before release. Thanks @vincentkoc. - OAuth/secrets: ignore root-level Google OAuth `client_secret_*.json` downloads so local client-secret files do not appear as commit candidates. (#74689) Thanks @jeongdulee. - Memory: mirror `sqlite-vec` into packaged bundled-plugin runtime deps for the default memory plugin, so builtin vector search does not lose its SQLite extension after upgrading to 2026.4.27. Fixes #74692. Thanks @mozi1924. diff --git a/extensions/amazon-bedrock/index.test.ts b/extensions/amazon-bedrock/index.test.ts index 491d0476671..4d021e771ab 100644 --- a/extensions/amazon-bedrock/index.test.ts +++ b/extensions/amazon-bedrock/index.test.ts @@ -253,6 +253,36 @@ describe("amazon-bedrock provider plugin", () => { }); }); + it("mirrors Claude Opus 4.7 thinking levels for Bedrock model refs", async () => { + const provider = await registerSingleProviderPlugin(amazonBedrockPlugin); + + for (const modelId of [ + "us.anthropic.claude-opus-4-7", + "us.anthropic.claude-opus-4.7-v1:0", + "eu.anthropic.claude-opus-4-7", + "arn:aws:bedrock:us-west-2:123456789012:inference-profile/us.anthropic.claude-opus-4-7", + ]) { + expect( + provider.resolveThinkingProfile?.({ + provider: "amazon-bedrock", + modelId, + } as never), + ).toMatchObject({ + levels: [ + { id: "off" }, + { id: "minimal" }, + { id: "low" }, + { id: "medium" }, + { id: "high" }, + { id: "xhigh" }, + { id: "adaptive" }, + { id: "max" }, + ], + defaultLevel: "off", + }); + } + }); + it("owns Anthropic-style replay policy for Claude Bedrock models", async () => { const provider = await registerSingleProviderPlugin(amazonBedrockPlugin); diff --git a/extensions/amazon-bedrock/register.sync.runtime.ts b/extensions/amazon-bedrock/register.sync.runtime.ts index 8fc6dc9885a..d213eb848f2 100644 --- a/extensions/amazon-bedrock/register.sync.runtime.ts +++ b/extensions/amazon-bedrock/register.sync.runtime.ts @@ -1,7 +1,7 @@ import type { StreamFn } from "@mariozechner/pi-agent-core"; import type { OpenClawConfig } from "openclaw/plugin-sdk/config-types"; import { resolvePluginConfigObject } from "openclaw/plugin-sdk/plugin-config-runtime"; -import type { OpenClawPluginApi } from "openclaw/plugin-sdk/plugin-entry"; +import type { OpenClawPluginApi, ProviderThinkingProfile } from "openclaw/plugin-sdk/plugin-entry"; import { ANTHROPIC_BY_MODEL_REPLAY_HOOKS, normalizeProviderId, @@ -290,6 +290,13 @@ export function registerAmazonBedrockPlugin(api: OpenClawPluginApi): void { // initialization during test bootstrap cannot trip TDZ reads. const providerId = "amazon-bedrock"; const claude46ModelRe = /claude-(?:opus|sonnet)-4(?:\.|-)6(?:$|[-.])/i; + const baseClaudeThinkingLevels = [ + { id: "off" }, + { id: "minimal" }, + { id: "low" }, + { id: "medium" }, + { id: "high" }, + ] as const satisfies ProviderThinkingProfile["levels"]; // Match region from bedrock-runtime (Converse API) URLs. // e.g. https://bedrock-runtime.us-east-1.amazonaws.com const bedrockRegionRe = /bedrock-runtime\.([a-z0-9-]+)\.amazonaws\./; @@ -303,6 +310,23 @@ export function registerAmazonBedrockPlugin(api: OpenClawPluginApi): void { const anthropicByModelReplayHooks = ANTHROPIC_BY_MODEL_REPLAY_HOOKS; const startupPluginConfig = (api.pluginConfig ?? {}) as AmazonBedrockPluginConfig; + function resolveBedrockClaudeThinkingProfile(modelId: string): ProviderThinkingProfile { + const trimmed = modelId.trim(); + if (isOpus47BedrockModelRef(trimmed)) { + return { + levels: [...baseClaudeThinkingLevels, { id: "xhigh" }, { id: "adaptive" }, { id: "max" }], + defaultLevel: "off", + }; + } + if (claude46ModelRe.test(trimmed)) { + return { + levels: [...baseClaudeThinkingLevels, { id: "adaptive" }], + defaultLevel: "adaptive", + }; + } + return { levels: baseClaudeThinkingLevels }; + } + function resolveCurrentPluginConfig( config: OpenClawConfig | undefined, ): AmazonBedrockPluginConfig | undefined { @@ -521,16 +545,6 @@ export function registerAmazonBedrockPlugin(api: OpenClawPluginApi): void { } return undefined; }, - resolveThinkingProfile: ({ modelId }) => ({ - levels: [ - { id: "off" }, - { id: "minimal" }, - { id: "low" }, - { id: "medium" }, - { id: "high" }, - ...(claude46ModelRe.test(modelId.trim()) ? [{ id: "adaptive" as const }] : []), - ], - defaultLevel: claude46ModelRe.test(modelId.trim()) ? "adaptive" : undefined, - }), + resolveThinkingProfile: ({ modelId }) => resolveBedrockClaudeThinkingProfile(modelId), }); }