@openclaw/amazon-bedrock-provider 2026.10.5-beta.3 → 2026.10.10-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/api.js CHANGED
@@ -1,2 +1 @@
1
- import { discoverBedrockModels, resolveImplicitBedrockProvider } from "./discovery.js";
2
- export { discoverBedrockModels, resolveImplicitBedrockProvider };
1
+ export { discoverBedrockModels, resolveImplicitBedrockProvider } from "./discovery.js";
@@ -1,31 +1,29 @@
1
1
  import { resolveClaudeModelIdentity } from "openclaw/plugin-sdk/provider-model-shared";
2
2
  //#region extensions/amazon-bedrock/bedrock-options.ts
3
+ /** Nova requires explicit opt-in; other models retain the existing env/default policy. */
4
+ function resolveBedrockCacheRetention(policy, cacheRetention) {
5
+ if (cacheRetention) return cacheRetention;
6
+ if (policy === "nova") return "none";
7
+ if (typeof process !== "undefined" && process.env.OPENCLAW_CACHE_RETENTION === "long") return "long";
8
+ return "short";
9
+ }
3
10
  function resolveBedrockPromptCachePolicy(model) {
4
11
  const modelId = model.id.trim().toLowerCase().replace(/^arn:aws(?:-cn|-us-gov)?:bedrock:[^:]+:[^:]*:(?:foundation-model|inference-profile)\//, "").replace(/^(?:us|eu|apac|jp|global)\./, "");
5
12
  if (/^amazon\.nova-(?:micro|lite|pro|premier|2-lite)-v1:0$/.test(modelId)) return "nova";
6
- if (supportsBedrockClaudePromptCaching(model.id, model.name) || supportsBedrockClaudePromptCaching(resolveClaudeModelIdentity(model), model.name)) return "claude";
13
+ return resolveBedrockClaudeCachePolicy(resolveClaudeModelIdentity(model), model.name);
7
14
  }
8
- function resolveBedrockCachePoint(model, retention) {
9
- const policy = resolveBedrockPromptCachePolicy(model);
15
+ function resolveBedrockCachePoint(policy, retention) {
10
16
  if (!policy || retention === "none") return;
11
17
  return {
12
18
  type: "default",
13
19
  ...policy === "claude" && retention === "long" ? { ttl: "1h" } : {}
14
20
  };
15
21
  }
16
- function getModelMatchCandidates(modelId, modelName) {
17
- return (modelName ? [modelId, modelName] : [modelId]).flatMap((value) => {
18
- const lower = value.toLowerCase();
19
- return [lower, lower.replace(/[\s_.:]+/g, "-")];
20
- });
21
- }
22
- function supportsBedrockClaudePromptCaching(modelId, modelName) {
23
- const candidates = getModelMatchCandidates(modelId, modelName);
24
- if (!candidates.some((s) => s.includes("claude"))) {
25
- if (typeof process !== "undefined" && process.env.AWS_BEDROCK_FORCE_CACHE === "1") return true;
26
- return false;
27
- }
28
- return candidates.some((candidate) => candidate.includes("-4-") || /claude-(?:fable-5|mythos-5|opus-5|sonnet-5|3-7-sonnet|3-5-haiku)/.test(candidate));
22
+ function resolveBedrockClaudeCachePolicy(modelId, modelName) {
23
+ const candidates = [modelId, modelName].map((id) => resolveClaudeModelIdentity({ id }));
24
+ if (!candidates.some((s) => s.includes("claude"))) return typeof process !== "undefined" && process.env.AWS_BEDROCK_FORCE_CACHE === "1" ? "claude-short" : void 0;
25
+ if (candidates.some((candidate) => /^claude-(?:haiku-(?:4-5|5-5)|sonnet-(?:4-[56]|5(?:-5)?)|opus-(?:4-[5-8]|5(?:-5)?)|(?:fable|mythos)-5(?:-1)?)(?:$|-v\d|-\d{8}(?:-|$))/.test(candidate))) return "claude";
26
+ return candidates.some((candidate) => candidate.includes("-4-") || /^claude-(?:fable-5|mythos-5|opus-5|sonnet-5|haiku-5|3-7-sonnet|3-5-haiku)/.test(candidate)) ? "claude-short" : void 0;
29
27
  }
30
28
  //#endregion
31
- export { resolveBedrockCachePoint, resolveBedrockPromptCachePolicy, supportsBedrockClaudePromptCaching };
29
+ export { resolveBedrockCachePoint, resolveBedrockCacheRetention, resolveBedrockPromptCachePolicy };
@@ -1,2 +1 @@
1
- import { t as migrateAmazonBedrockLegacyConfig } from "./.setup/config-compat-HlsW2HRS.mjs";
2
- export { migrateAmazonBedrockLegacyConfig };
1
+ export { t as migrateAmazonBedrockLegacyConfig } from "./.setup/config-compat-HlsW2HRS.mjs";
@@ -1,5 +1,4 @@
1
1
  import { DEFAULT_BEDROCK_EMBEDDING_MODEL, createBedrockEmbeddingProvider, hasAwsCredentials } from "./embedding-provider.js";
2
- import { isMissingEmbeddingApiKeyError } from "openclaw/plugin-sdk/embedding-provider-adapter";
3
2
  //#region extensions/amazon-bedrock/memory-embedding-adapter.ts
4
3
  const bedrockMemoryEmbeddingProviderAdapter = {
5
4
  id: "bedrock",
@@ -7,8 +6,6 @@ const bedrockMemoryEmbeddingProviderAdapter = {
7
6
  transport: "remote",
8
7
  authProviderId: "amazon-bedrock",
9
8
  autoSelectPriority: 60,
10
- allowExplicitWhenConfiguredAuto: true,
11
- shouldContinueAutoSelection: isMissingEmbeddingApiKeyError,
12
9
  create: async (options) => {
13
10
  if (!await hasAwsCredentials()) throw new Error("No API key found for provider \"bedrock\". AWS credentials are not available. Set AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY, AWS_PROFILE, or AWS_BEARER_TOKEN_BEDROCK, configure an EC2/ECS/EKS role, or set memory.search.provider to another provider.");
14
11
  const { provider, client } = await createBedrockEmbeddingProvider({
@@ -1,4 +1,4 @@
1
- import { resolveBedrockPromptCachePolicy, supportsBedrockClaudePromptCaching } from "./bedrock-options.js";
1
+ import { resolveBedrockCachePoint, resolveBedrockPromptCachePolicy } from "./bedrock-options.js";
2
2
  import { loadBedrockControlPlaneSdk, runBedrockControlPlaneRequest } from "./control-plane.js";
3
3
  import { bedrockMemoryEmbeddingProviderAdapter } from "./memory-embedding-adapter.js";
4
4
  import { isLatestAdaptiveBedrockModelRef, isOpus47OrNewerBedrockModelRef, resolveBedrockClaudeThinkingProfile, resolveBedrockNativeThinkingLevelMap, supportsBedrockNativeMaxEffort } from "./thinking-policy.js";
@@ -106,14 +106,14 @@ async function resolveAppProfileTraits(modelId, fallbackRegion, signal) {
106
106
  const controlPlaneClient = sdk.createClient(region);
107
107
  client = controlPlaneClient;
108
108
  const command = sdk.createGetInferenceProfileCommand({ inferenceProfileIdentifier: modelId });
109
- const models = (await runBedrockControlPlaneRequest({
109
+ const modelArns = ((await runBedrockControlPlaneRequest({
110
110
  operation: "Bedrock GetInferenceProfile",
111
111
  signal,
112
112
  send: (options) => controlPlaneClient.send(command, options)
113
- })).models ?? [];
114
- const modelArns = models.map((model) => model.modelArn ?? "");
113
+ })).models ?? []).map((model) => model.modelArn ?? "");
114
+ const cachePolicies = modelArns.map((id) => resolveBedrockPromptCachePolicy({ id }));
115
115
  const traits = {
116
- cacheEligible: models.length > 0 && modelArns.every((modelArn) => supportsBedrockClaudePromptCaching(modelArn)),
116
+ cachePolicy: cachePolicies.length > 0 && cachePolicies.every((policy) => policy === "claude" || policy === "claude-short") ? cachePolicies.includes("claude-short") ? "claude-short" : "claude" : void 0,
117
117
  omitTemperature: modelArns.some(isOpus47OrNewerBedrockModelRef)
118
118
  };
119
119
  appProfileTraitsCache.set(modelId, traits);
@@ -121,7 +121,7 @@ async function resolveAppProfileTraits(modelId, fallbackRegion, signal) {
121
121
  } catch {
122
122
  signal?.throwIfAborted();
123
123
  return {
124
- cacheEligible: isAnthropicBedrockModel(modelId),
124
+ cachePolicy: isAnthropicBedrockModel(modelId) ? "claude-short" : void 0,
125
125
  omitTemperature: isOpus47OrNewerBedrockModelRef(modelId)
126
126
  };
127
127
  } finally {
@@ -135,12 +135,9 @@ function hasCachePoint(blocks) {
135
135
  * Inject Bedrock Converse cache points into the payload when the shared runtime skipped them
136
136
  * because it didn't recognize the model ID (application inference profiles).
137
137
  */
138
- function injectBedrockCachePoints(payload, cacheRetention, context, model) {
139
- if (!cacheRetention || cacheRetention === "none" || resolveBedrockPromptCachePolicy(model)) return;
140
- const point = { cachePoint: {
141
- type: "default",
142
- ...cacheRetention === "long" ? { ttl: "1h" } : {}
143
- } };
138
+ function injectBedrockCachePoints(payload, cachePoint, context) {
139
+ if (!cachePoint) return;
140
+ const point = { cachePoint };
144
141
  const system = payload.system;
145
142
  if (Array.isArray(system) && system.length > 0 && !hasCachePoint(system)) {
146
143
  const split = context.systemPrompt && splitSystemPromptCacheBoundary(context.systemPrompt);
@@ -149,8 +146,14 @@ function injectBedrockCachePoints(payload, cacheRetention, context, model) {
149
146
  if (context.messages.some(hasRuntimeContextMarker)) return;
150
147
  const messages = payload.messages;
151
148
  if (Array.isArray(messages)) {
152
- const userContent = messages.toReversed().find((msg) => msg.role === "user" && Array.isArray(msg.content))?.content;
153
- if (userContent && !hasCachePoint(userContent)) userContent.push(point);
149
+ let remaining = 2;
150
+ for (let index = messages.length - 1; index >= 0; index--) {
151
+ const message = messages[index];
152
+ if (message?.role === "user" && Array.isArray(message.content)) {
153
+ if (!hasCachePoint(message.content)) message.content.push(point);
154
+ if (--remaining === 0) break;
155
+ }
156
+ }
154
157
  }
155
158
  }
156
159
  function patchMaxThinkingEffort(payload) {
@@ -252,7 +255,7 @@ function registerAmazonBedrockPlugin(api) {
252
255
  } else wrapped = createBedrockServiceTierWrapper(wrapped, serviceTier);
253
256
  }
254
257
  const region = resolveBedrockRegion(config, provider) ?? extractRegionFromBaseUrl(model?.baseUrl) ?? currentPluginConfig?.discovery?.region;
255
- const mayNeedCacheInjection = isBedrockAppInferenceProfile(modelId) && !supportsBedrockClaudePromptCaching(modelId);
258
+ const mayNeedCacheInjection = isBedrockAppInferenceProfile(modelId) && !resolveBedrockPromptCachePolicy(modelRef);
256
259
  const shouldOmitTemperature = opus47OrNewer || fable5 || isLatestAdaptiveBedrockModelRef(modelId, model?.params);
257
260
  const shouldPatchMaxThinking = supportsNativeMax && thinkingLevel === "max";
258
261
  const shouldPatchPayload = shouldOmitTemperature || shouldPatchMaxThinking;
@@ -273,16 +276,16 @@ function registerAmazonBedrockPlugin(api) {
273
276
  return originalOnPayload?.(payload, payloadModel);
274
277
  } } : {}
275
278
  });
276
- const cacheRetention = typeof merged.cacheRetention === "string" ? merged.cacheRetention : "short";
279
+ const cacheRetention = merged.cacheRetention ?? "short";
277
280
  return underlying(streamModel, context, {
278
281
  ...merged,
279
282
  onPayload: async (payload, payloadModel) => {
280
- const traits = heuristicMatch ? void 0 : await resolveAppProfileTraits(modelId, region, merged.signal);
283
+ const traits = await resolveAppProfileTraits(modelId, region, merged.signal);
281
284
  if (payload && typeof payload === "object") {
282
285
  const payloadRecord = payload;
283
- if (heuristicMatch || traits?.cacheEligible) injectBedrockCachePoints(payloadRecord, cacheRetention, context, streamModel);
286
+ injectBedrockCachePoints(payloadRecord, resolveBedrockCachePoint(traits.cachePolicy, cacheRetention), context);
284
287
  if (shouldPatchMaxThinking) patchMaxThinkingEffort(payloadRecord);
285
- if (heuristicMatch ? shouldOmitTemperature || "temperature" in merged && (await resolveAppProfileTraits(modelId, region, merged.signal)).omitTemperature : traits?.omitTemperature) omitUnsupportedClaudePayloadTemperature(payloadRecord);
288
+ if (shouldOmitTemperature || traits.omitTemperature) omitUnsupportedClaudePayloadTemperature(payloadRecord);
286
289
  }
287
290
  return originalOnPayload?.(payload, payloadModel);
288
291
  }
@@ -1,4 +1,4 @@
1
- import { resolveBedrockCachePoint, resolveBedrockPromptCachePolicy } from "./bedrock-options.js";
1
+ import { resolveBedrockCachePoint, resolveBedrockCacheRetention, resolveBedrockPromptCachePolicy } from "./bedrock-options.js";
2
2
  import { resolveBedrockRuntimeAuth } from "./aws-credential-refresh.js";
3
3
  import { isClaude5BedrockModel, resolveBedrockClaudeThinkingProfile, supportsBedrockNativeMaxEffort } from "./thinking-policy.js";
4
4
  import { AssistantMessageEventStream, adjustMaxTokensForThinking, buildBaseOptions, calculateCost, clampReasoning, createHttpProxyAgentsForTarget, createToolArgumentPreviewSchedule, hasRuntimeContextMarker, parseStreamingJson, sanitizeSurrogates, transformMessages } from "openclaw/plugin-sdk/llm";
@@ -75,8 +75,9 @@ const streamBedrock = (model, context, options = {}) => {
75
75
  try {
76
76
  options.signal?.throwIfAborted();
77
77
  client = new BedrockRuntimeClient(config);
78
- const cacheRetention = resolveCacheRetention(model, options.cacheRetention);
79
- const cachePoint = resolveBedrockCachePoint(model, cacheRetention);
78
+ const cachePolicy = resolveBedrockPromptCachePolicy(model);
79
+ const cacheRetention = resolveBedrockCacheRetention(cachePolicy, options.cacheRetention);
80
+ const cachePoint = resolveBedrockCachePoint(cachePolicy, cacheRetention);
80
81
  const additionalModelRequestFields = buildAdditionalModelRequestFields(model, options);
81
82
  const thinking = additionalModelRequestFields?.thinking;
82
83
  const sendsAdaptiveThinking = thinking !== null && typeof thinking === "object" && thinking.type === "adaptive";
@@ -161,10 +162,7 @@ const streamBedrock = (model, context, options = {}) => {
161
162
  error,
162
163
  cleanup: () => {
163
164
  output.content = output.content.filter((block) => block.type !== "toolCall");
164
- for (const block of output.content) {
165
- delete block.index;
166
- delete block.partialJson;
167
- }
165
+ for (const block of output.content) delete block.index;
168
166
  if (refusalBuffer) {
169
167
  refusalBuffer.discard();
170
168
  output.content = [];
@@ -452,16 +450,6 @@ function mapThinkingLevelToEffort(model, level) {
452
450
  }
453
451
  }
454
452
  /**
455
- * Resolve cache retention preference.
456
- * Nova requires explicit opt-in; other models retain the existing env/default policy.
457
- */
458
- function resolveCacheRetention(model, cacheRetention) {
459
- if (cacheRetention) return cacheRetention;
460
- if (resolveBedrockPromptCachePolicy(model) === "nova") return "none";
461
- if (typeof process !== "undefined" && process.env.OPENCLAW_CACHE_RETENTION === "long") return "long";
462
- return "short";
463
- }
464
- /**
465
453
  * Check if the model is an Anthropic Claude model on Bedrock.
466
454
  * Checks both model ID and model name to support application inference profiles
467
455
  * whose ARNs don't contain the model name.
@@ -604,8 +592,14 @@ function convertMessages(context, model, cachePoint) {
604
592
  }
605
593
  }
606
594
  if (cachePoint && result.at(-1)?.role === ConversationRole.USER) {
607
- const cacheAnchor = result.findLast((message, index) => message.role === ConversationRole.USER && (firstVolatileMessageIndex === void 0 || index < firstVolatileMessageIndex));
608
- if (cacheAnchor?.content) cacheAnchor.content.push({ cachePoint });
595
+ let remaining = 2;
596
+ for (let index = (firstVolatileMessageIndex ?? result.length) - 1; index >= 0; index--) {
597
+ const message = result[index];
598
+ if (message?.role === ConversationRole.USER && message.content) {
599
+ message.content.push({ cachePoint });
600
+ if (--remaining === 0) break;
601
+ }
602
+ }
609
603
  }
610
604
  return result;
611
605
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/amazon-bedrock-provider",
3
- "version": "2026.10.5-beta.3",
3
+ "version": "2026.10.10-beta.1",
4
4
  "description": "OpenClaw Amazon Bedrock provider plugin with model discovery, embeddings, and guardrail support.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -25,10 +25,10 @@
25
25
  "minHostVersion": ">=2026.5.12-beta.1"
26
26
  },
27
27
  "compat": {
28
- "pluginApi": ">=2026.10.5-beta.3"
28
+ "pluginApi": ">=2026.10.10-beta.1"
29
29
  },
30
30
  "build": {
31
- "openclawVersion": "2026.10.5-beta.3",
31
+ "openclawVersion": "2026.10.10-beta.1",
32
32
  "bundledDist": false
33
33
  },
34
34
  "release": {
@@ -47,7 +47,7 @@
47
47
  "assets/activity.svg"
48
48
  ],
49
49
  "peerDependencies": {
50
- "openclaw": ">=2026.10.5-beta.3"
50
+ "openclaw": ">=2026.10.10-beta.1"
51
51
  },
52
52
  "peerDependenciesMeta": {
53
53
  "openclaw": {