fix(amazon-bedrock): expose Opus 4.7 thinking profile

This commit is contained in:
Peter Steinberger
2026-04-30 03:36:38 +01:00
parent b7dd912541
commit b07c7f6ab3
3 changed files with 57 additions and 12 deletions

View File

@@ -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.

View File

@@ -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);

View File

@@ -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),
});
}