@openclaw/amazon-bedrock-provider 2026.7.1 → 2026.7.2-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.
@@ -1,4 +1,8 @@
1
1
  //#region extensions/amazon-bedrock/aws-credential-refresh.ts
2
+ /**
3
+ * AWS shared config cache refresh helpers for Bedrock. They nudge the AWS SDK
4
+ * to re-read profile/SSO config when no static credentials are present.
5
+ */
2
6
  function hasStaticAwsCredentialEnv(env) {
3
7
  return Boolean(env.AWS_ACCESS_KEY_ID && env.AWS_SECRET_ACCESS_KEY);
4
8
  }
@@ -7,13 +11,11 @@ function shouldRefreshAwsSharedConfigCacheForBedrock(env) {
7
11
  if (env.AWS_BEDROCK_SKIP_AUTH === "1" || env.AWS_BEARER_TOKEN_BEDROCK) return false;
8
12
  return !hasStaticAwsCredentialEnv(env);
9
13
  }
10
- async function loadSharedIniFileLoader() {
11
- return await import("@smithy/shared-ini-file-loader");
12
- }
13
14
  /** Refresh Smithy shared config files when Bedrock needs default-chain credentials. */
14
15
  async function refreshAwsSharedConfigCacheForBedrock(env = process.env) {
15
16
  if (!shouldRefreshAwsSharedConfigCacheForBedrock(env)) return;
16
- await (await loadSharedIniFileLoader()).loadSharedConfigFiles({ ignoreCache: true });
17
+ const { loadSharedConfigFiles } = await import("@smithy/shared-ini-file-loader");
18
+ await loadSharedConfigFiles({ ignoreCache: true });
17
19
  }
18
20
  //#endregion
19
21
  export { refreshAwsSharedConfigCacheForBedrock };
@@ -104,25 +104,18 @@ function inferFamily(modelId) {
104
104
  if (id.startsWith("twelvelabs.")) return "twelvelabs";
105
105
  return "titan-v1";
106
106
  }
107
- let sdkCache = null;
108
- let credentialProviderSdkCache;
107
+ let sdkPromise = null;
108
+ let credentialProviderPromise = null;
109
109
  async function loadSdk() {
110
- if (sdkCache) return sdkCache;
111
110
  try {
112
- sdkCache = await import("@aws-sdk/client-bedrock-runtime");
113
- return sdkCache;
111
+ return await (sdkPromise ??= import("@aws-sdk/client-bedrock-runtime"));
114
112
  } catch {
113
+ sdkPromise = null;
115
114
  throw new Error("No API key found for provider bedrock: @aws-sdk/client-bedrock-runtime is not installed. Install it with: npm install @aws-sdk/client-bedrock-runtime");
116
115
  }
117
116
  }
118
- async function loadCredentialProviderSdk() {
119
- if (credentialProviderSdkCache !== void 0) return credentialProviderSdkCache;
120
- try {
121
- credentialProviderSdkCache = await import("@aws-sdk/credential-provider-node");
122
- } catch {
123
- credentialProviderSdkCache = null;
124
- }
125
- return credentialProviderSdkCache;
117
+ function loadDefaultCredentialProvider() {
118
+ return credentialProviderPromise ??= import("@aws-sdk/credential-provider-node").then(({ defaultProvider }) => defaultProvider).catch(() => null);
126
119
  }
127
120
  const MODEL_PREFIX_RE = /^(?:bedrock|amazon-bedrock|aws)\//;
128
121
  const REGION_RE = /bedrock-runtime\.([a-z0-9-]+)\./;
@@ -295,13 +288,13 @@ function resolveBedrockEmbeddingClient(options) {
295
288
  dimensions
296
289
  };
297
290
  }
