@openclaw/amazon-bedrock-provider 2026.8.1-beta.2 → 2026.8.1-beta.3
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 +2 -2
- package/dist/discovery.js +1 -6
- package/dist/register.sync.runtime.js +2 -1
- package/dist/stream.runtime.js +43 -19
- package/openclaw.plugin.json +1 -1
- package/package.json +4 -4
package/dist/api.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { mergeImplicitBedrockProvider, resolveBedrockConfigApiKey } from "./discovery-shared.js";
|
|
2
|
-
import { discoverBedrockModels,
|
|
3
|
-
export { discoverBedrockModels, mergeImplicitBedrockProvider,
|
|
2
|
+
import { discoverBedrockModels, resolveImplicitBedrockProvider } from "./discovery.js";
|
|
3
|
+
export { discoverBedrockModels, mergeImplicitBedrockProvider, resolveBedrockConfigApiKey, resolveImplicitBedrockProvider };
|
package/dist/discovery.js
CHANGED
|
@@ -278,11 +278,6 @@ function resolveInferenceProfiles(profiles, defaults, providerFilter, foundation
|
|
|
278
278
|
}
|
|
279
279
|
return discovered;
|
|
280
280
|
}
|
|
281
|
-
/** Reset Bedrock discovery cache for tests. */
|
|
282
|
-
function resetBedrockDiscoveryCacheForTest() {
|
|
283
|
-
discoveryCache.clear();
|
|
284
|
-
hasLoggedBedrockError = false;
|
|
285
|
-
}
|
|
286
281
|
/** Discover Bedrock models and inference profiles for one region/config. */
|
|
287
282
|
async function discoverBedrockModels(params) {
|
|
288
283
|
const refreshIntervalSeconds = Math.max(0, Math.floor(params.config?.refreshInterval ?? DEFAULT_REFRESH_INTERVAL_SECONDS));
|
|
@@ -400,4 +395,4 @@ async function resolveImplicitBedrockProvider(params) {
|
|
|
400
395
|
};
|
|
401
396
|
}
|
|
402
397
|
//#endregion
|
|
403
|
-
export { discoverBedrockModels,
|
|
398
|
+
export { discoverBedrockModels, resolveImplicitBedrockProvider };
|
|
@@ -5,6 +5,7 @@ import { mergeImplicitBedrockProvider, resolveBedrockConfigApiKey } from "./disc
|
|
|
5
5
|
import { bedrockMemoryEmbeddingProviderAdapter } from "./memory-embedding-adapter.js";
|
|
6
6
|
import { isLatestAdaptiveBedrockModelRef, isOpus47OrNewerBedrockModelRef, resolveBedrockClaudeThinkingProfile, resolveBedrockNativeThinkingLevelMap, supportsBedrockNativeMaxEffort } from "./thinking-policy.js";
|
|
7
7
|
import { streamSimpleBedrock } from "./stream.runtime.js";
|
|
8
|
+
import { adaptMemoryEmbeddingProviderAdapter } from "openclaw/plugin-sdk/memory-core-host-engine-embeddings";
|
|
8
9
|
import { resolvePluginConfigObject } from "openclaw/plugin-sdk/plugin-config-runtime";
|
|
9
10
|
import { buildProviderReplayFamilyHooks, normalizeProviderId, resolveClaudeFable5ModelIdentity, resolveClaudeModelIdentity, resolveClaudeMythos5ModelIdentity, resolveClaudeOpus5ModelIdentity, resolveClaudeSonnet5ModelIdentity } from "openclaw/plugin-sdk/provider-model-shared";
|
|
10
11
|
import { createPayloadPatchStreamWrapper } from "openclaw/plugin-sdk/provider-stream-shared";
|
|
@@ -215,7 +216,7 @@ function registerAmazonBedrockPlugin(api) {
|
|
|
215
216
|
function resolveCurrentPluginConfig(config) {
|
|
216
217
|
return resolvePluginConfigObject(config, providerId) ?? (config ? void 0 : startupPluginConfig);
|
|
217
218
|
}
|
|
218
|
-
api.
|
|
219
|
+
api.registerEmbeddingProvider(adaptMemoryEmbeddingProviderAdapter(bedrockMemoryEmbeddingProviderAdapter));
|
|
219
220
|
const baseWrapStreamFn = ({ modelId, model, streamFn }) => {
|
|
220
221
|
const modelRef = {
|
|
221
222
|
id: modelId,
|
package/dist/stream.runtime.js
CHANGED
|
@@ -2,13 +2,13 @@ import { supportsBedrockPromptCaching } from "./bedrock-options.js";
|
|
|
2
2
|
import { supportsBedrockNativeMaxEffort } from "./thinking-policy.js";
|
|
3
3
|
import { requiresClaudeMandatoryAdaptiveThinking, resolveClaudeFable5ModelIdentity, resolveClaudeModelIdentity, resolveClaudeMythos5ModelIdentity, resolveClaudeOpus5ModelIdentity, resolveClaudeSonnet5ModelIdentity, supportsClaudeAdaptiveThinking, supportsClaudeNativeXhighEffort } from "openclaw/plugin-sdk/provider-model-shared";
|
|
4
4
|
import { applyAnthropicRefusal, createDeferredEventBuffer, notifyLlmRequestActivity } from "openclaw/plugin-sdk/provider-stream-shared";
|
|
5
|
-
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
5
|
+
import { isRecord, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
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
8
|
import { expectDefined } from "openclaw/plugin-sdk/expect-runtime";
|
|
9
9
|
import { AssistantMessageEventStream, adjustMaxTokensForThinking, buildBaseOptions, calculateCost, clampReasoning, createHttpProxyAgentsForTarget, parseStreamingJson, sanitizeSurrogates, transformMessages } from "openclaw/plugin-sdk/llm";
|
|
10
10
|
import { canonicalizeBase64 } from "openclaw/plugin-sdk/media-runtime";
|
|
11
|
-
import { describeToolResultMediaPlaceholder } from "openclaw/plugin-sdk/provider-transport-runtime";
|
|
11
|
+
import { describeToolResultMediaPlaceholder, finalizeTerminalToolCallArguments, notifyProviderHttpMetadata } from "openclaw/plugin-sdk/provider-transport-runtime";
|
|
12
12
|
//#region extensions/amazon-bedrock/stream.runtime.ts
|
|
13
13
|
/**
|
|
14
14
|
* Amazon Bedrock Converse streaming runtime. It maps OpenClaw messages/tools,
|
|
@@ -72,6 +72,7 @@ const streamBedrock = (model, context, options = {}) => {
|
|
|
72
72
|
timestamp: Date.now()
|
|
73
73
|
};
|
|
74
74
|
const blocks = output.content;
|
|
75
|
+
const pendingToolCallEnds = [];
|
|
75
76
|
const redactedReasoningChunks = /* @__PURE__ */ new Map();
|
|
76
77
|
const fable5 = usesClaudeFable5BedrockContract(model);
|
|
77
78
|
const refusalBuffer = usesClaudeStreamingRefusalBedrockContract(model) ? createDeferredEventBuffer(stream, () => notifyLlmRequestActivity(options.signal)) : void 0;
|
|
@@ -125,16 +126,24 @@ const streamBedrock = (model, context, options = {}) => {
|
|
|
125
126
|
if (nextCommandInput !== void 0) commandInput = nextCommandInput;
|
|
126
127
|
const command = new ConverseStreamCommand(commandInput);
|
|
127
128
|
const response = await client.send(command, { abortSignal: options.signal });
|
|
129
|
+
const responseIterator = response.stream[Symbol.asyncIterator]();
|
|
128
130
|
if (response.$metadata.httpStatusCode !== void 0) {
|
|
129
131
|
const responseHeaders = {};
|
|
130
132
|
if (response.$metadata.requestId) responseHeaders["x-amzn-requestid"] = response.$metadata.requestId;
|
|
131
|
-
await
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
133
|
+
await notifyProviderHttpMetadata({
|
|
134
|
+
options,
|
|
135
|
+
response: {
|
|
136
|
+
status: response.$metadata.httpStatusCode,
|
|
137
|
+
headers: responseHeaders
|
|
138
|
+
},
|
|
139
|
+
model,
|
|
140
|
+
cancelStream: async () => {
|
|
141
|
+
await responseIterator.return?.();
|
|
142
|
+
}
|
|
143
|
+
});
|
|
135
144
|
}
|
|
136
145
|
let sawMessageStop = false;
|
|
137
|
-
for await (const item of
|
|
146
|
+
for await (const item of { [Symbol.asyncIterator]: () => responseIterator }) if (item.messageStart) {
|
|
138
147
|
if (item.messageStart.role !== ConversationRole.ASSISTANT) throw new Error("Unexpected assistant message start but got user message start instead");
|
|
139
148
|
eventSink.push({
|
|
140
149
|
type: "start",
|
|
@@ -142,7 +151,7 @@ const streamBedrock = (model, context, options = {}) => {
|
|
|
142
151
|
});
|
|
143
152
|
} else if (item.contentBlockStart) handleContentBlockStart(item.contentBlockStart, blocks, output, eventSink);
|
|
144
153
|
else if (item.contentBlockDelta) handleContentBlockDelta(item.contentBlockDelta, blocks, output, eventSink, redactedReasoningChunks);
|
|
145
|
-
else if (item.contentBlockStop) handleContentBlockStop(item.contentBlockStop, blocks, output, eventSink, redactedReasoningChunks);
|
|
154
|
+
else if (item.contentBlockStop) handleContentBlockStop(item.contentBlockStop, blocks, output, eventSink, redactedReasoningChunks, pendingToolCallEnds);
|
|
146
155
|
else if (item.messageStop) {
|
|
147
156
|
sawMessageStop = true;
|
|
148
157
|
if (item.messageStop.stopReason === "refusal") applyAnthropicRefusal(output, readBedrockStopDetails(item.messageStop.additionalModelResponseFields), model.provider);
|
|
@@ -160,7 +169,8 @@ const streamBedrock = (model, context, options = {}) => {
|
|
|
160
169
|
if (!sawMessageStop) throw new Error("Bedrock stream ended before messageStop");
|
|
161
170
|
if (options.signal?.aborted) throw new Error("Request was aborted");
|
|
162
171
|
if (output.stopReason === "error" || output.stopReason === "aborted") throw new Error(output.errorMessage ?? "An unknown error occurred");
|
|
163
|
-
for (const block of blocks) if (block.index !== void 0) handleContentBlockStop({ contentBlockIndex: block.index }, blocks, output, eventSink, redactedReasoningChunks);
|
|
172
|
+
for (const block of blocks) if (block.index !== void 0 && block.type !== "toolCall") handleContentBlockStop({ contentBlockIndex: block.index }, blocks, output, eventSink, redactedReasoningChunks, pendingToolCallEnds);
|
|
173
|
+
flushPendingBedrockToolCalls(pendingToolCallEnds, blocks, output, eventSink);
|
|
164
174
|
refusalBuffer?.flush();
|
|
165
175
|
stream.push({
|
|
166
176
|
type: "done",
|
|
@@ -169,6 +179,7 @@ const streamBedrock = (model, context, options = {}) => {
|
|
|
169
179
|
});
|
|
170
180
|
stream.end();
|
|
171
181
|
} catch (error) {
|
|
182
|
+
output.content = output.content.filter((block) => block.type !== "toolCall");
|
|
172
183
|
for (const block of output.content) {
|
|
173
184
|
delete block.index;
|
|
174
185
|
delete block.partialJson;
|
|
@@ -274,11 +285,12 @@ function handleContentBlockStart(event, blocks, output, stream) {
|
|
|
274
285
|
const index = event.contentBlockIndex;
|
|
275
286
|
const start = event.start;
|
|
276
287
|
if (start?.toolUse) {
|
|
288
|
+
const startArguments = isRecord(start.toolUse) ? start.toolUse.input : void 0;
|
|
277
289
|
const block = {
|
|
278
290
|
type: "toolCall",
|
|
279
291
|
id: start.toolUse.toolUseId || "",
|
|
280
292
|
name: start.toolUse.name || "",
|
|
281
|
-
arguments: {},
|
|
293
|
+
arguments: isRecord(startArguments) ? startArguments : {},
|
|
282
294
|
partialJson: "",
|
|
283
295
|
index
|
|
284
296
|
};
|
|
@@ -387,13 +399,13 @@ function handleMetadata(event, model, output) {
|
|
|
387
399
|
calculateCost(model, output.usage);
|
|
388
400
|
}
|
|
389
401
|
}
|
|
390
|
-
function handleContentBlockStop(event, blocks, output, stream, redactedReasoningChunks) {
|
|
402
|
+
function handleContentBlockStop(event, blocks, output, stream, redactedReasoningChunks, pendingToolCallEnds) {
|
|
391
403
|
const index = blocks.findIndex((b) => b.index === event.contentBlockIndex);
|
|
392
404
|
const block = blocks[index];
|
|
393
405
|
if (!block) return;
|
|
394
|
-
delete block.index;
|
|
395
406
|
switch (block.type) {
|
|
396
407
|
case "text":
|
|
408
|
+
delete block.index;
|
|
397
409
|
stream.push({
|
|
398
410
|
type: "text_end",
|
|
399
411
|
contentIndex: index,
|
|
@@ -402,6 +414,7 @@ function handleContentBlockStop(event, blocks, output, stream, redactedReasoning
|
|
|
402
414
|
});
|
|
403
415
|
break;
|
|
404
416
|
case "thinking":
|
|
417
|
+
delete block.index;
|
|
405
418
|
if (block.redacted) {
|
|
406
419
|
const chunks = redactedReasoningChunks.get(event.contentBlockIndex);
|
|
407
420
|
if (chunks) {
|
|
@@ -419,16 +432,27 @@ function handleContentBlockStop(event, blocks, output, stream, redactedReasoning
|
|
|
419
432
|
});
|
|
420
433
|
break;
|
|
421
434
|
case "toolCall":
|
|
422
|
-
delete block.
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
contentIndex: index
|
|
426
|
-
toolCall: block,
|
|
427
|
-
partial: output
|
|
435
|
+
delete block.index;
|
|
436
|
+
pendingToolCallEnds.push({
|
|
437
|
+
block,
|
|
438
|
+
contentIndex: index
|
|
428
439
|
});
|
|
429
440
|
break;
|
|
430
441
|
}
|
|
431
442
|
}
|
|
443
|
+
function flushPendingBedrockToolCalls(pending, blocks, output, stream) {
|
|
444
|
+
if (blocks.some((block) => block.type === "toolCall" && block.index !== void 0)) throw new Error("Provider completed stream with an incomplete tool call");
|
|
445
|
+
finalizeTerminalToolCallArguments(pending.map(({ block }) => block), (block) => block.partialJson && block.partialJson.length > 0 ? block.partialJson : block.arguments);
|
|
446
|
+
for (const toolCall of pending) {
|
|
447
|
+
delete toolCall.block.partialJson;
|
|
448
|
+
stream.push({
|
|
449
|
+
type: "toolcall_end",
|
|
450
|
+
contentIndex: toolCall.contentIndex,
|
|
451
|
+
toolCall: toolCall.block,
|
|
452
|
+
partial: output
|
|
453
|
+
});
|
|
454
|
+
}
|
|
455
|
+
}
|
|
432
456
|
function resolveClaudeProfileNameModelId(modelName) {
|
|
433
457
|
const normalized = modelName?.trim().toLowerCase().replace(/[\s_.:]+/g, "-") ?? "";
|
|
434
458
|
if (!normalized.includes("claude")) return;
|
|
@@ -639,7 +663,7 @@ function convertToolConfig(tools, toolChoice) {
|
|
|
639
663
|
const bedrockTools = tools.map((tool) => ({ toolSpec: {
|
|
640
664
|
name: tool.name,
|
|
641
665
|
description: tool.description,
|
|
642
|
-
inputSchema: { json: tool.parameters }
|
|
666
|
+
inputSchema: { json: { ...tool.parameters } }
|
|
643
667
|
} }));
|
|
644
668
|
let bedrockToolChoice;
|
|
645
669
|
switch (toolChoice) {
|
package/openclaw.plugin.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/amazon-bedrock-provider",
|
|
3
|
-
"version": "2026.8.1-beta.
|
|
3
|
+
"version": "2026.8.1-beta.3",
|
|
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.8.1-beta.
|
|
28
|
+
"pluginApi": ">=2026.8.1-beta.3"
|
|
29
29
|
},
|
|
30
30
|
"build": {
|
|
31
|
-
"openclawVersion": "2026.8.1-beta.
|
|
31
|
+
"openclawVersion": "2026.8.1-beta.3",
|
|
32
32
|
"bundledDist": false
|
|
33
33
|
},
|
|
34
34
|
"release": {
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"README.md"
|
|
46
46
|
],
|
|
47
47
|
"peerDependencies": {
|
|
48
|
-
"openclaw": ">=2026.8.1-beta.
|
|
48
|
+
"openclaw": ">=2026.8.1-beta.3"
|
|
49
49
|
},
|
|
50
50
|
"peerDependenciesMeta": {
|
|
51
51
|
"openclaw": {
|