298
- async function hasAwsCredentials(env = process.env, loadCredentialProvider = loadCredentialProviderSdk) {
291
+ async function hasAwsCredentials(env = process.env, loadCredentialProvider = loadDefaultCredentialProvider) {
299
292
  if (env.AWS_ACCESS_KEY_ID?.trim() && env.AWS_SECRET_ACCESS_KEY?.trim()) return true;
300
293
  if (env.AWS_BEARER_TOKEN_BEDROCK?.trim()) return true;
301
- const credentialProviderSdk = await loadCredentialProvider();
302
- if (!credentialProviderSdk) return false;
294
+ const defaultProvider = await loadCredentialProvider();
295
+ if (!defaultProvider) return false;
303
296
  try {
304
- const credentials = await credentialProviderSdk.defaultProvider({
297
+ const credentials = await defaultProvider({
305
298
  timeout: 1e3,
306
299
  maxRetries: 0
307
300
  })();
@@ -129,18 +129,15 @@ function resolvedModelSupportsCaching(modelArn) {
129
129
  return supportsBedrockPromptCaching(modelArn);
130
130
  }
131
131
  const appProfileTraitsCache = /* @__PURE__ */ new Map();
132
- async function createBedrockControlPlane(region) {
133
- await refreshAwsSharedConfigCacheForBedrock();
134
- const { BedrockClient, GetInferenceProfileCommand } = await import("@aws-sdk/client-bedrock");
135
- const client = new BedrockClient(region ? { region } : {});
136
- return { getInferenceProfile: async (input) => await client.send(new GetInferenceProfileCommand(input)) };
137
- }
138
132
  async function resolveAppProfileTraits(modelId, fallbackRegion) {
139
133
  const cached = appProfileTraitsCache.get(modelId);
140
134
  if (cached) return cached;
141
135
  try {
142
- const models = (await (await createBedrockControlPlane(extractRegionFromArn(modelId) ?? fallbackRegion)).getInferenceProfile({ inferenceProfileIdentifier: modelId })).models ?? [];
143
- const modelArns = models.map((m) => m.modelArn ?? "");
136
+ const region = extractRegionFromArn(modelId) ?? fallbackRegion;
137
+ await refreshAwsSharedConfigCacheForBedrock();
138
+ const { BedrockClient, GetInferenceProfileCommand } = await import("@aws-sdk/client-bedrock");
139
+ const models = (await new BedrockClient(region ? { region } : {}).send(new GetInferenceProfileCommand({ inferenceProfileIdentifier: modelId }))).models ?? [];
140
+ const modelArns = models.map((model) => model.modelArn ?? "");
144
141
  const traits = {
145
142
  cacheEligible: models.length > 0 && modelArns.every((modelArn) => resolvedModelSupportsCaching(modelArn)),
146
143
  omitTemperature: modelArns.some(isOpus47OrNewerBedrockModelRef)
@@ -173,9 +170,8 @@ function injectBedrockCachePoints(payload, cacheRetention) {
173
170
  const system = payload.system;
174
171
  if (Array.isArray(system) && system.length > 0 && !hasCachePoint(system)) system.push(point);
175
172
  const messages = payload.messages;
176
- if (Array.isArray(messages) && messages.length > 0) for (let i = messages.length - 1; i >= 0; i--) {
177
- const msg = messages[i];
178
- if (msg.role === "user" && Array.isArray(msg.content)) {
173
+ if (Array.isArray(messages) && messages.length > 0) {
174
+ for (const msg of messages.toReversed()) if (msg.role === "user" && Array.isArray(msg.content)) {
179
175
  if (!hasCachePoint(msg.content)) msg.content.push(point);
180
176
  break;
181
177
  }
@@ -5,6 +5,7 @@ import { requiresClaudeMandatoryAdaptiveThinking, resolveClaudeFable5ModelIdenti
5
5
  import { applyAnthropicRefusal, createDeferredEventBuffer, notifyLlmRequestActivity } from "openclaw/plugin-sdk/provider-stream-shared";
6
6
  import { BedrockRuntimeClient, BedrockRuntimeServiceException, CachePointType, CacheTTL, ConversationRole, ConverseStreamCommand, ImageFormat, StopReason, ToolResultStatus } from "@aws-sdk/client-bedrock-runtime";
7
7
  import { NodeHttpHandler } from "@smithy/node-http-handler";
8
+ import { expectDefined } from "openclaw/plugin-sdk/expect-runtime";
8
9
  //#region extensions/amazon-bedrock/stream.runtime.ts
9
10
  /**
10
11
  * Amazon Bedrock Converse streaming runtime. It maps OpenClaw messages/tools,
@@ -284,7 +285,7 @@ function handleContentBlockDelta(event, blocks, output, stream) {
284
285
  };
285
286
  output.content.push(newBlock);
286
287
  index = blocks.length - 1;
287
- block = blocks[index];
288
+ block = newBlock;
288
289
  stream.push({
289
290
  type: "text_start",
290
291
  contentIndex: index,
@@ -375,7 +376,6 @@ function handleContentBlockStop(event, blocks, output, stream) {
375
376
  });
376
377
  break;
377
378
  case "toolCall":
378
- block.arguments = parseStreamingJson(block.partialJson);
379
379
  delete block.partialJson;
380
380
  stream.push({
381
381
  type: "toolcall_end",
@@ -478,7 +478,7 @@ function convertMessages(context, model, cacheRetention) {
478
478
  const result = [];
479
479
  const transformedMessages = transformMessages(context.messages, model, normalizeToolCallId);
480
480
  for (let i = 0; i < transformedMessages.length; i++) {
481
- const m = transformedMessages[i];
481
+ const m = expectDefined(transformedMessages[i], "message conversion index is in bounds");
482
482
  switch (m.role) {
483
483
  case "user": {
484
484
  const content = [];
@@ -547,8 +547,9 @@ function convertMessages(context, model, cacheRetention) {
547
547
  status: m.isError ? ToolResultStatus.ERROR : ToolResultStatus.SUCCESS
548
548
  } });
549
549
  let j = i + 1;
550
- while (j < transformedMessages.length && transformedMessages[j].role === "toolResult") {
551
- const nextMsg = transformedMessages[j];
550
+ while (true) {
551
+ const nextMsg = transformedMessages.at(j);
552
+ if (nextMsg?.role !== "toolResult") break;
552
553
  toolResults.push({ toolResult: {
553
554
  toolUseId: nextMsg.toolCallId,
554
555
  content: nextMsg.content.map((c) => c.type === "image" ? { image: createImageBlock(c.mimeType, c.data) } : { text: sanitizeSurrogates(c.text) }),
@@ -567,7 +568,7 @@ function convertMessages(context, model, cacheRetention) {
567
568
  }
568
569
  }
569
570
  if (cacheRetention !== "none" && supportsPromptCaching(model) && result.length > 0) {
570
- const lastMessage = result[result.length - 1];
571
+ const lastMessage = expectDefined(result.at(-1), "non-empty converted message list");
571
572
  if (lastMessage.role === ConversationRole.USER && lastMessage.content) lastMessage.content.push({ cachePoint: {
572
573
  type: CachePointType.DEFAULT,
573
574
  ...cacheRetention === "long" ? { ttl: CacheTTL.ONE_HOUR } : {}
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@openclaw/amazon-bedrock-provider",
3
- "version": "2026.7.1",
3
+ "version": "2026.7.2-beta.1",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@openclaw/amazon-bedrock-provider",
9
- "version": "2026.7.1",
9
+ "version": "2026.7.2-beta.1",
10
10
  "dependencies": {
11
11
  "@aws-sdk/client-bedrock": "3.1078.0",
12
12
  "@aws-sdk/client-bedrock-runtime": "3.1078.0",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/amazon-bedrock-provider",
3
- "version": "2026.7.1",
3
+ "version": "2026.7.2-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.7.1"
28
+ "pluginApi": ">=2026.7.2-beta.1"
29
29
  },
30
30
  "build": {
31
- "openclawVersion": "2026.7.1",
31
+ "openclawVersion": "2026.7.2-beta.1",
32
32
  "bundledDist": false
33
33
  },
34
34
  "release": {
@@ -46,7 +46,7 @@
46
46
  "README.md"
47
47
  ],
48
48
  "peerDependencies": {
49
- "openclaw": ">=2026.7.1"
49
+ "openclaw": ">=2026.7.2-beta.1"
50
50
  },
51
51
  "peerDependenciesMeta": {
52
52
  "openclaw": {