@openclaw/amazon-bedrock-provider 2026.9.6 → 2026.9.7

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/assets/icon.png CHANGED
Binary file
@@ -0,0 +1,258 @@
1
+ import { asNullableRecord, isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
2
+ //#region \0rolldown/runtime.js
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __exportAll = (all, no_symbols) => {
8
+ let target = {};
9
+ for (var name in all) __defProp(target, name, {
10
+ get: all[name],
11
+ enumerable: true
12
+ });
13
+ if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
14
+ return target;
15
+ };
16
+ var __copyProps = (to, from, except, desc) => {
17
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
18
+ key = keys[i];
19
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
20
+ get: ((k) => from[k]).bind(null, key),
21
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
22
+ });
23
+ }
24
+ return to;
25
+ };
26
+ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
27
+ //#endregion
28
+ //#region packages/normalization-core/src/record-coerce.ts
29
+ /** Type guard for non-array object records at browser-safe boundaries. */
30
+ function isRecord$1(value) {
31
+ return value !== null && typeof value === "object" && !Array.isArray(value);
32
+ }
33
+ /** Returns a non-array record or null. */
34
+ function asNullableRecord$1(value) {
35
+ return isRecord$1(value) ? value : null;
36
+ }
37
+ //#endregion
38
+ //#region src/config/channel-config-normalization.ts
39
+ /** Applies one channel-specific doctor migration to every object-shaped account. */
40
+ function normalizeChannelAccounts(params) {
41
+ const rawAccounts = asNullableRecord$1(params.entry.accounts);
42
+ if (!rawAccounts) return {
43
+ entry: params.entry,
44
+ changed: false
45
+ };
46
+ let changed = false;
47
+ const accounts = { ...rawAccounts };
48
+ for (const [accountId, value] of Object.entries(rawAccounts)) {
49
+ const account = asNullableRecord$1(value);
50
+ if (!account) continue;
51
+ const normalized = params.normalizeAccount({
52
+ account,
53
+ accountId,
54
+ pathPrefix: `${params.pathPrefix}.accounts.${accountId}`,
55
+ changes: params.changes
56
+ });
57
+ if (normalized.changed) {
58
+ accounts[accountId] = normalized.entry;
59
+ changed = true;
60
+ }
61
+ }
62
+ return changed ? {
63
+ entry: {
64
+ ...params.entry,
65
+ accounts
66
+ },
67
+ changed: true
68
+ } : {
69
+ entry: params.entry,
70
+ changed: false
71
+ };
72
+ }
73
+ /** Applies the same channel-specific doctor migration at root and account scope. */
74
+ function normalizeChannelConfigEntries(params) {
75
+ const changes = params.changes ?? [];
76
+ const channels = params.cfg.channels;
77
+ const entry = asNullableRecord$1(channels?.[params.channelId]);
78
+ if (!entry) return {
79
+ config: params.cfg,
80
+ changes
81
+ };
82
+ const channelPath = `channels.${params.channelId}`;
83
+ const root = params.normalizeEntry({
84
+ entry,
85
+ pathPrefix: channelPath,
86
+ changes
87
+ });
88
+ const accounts = normalizeChannelAccounts({
89
+ entry: root.entry,
90
+ pathPrefix: channelPath,
91
+ changes,
92
+ normalizeAccount: (accountParams) => params.normalizeEntry({
93
+ entry: accountParams.account,
94
+ accountId: accountParams.accountId,
95
+ pathPrefix: accountParams.pathPrefix,
96
+ changes: accountParams.changes
97
+ })
98
+ });
99
+ if (!root.changed && !accounts.changed) return {
100
+ config: params.cfg,
101
+ changes
102
+ };
103
+ return {
104
+ config: {
105
+ ...params.cfg,
106
+ channels: {
107
+ ...channels,
108
+ [params.channelId]: accounts.entry
109
+ }
110
+ },
111
+ changes
112
+ };
113
+ }
114
+ //#endregion
115
+ //#region src/plugin-sdk/legacy-webhook-listener-migration.ts
116
+ /** Preserve explicitly configured webhook listeners while moving ingress onto Gateway routes. */
117
+ function createLegacyWebhookListenerDoctorContract(params) {
118
+ const portKey = params.portKey ?? "webhookPort";
119
+ const hostKey = params.hostKey === void 0 ? "webhookHost" : params.hostKey;
120
+ const source = (entry) => params.webhookKey ? asNullableRecord$1(entry[params.webhookKey]) : entry;
121
+ const hasLegacy = (value) => {
122
+ const entry = asNullableRecord$1(value);
123
+ const listener = entry && source(entry);
124
+ return Boolean(listener && (Object.hasOwn(listener, portKey) || hostKey && Object.hasOwn(listener, hostKey)));
125
+ };
126
+ const prefix = `channels.${params.channelKey}`;
127
+ return {
128
+ legacyConfigRules: [{
129
+ path: ["channels", params.channelKey],
130
+ message: `${prefix} webhook listeners moved to Gateway routes. Run "openclaw doctor --fix" to preserve explicitly configured listener settings as legacyWebhook.`,
131
+ match: (value) => {
132
+ const accounts = asNullableRecord$1(asNullableRecord$1(value)?.accounts);
133
+ return hasLegacy(value) || Object.values(accounts ?? {}).some(hasLegacy);
134
+ }
135
+ }],
136
+ normalizeCompatibilityConfig: ({ cfg }) => {
137
+ const root = asNullableRecord$1(asNullableRecord$1(cfg.channels)?.[params.channelKey]);
138
+ const inherited = root && source(root);
139
+ const canonicalRoot = asNullableRecord$1(root?.legacyWebhook);
140
+ return normalizeChannelConfigEntries({
141
+ cfg,
142
+ channelId: params.channelKey,
143
+ normalizeEntry: ({ entry, accountId, pathPrefix, changes }) => {
144
+ const listener = source(entry);
145
+ if (!listener || !hasLegacy(entry)) return {
146
+ entry,
147
+ changed: false
148
+ };
149
+ const next = { ...entry };
150
+ const port = Object.hasOwn(listener, portKey) ? listener[portKey] : (accountId ? canonicalRoot?.port ?? inherited?.[portKey] : void 0) ?? params.defaultPort;
151
+ const inheritedHost = accountId ? canonicalRoot ? canonicalRoot.host : (hostKey ? inherited?.[hostKey] : void 0) ?? params.defaultHost : params.defaultHost;
152
+ const host = hostKey ? listener[hostKey] ?? inheritedHost : inheritedHost;
153
+ const legacyPath = [pathPrefix, params.webhookKey].filter(Boolean).join(".");
154
+ if (Object.hasOwn(entry, "legacyWebhook")) changes.push(`Removed ${legacyPath} legacy listener keys; ${pathPrefix}.legacyWebhook is already configured.`);
155
+ else if (accountId && root?.legacyWebhook === false) changes.push(`Removed ${legacyPath} legacy listener keys; ${prefix}.legacyWebhook: false keeps this account's inherited listener disabled.`);
156
+ else {
157
+ next.legacyWebhook = {
158
+ port,
159
+ ...host !== void 0 ? { host } : {}
160
+ };
161
+ changes.push(`Moved ${legacyPath} listener settings to ${pathPrefix}.legacyWebhook. Point the external callback or reverse proxy at the Gateway port and webhook path, verify delivery, then set legacyWebhook: false to disable legacy forwarding.`);
162
+ }
163
+ const updated = params.webhookKey ? { ...listener } : next;
164
+ delete updated[portKey];
165
+ if (hostKey) delete updated[hostKey];
166
+ if (params.webhookKey) {
167
+ if (Object.keys(updated).length) next[params.webhookKey] = updated;
168
+ else delete next[params.webhookKey];
169
+ }
170
+ return {
171
+ entry: next,
172
+ changed: true
173
+ };
174
+ }
175
+ });
176
+ }
177
+ };
178
+ }
179
+ //#endregion
180
+ //#region \0openclaw:bundled-sdk:openclaw/plugin-sdk/runtime-doctor-migrations
181
+ var runtime_doctor_migrations_exports = /* @__PURE__ */ __exportAll({ createLegacyWebhookListenerDoctorContract: () => createLegacyWebhookListenerDoctorContract });
182
+ import * as import_openclaw_plugin_sdk_runtime_doctor_migrations from "openclaw/plugin-sdk/runtime-doctor-migrations";
183
+ __reExport(runtime_doctor_migrations_exports, import_openclaw_plugin_sdk_runtime_doctor_migrations);
184
+ //#endregion
185
+ //#region extensions/amazon-bedrock/config-compat.ts
186
+ /**
187
+ * Legacy config migration for Amazon Bedrock discovery settings. It moves
188
+ * old `models.bedrockDiscovery` config into plugin-local config shape.
189
+ */
190
+ const LEGACY_PATH = "models.bedrockDiscovery";
191
+ const TARGET_PATH = "plugins.entries.amazon-bedrock.config.discovery";
192
+ function ensureRecord(root, key) {
193
+ const existing = root[key];
194
+ if (isRecord(existing)) return existing;
195
+ const next = {};
196
+ root[key] = next;
197
+ return next;
198
+ }
199
+ function resolveLegacyBedrockDiscoveryConfig(raw) {
200
+ if (!isRecord(raw)) return;
201
+ const models = asNullableRecord(raw.models);
202
+ return asNullableRecord(models?.bedrockDiscovery) ?? void 0;
203
+ }
204
+ function pruneEmptyModelsRoot(root) {
205
+ const models = asNullableRecord(root.models);
206
+ if (models && Object.keys(models).length === 0) delete root.models;
207
+ }
208
+ /** Migrate legacy Bedrock discovery config into `plugins.entries.amazon-bedrock.config`. */
209
+ function migrateAmazonBedrockLegacyConfig(raw) {
210
+ if (!isRecord(raw)) return {
211
+ config: raw,
212
+ changes: []
213
+ };
214
+ const legacy = resolveLegacyBedrockDiscoveryConfig(raw);
215
+ if (!legacy) return {
216
+ config: raw,
217
+ changes: []
218
+ };
219
+ const nextRoot = structuredClone(raw);
220
+ const models = ensureRecord(nextRoot, "models");
221
+ delete models.bedrockDiscovery;
222
+ pruneEmptyModelsRoot(nextRoot);
223
+ const changes = [];
224
+ if (Object.keys(legacy).length === 0) {
225
+ changes.push(`Removed empty ${LEGACY_PATH}.`);
226
+ return {
227
+ config: nextRoot,
228
+ changes
229
+ };
230
+ }
231
+ const config = ensureRecord(ensureRecord(ensureRecord(ensureRecord(nextRoot, "plugins"), "entries"), "amazon-bedrock"), "config");
232
+ const existing = asNullableRecord(config.discovery) ?? void 0;
233
+ if (!existing) {
234
+ config.discovery = { ...legacy };
235
+ changes.push(`Moved ${LEGACY_PATH} → ${TARGET_PATH}.`);
236
+ return {
237
+ config: nextRoot,
238
+ changes
239
+ };
240
+ }
241
+ const merged = { ...existing };
242
+ (0, runtime_doctor_migrations_exports.mergeMissing)(merged, legacy);
243
+ config.discovery = merged;
244
+ if (JSON.stringify(merged) !== JSON.stringify(existing)) {
245
+ changes.push(`Merged ${LEGACY_PATH} → ${TARGET_PATH} (filled missing fields from legacy; kept explicit plugin config values).`);
246
+ return {
247
+ config: nextRoot,
248
+ changes
249
+ };
250
+ }
251
+ changes.push(`Removed ${LEGACY_PATH} (${TARGET_PATH} already set).`);
252
+ return {
253
+ config: nextRoot,
254
+ changes
255
+ };
256
+ }
257
+ //#endregion
258
+ export { migrateAmazonBedrockLegacyConfig as t };
@@ -1,19 +1,7 @@
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
- */
6
- function hasStaticAwsCredentialEnv(env) {
7
- return Boolean(env.AWS_ACCESS_KEY_ID && env.AWS_SECRET_ACCESS_KEY);
8
- }
9
- /** Return whether Bedrock should refresh the AWS shared config cache before discovery. */
10
- function shouldRefreshAwsSharedConfigCacheForBedrock(env) {
11
- if (env.AWS_BEDROCK_SKIP_AUTH === "1" || env.AWS_BEARER_TOKEN_BEDROCK) return false;
12
- return !hasStaticAwsCredentialEnv(env);
13
- }
14
2
  /** Refresh Smithy shared config files when Bedrock needs default-chain credentials. */
15
3
  async function refreshAwsSharedConfigCacheForBedrock(env = process.env) {
16
- if (!shouldRefreshAwsSharedConfigCacheForBedrock(env)) return;
4
+ if (env.AWS_BEDROCK_SKIP_AUTH === "1" || env.AWS_BEARER_TOKEN_BEDROCK || env.AWS_ACCESS_KEY_ID && env.AWS_SECRET_ACCESS_KEY) return;
17
5
  const { loadSharedConfigFiles } = await import("@smithy/shared-ini-file-loader");
18
6
  await loadSharedConfigFiles({ ignoreCache: true });
19
7
  }
@@ -1,81 +1,2 @@
1
- import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
2
- import { mergeMissing } from "openclaw/plugin-sdk/runtime-doctor-migrations";
3
- //#region extensions/amazon-bedrock/config-compat.ts
4
- /**
5
- * Legacy config migration for Amazon Bedrock discovery settings. It moves
6
- * old `models.bedrockDiscovery` config into plugin-local config shape.
7
- */
8
- const LEGACY_PATH = "models.bedrockDiscovery";
9
- const TARGET_PATH = "plugins.entries.amazon-bedrock.config.discovery";
10
- function getRecord(value) {
11
- return isRecord(value) ? value : null;
12
- }
13
- function ensureRecord(root, key) {
14
- const existing = root[key];
15
- if (isRecord(existing)) return existing;
16
- const next = {};
17
- root[key] = next;
18
- return next;
19
- }
20
- function cloneRecord(value) {
21
- return { ...value };
22
- }
23
- function resolveLegacyBedrockDiscoveryConfig(raw) {
24
- if (!isRecord(raw)) return;
25
- return getRecord(getRecord(raw.models)?.bedrockDiscovery) ?? void 0;
26
- }
27
- function pruneEmptyModelsRoot(root) {
28
- const models = getRecord(root.models);
29
- if (models && Object.keys(models).length === 0) delete root.models;
30
- }
31
- /** Migrate legacy Bedrock discovery config into `plugins.entries.amazon-bedrock.config`. */
32
- function migrateAmazonBedrockLegacyConfig(raw) {
33
- if (!isRecord(raw)) return {
34
- config: raw,
35
- changes: []
36
- };
37
- const legacy = resolveLegacyBedrockDiscoveryConfig(raw);
38
- if (!legacy) return {
39
- config: raw,
40
- changes: []
41
- };
42
- const nextRoot = structuredClone(raw);
43
- const models = ensureRecord(nextRoot, "models");
44
- delete models.bedrockDiscovery;
45
- pruneEmptyModelsRoot(nextRoot);
46
- const changes = [];
47
- if (Object.keys(legacy).length === 0) {
48
- changes.push(`Removed empty ${LEGACY_PATH}.`);
49
- return {
50
- config: nextRoot,
51
- changes
52
- };
53
- }
54
- const config = ensureRecord(ensureRecord(ensureRecord(ensureRecord(nextRoot, "plugins"), "entries"), "amazon-bedrock"), "config");
55
- const existing = getRecord(config.discovery) ?? void 0;
56
- if (!existing) {
57
- config.discovery = cloneRecord(legacy);
58
- changes.push(`Moved ${LEGACY_PATH} → ${TARGET_PATH}.`);
59
- return {
60
- config: nextRoot,
61
- changes
62
- };
63
- }
64
- const merged = cloneRecord(existing);
65
- mergeMissing(merged, legacy);
66
- config.discovery = merged;
67
- if (JSON.stringify(merged) !== JSON.stringify(existing)) {
68
- changes.push(`Merged ${LEGACY_PATH} → ${TARGET_PATH} (filled missing fields from legacy; kept explicit plugin config values).`);
69
- return {
70
- config: nextRoot,
71
- changes
72
- };
73
- }
74
- changes.push(`Removed ${LEGACY_PATH} (${TARGET_PATH} already set).`);
75
- return {
76
- config: nextRoot,
77
- changes
78
- };
79
- }
80
- //#endregion
1
+ import { t as migrateAmazonBedrockLegacyConfig } from "./.setup/config-compat-C0KbKqqH.mjs";
81
2
  export { migrateAmazonBedrockLegacyConfig };
package/dist/discovery.js CHANGED
@@ -102,9 +102,6 @@ function resolveKnownContextWindow(modelId) {
102
102
  function isKnownClaudeMythosPreviewModelId(modelId) {
103
103
  return [modelId, modelId.replace(/^(?:us|eu|ap|apac|au|jp|global)\./, "")].some((candidate) => /(?:^|[/.:])anthropic\.claude-mythos-preview(?:$|[-.:/])/i.test(candidate));
104
104
  }
105
- function resolveKnownThinkingLevelMap(modelId) {
106
- return resolveBedrockNativeThinkingLevelMap(modelId);
107
- }
108
105
  function resolveKnownMaxTokens(modelId) {
109
106
  return resolveClaudeFable5ModelIdentity({ id: modelId }) || resolveClaudeMythos5ModelIdentity({ id: modelId }) || resolveClaudeSonnet5ModelIdentity({ id: modelId }) || resolveClaudeOpus5ModelIdentity({ id: modelId }) ? 128e3 : void 0;
110
107
  }
@@ -172,7 +169,7 @@ function shouldIncludeSummary(summary, filter) {
172
169
  }
173
170
  function toModelDefinition(summary, defaults) {
174
171
  const id = summary.modelId?.trim() ?? "";
175
- const thinkingLevelMap = resolveKnownThinkingLevelMap(id);
172
+ const thinkingLevelMap = resolveBedrockNativeThinkingLevelMap(id);
176
173
  return {
177
174
  id,
178
175
  name: summary.modelName?.trim() || id,
@@ -250,7 +247,7 @@ function resolveInferenceProfiles(profiles, defaults, providerFilter, foundation
250
247
  const baseModelId = resolveBaseModelId(profile);
251
248
  if (isKnownClaudeMythosPreviewModelId(baseModelId ?? profile.inferenceProfileId)) continue;
252
249
  const baseModel = baseModelId ? foundationModels.get(normalizeLowercaseStringOrEmpty(baseModelId)) : void 0;
253
- const knownThinkingLevelMap = resolveKnownThinkingLevelMap(baseModelId ?? profile.inferenceProfileId);
250
+ const knownThinkingLevelMap = resolveBedrockNativeThinkingLevelMap(baseModelId ?? profile.inferenceProfileId);
254
251
  const contractModelId = baseModelId ?? profile.inferenceProfileId;
255
252
  const canonicalClaudeId = resolveClaudeModelIdentity({ id: baseModelId });
256
253
  discovered.push({
package/dist/index.js CHANGED
@@ -9,9 +9,7 @@ var amazon_bedrock_default = definePluginEntry({
9
9
  id: "amazon-bedrock",
10
10
  name: "Amazon Bedrock Provider",
11
11
  description: "Bundled Amazon Bedrock provider policy plugin",
12
- register(api) {
13
- registerAmazonBedrockPlugin(api);
14
- }
12
+ register: registerAmazonBedrockPlugin
15
13
  });
16
14
  //#endregion
17
15
  export { amazon_bedrock_default as default };
@@ -1,29 +1,5 @@
1
1
  import { resolveBedrockClaudeThinkingProfile } from "./thinking-policy.js";
2
- //#region packages/normalization-core/src/string-coerce.ts
3
- /** Trims string input and returns null for non-strings or empty strings. */
4
- function normalizeNullableString(value) {
5
- if (typeof value !== "string") return null;
6
- const trimmed = value.trim();
7
- return trimmed ? trimmed : null;
8
- }
9
- /** Trims string input and returns undefined for non-strings or empty strings. */
10
- function normalizeOptionalString(value) {
11
- return normalizeNullableString(value) ?? void 0;
12
- }
13
- /** Lowercases a normalized optional string. */
14
- function normalizeOptionalLowercaseString(value) {
15
- return normalizeOptionalString(value)?.toLowerCase();
16
- }
17
- /** Lowercases a normalized string or returns an empty string when absent. */
18
- function normalizeLowercaseStringOrEmpty(value) {
19
- return normalizeOptionalLowercaseString(value) ?? "";
20
- }
21
- //#endregion
22
- //#region packages/model-catalog-core/src/provider-id.ts
23
- function normalizeProviderId(provider) {
24
- return normalizeLowercaseStringOrEmpty(provider);
25
- }
26
- //#endregion
2
+ import { normalizeProviderId } from "openclaw/plugin-sdk/model-ref-parse";
27
3
  //#region extensions/amazon-bedrock/provider-policy-api.ts
28
4
  /**
29
5
  * Provider-policy API for Amazon Bedrock. Core asks this plugin for thinking
@@ -74,20 +74,15 @@ function createBedrockServiceTierWrapper(underlying, serviceTier) {
74
74
  payload.serviceTier ??= { type: serviceTier };
75
75
  }, { shouldPatch: ({ model }) => model.api === "bedrock-converse-stream" });
76
76
  }
77
- function createGuardrailWrapStreamFn(innerWrapStreamFn, guardrailConfig) {
78
- return (ctx) => {
79
- const inner = innerWrapStreamFn(ctx);
80
- if (!inner) return inner;
81
- return createPayloadPatchStreamWrapper(inner, ({ payload }) => {
82
- const gc = {
83
- guardrailIdentifier: guardrailConfig.guardrailIdentifier,
84
- guardrailVersion: guardrailConfig.guardrailVersion
85
- };
86
- if (guardrailConfig.streamProcessingMode) gc.streamProcessingMode = guardrailConfig.streamProcessingMode;
87
- if (guardrailConfig.trace) gc.trace = guardrailConfig.trace;
88
- payload.guardrailConfig = gc;
89
- });
90
- };
77
+ function createGuardrailStreamWrapper(streamFn, guardrailConfig) {
78
+ return createPayloadPatchStreamWrapper(streamFn, ({ payload }) => {
79
+ payload.guardrailConfig = {
80
+ guardrailIdentifier: guardrailConfig.guardrailIdentifier,
81
+ guardrailVersion: guardrailConfig.guardrailVersion,
82
+ ...guardrailConfig.streamProcessingMode ? { streamProcessingMode: guardrailConfig.streamProcessingMode } : {},
83
+ ...guardrailConfig.trace ? { trace: guardrailConfig.trace } : {}
84
+ };
85
+ });
91
86
  }
92
87
  /**
93
88
  * Detect Bedrock application inference profile ARNs — these are the only IDs
@@ -294,15 +289,12 @@ function registerAmazonBedrockPlugin(api) {
294
289
  const canonicalModelId = resolveClaudeModelIdentity(modelRef);
295
290
  const opus47OrNewer = isOpus47OrNewerBedrockModelRef(modelId) || isOpus47OrNewerBedrockModelRef(canonicalModelId);
296
291
  const supportsNativeMax = supportsBedrockNativeMaxEffort(modelId, model?.params);
297
- let wrapped = (currentGuardrail?.guardrailIdentifier && currentGuardrail?.guardrailVersion ? createGuardrailWrapStreamFn(baseWrapStreamFn, currentGuardrail)({
292
+ let wrapped = baseWrapStreamFn({
298
293
  modelId,
299
294
  model,
300
295
  streamFn
301
- }) : baseWrapStreamFn({
302
- modelId,
303
- model,
304
- streamFn
305
- })) ?? void 0;
296
+ });
297
+ if (wrapped && currentGuardrail?.guardrailIdentifier && currentGuardrail.guardrailVersion) wrapped = createGuardrailStreamWrapper(wrapped, currentGuardrail);
306
298
  const serviceTier = resolveBedrockServiceTier(extraParams, (message) => api.logger.warn(message));
307
299
  if (serviceTier && wrapped) {
308
300
  if ((fable5 || opus5 || sonnet5) && serviceTier !== "default") {
@@ -334,33 +326,15 @@ function registerAmazonBedrockPlugin(api) {
334
326
  } } : {}
335
327
  }));
336
328
  const cacheRetention = typeof merged.cacheRetention === "string" ? merged.cacheRetention : "short";
337
- if (heuristicMatch) {
338
- const mayNeedTemperatureTrait = "temperature" in merged;
339
- return underlying(streamModel, context, withAwsCredentialRefreshOnPayload({
340
- ...merged,
341
- onPayload: async (payload, payloadModel) => {
342
- if (payload && typeof payload === "object") {
343
- const payloadRecord = payload;
344
- injectBedrockCachePoints(payloadRecord, cacheRetention, context, streamModel);
345
- if (shouldPatchMaxThinking) patchMaxThinkingEffort(payloadRecord);
346
- if (shouldOmitTemperature) omitUnsupportedClaudePayloadTemperature(payloadRecord);
347
- else if (mayNeedTemperatureTrait) {
348
- if ((await resolveAppProfileTraits(modelId, region, merged.signal)).omitTemperature) omitUnsupportedClaudePayloadTemperature(payloadRecord);
349
- }
350
- }
351
- return originalOnPayload?.(payload, payloadModel);
352
- }
353
- }));
354
- }
355
329
  return underlying(streamModel, context, withAwsCredentialRefreshOnPayload({
356
330
  ...merged,
357
331
  onPayload: async (payload, payloadModel) => {
358
- const traits = await resolveAppProfileTraits(modelId, region, merged.signal);
332
+ const traits = heuristicMatch ? void 0 : await resolveAppProfileTraits(modelId, region, merged.signal);
359
333
  if (payload && typeof payload === "object") {
360
334
  const payloadRecord = payload;
361
- if (traits.cacheEligible) injectBedrockCachePoints(payloadRecord, cacheRetention, context, streamModel);
335
+ if (heuristicMatch || traits?.cacheEligible) injectBedrockCachePoints(payloadRecord, cacheRetention, context, streamModel);
362
336
  if (shouldPatchMaxThinking) patchMaxThinkingEffort(payloadRecord);
363
- if (traits.omitTemperature) omitUnsupportedClaudePayloadTemperature(payloadRecord);
337
+ if (heuristicMatch ? shouldOmitTemperature || "temperature" in merged && (await resolveAppProfileTraits(modelId, region, merged.signal)).omitTemperature : traits?.omitTemperature) omitUnsupportedClaudePayloadTemperature(payloadRecord);
364
338
  }
365
339
  return originalOnPayload?.(payload, payloadModel);
366
340
  }
package/dist/setup-api.js CHANGED
@@ -1,5 +1,5 @@
1
+ import { t as migrateAmazonBedrockLegacyConfig } from "./.setup/config-compat-C0KbKqqH.mjs";
1
2
  import { resolveBedrockConfigApiKey } from "./discovery-shared.js";
2
- import { migrateAmazonBedrockLegacyConfig } from "./config-compat.js";
3
3
  import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
4
4
  //#region extensions/amazon-bedrock/setup-api.ts
5
5
  /**
@@ -2,7 +2,7 @@ import { resolveBedrockCachePoint, resolveBedrockPromptCachePolicy } from "./bed
2
2
  import { resolveBedrockClaudeThinkingProfile, supportsBedrockNativeMaxEffort } from "./thinking-policy.js";
3
3
  import { bindsClaudeThinkingPrefix, 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 { describeToolResultMediaPlaceholder, failTransportStream, finalizeTerminalToolCallArguments, notifyProviderHttpMetadata, splitSystemPromptCacheBoundary, stripSystemPromptCacheBoundary } from "openclaw/plugin-sdk/provider-transport-runtime";
5
+ import { createEmptyTransportUsage, describeToolResultMediaPlaceholder, failTransportStream, finalizeTerminalToolCallArguments, notifyProviderHttpMetadata, splitSystemPromptCacheBoundary, stripSystemPromptCacheBoundary } from "openclaw/plugin-sdk/provider-transport-runtime";
6
6
  import { isRecord, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
7
7
  import { BedrockRuntimeClient, BedrockRuntimeServiceException, CacheTTL, ConversationRole, ConverseStreamCommand, ImageFormat, StopReason, ToolResultStatus } from "@aws-sdk/client-bedrock-runtime";
8
8
  import { NodeHttpHandler } from "@smithy/node-http-handler";
@@ -54,20 +54,7 @@ const streamBedrock = (model, context, options = {}) => {
54
54
  api: "bedrock-converse-stream",
55
55
  provider: model.provider,
56
56
  model: model.id,
57
- usage: {
58
- input: 0,
59
- output: 0,
60
- cacheRead: 0,
61
- cacheWrite: 0,
62
- totalTokens: 0,
63
- cost: {
64
- input: 0,
65
- output: 0,
66
- cacheRead: 0,
67
- cacheWrite: 0,
68
- total: 0
69
- }
70
- },
57
+ usage: createEmptyTransportUsage(),
71
58
  stopReason: "stop",
72
59
  timestamp: Date.now()
73
60
  };
@@ -534,17 +521,6 @@ function isAnthropicClaudeModel(model) {
534
521
  const name = model.name?.toLowerCase() ?? "";
535
522
  return id.includes("anthropic.claude") || id.includes("anthropic/claude") || name.includes("anthropic.claude") || name.includes("anthropic/claude") || name.includes("claude");
536
523
  }
537
- /**
538
- * Check if the model supports thinking signatures in reasoningContent.
539
- * Only Anthropic Claude models support the signature field.
540
- * Other models (OpenAI, Qwen, Minimax, Moonshot, etc.) reject it with:
541
- * "This model doesn't support the reasoningContent.reasoningText.signature field"
542
- *
543
- * Checks both model ID and model name to support application inference profiles.
544
- */
545
- function supportsThinkingSignature(model) {
546
- return isAnthropicClaudeModel(model);
547
- }
548
524
  function buildSystemPrompt(systemPrompt, cacheRetention, cachePoint) {
549
525
  if (!systemPrompt) return;
550
526
  if (cacheRetention === "none") return [{ text: sanitizeSurrogates(stripSystemPromptCacheBoundary(systemPrompt)) }];
@@ -618,14 +594,14 @@ function convertMessages(context, model, cachePoint) {
618
594
  break;
619
595
  case "thinking": {
620
596
  if (c.redacted) {
621
- if (!supportsThinkingSignature(model)) continue;
597
+ if (!isAnthropicClaudeModel(model)) continue;
622
598
  if (!c.thinkingSignature) throw new Error("Bedrock redacted reasoning block is missing its opaque signature");
623
599
  contentBlocks.push({ reasoningContent: { redactedContent: decodeBedrockBase64(c.thinkingSignature, "Bedrock redacted reasoning block has a malformed opaque signature") } });
624
600
  break;
625
601
  }
626
602
  const thinkingSignature = c.thinkingSignature;
627
603
  const normalizedThinkingSignature = thinkingSignature?.trim();
628
- const supportsSignature = supportsThinkingSignature(model);
604
+ const supportsSignature = isAnthropicClaudeModel(model);
629
605
  const hasNativeThinkingSignature = supportsSignature && Boolean(normalizedThinkingSignature) && normalizedThinkingSignature !== "reasoning_content";
630
606
  if (c.thinking.trim().length === 0 && !hasNativeThinkingSignature) continue;
631
607
  if (supportsSignature) {
@@ -771,30 +747,30 @@ function buildAdditionalModelRequestFields(model, options) {
771
747
  if (!reasoning || !model.reasoning && !usesClaudeFable5BedrockContract(model) && !supportsAdaptiveThinking(model)) return;
772
748
  if (isAnthropicClaudeModel(model)) {
773
749
  const display = isGovCloudBedrockTarget(model, options) ? void 0 : options.thinkingDisplay ?? "summarized";
774
- const result = supportsAdaptiveThinking(model) ? {
750
+ if (supportsAdaptiveThinking(model)) return {
775
751
  thinking: {
776
752
  type: "adaptive",
777
753
  ...display !== void 0 ? { display } : {}
778
754
  },
779
755
  output_config: { effort: mapThinkingLevelToEffort(model, reasoning) }
780
- } : (() => {
781
- const defaultBudgets = {
782
- minimal: 1024,
783
- low: 2048,
784
- medium: 8192,
785
- high: 16384,
786
- xhigh: 16384,
787
- max: 16384
788
- };
789
- const level = reasoning === "xhigh" ? "high" : reasoning;
790
- return { thinking: {
756
+ };
757
+ const defaultBudgets = {
758
+ minimal: 1024,
759
+ low: 2048,
760
+ medium: 8192,
761
+ high: 16384,
762
+ xhigh: 16384,
763
+ max: 16384
764
+ };
765
+ const level = reasoning === "xhigh" ? "high" : reasoning;
766
+ return {
767
+ thinking: {
791
768
  type: "enabled",
792
769
  budget_tokens: options.thinkingBudgets?.[level] ?? defaultBudgets[reasoning],
793
770
  ...display !== void 0 ? { display } : {}
794
- } };
795
- })();
796
- if (!supportsAdaptiveThinking(model) && (options.interleavedThinking ?? true)) result.anthropic_beta = ["interleaved-thinking-2025-05-14"];
797
- return result;
771
+ },
772
+ ...options.interleavedThinking ?? true ? { anthropic_beta: ["interleaved-thinking-2025-05-14"] } : {}
773
+ };
798
774
  }
799
775
  }
800
776
  function createImageBlock(mimeType, data) {
@@ -86,7 +86,7 @@ const commonParams = {
86
86
  UseDualStack: { type: "builtInParams", name: "useDualstackEndpoint" },
87
87
  };
88
88
 
89
- var version = "3.1130.0";
89
+ var version = "3.1135.0";
90
90
  var packageInfo = {
91
91
  version: version};
92
92
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aws-sdk/token-providers",
3
- "version": "3.1131.0",
3
+ "version": "3.1136.0",
4
4
  "description": "A collection of token providers",
5
5
  "keywords": [
6
6
  "aws",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aws-sdk/client-bedrock",
3
- "version": "3.1131.0",
3
+ "version": "3.1136.0",
4
4
  "description": "AWS SDK for JavaScript Bedrock Client for Node.js, Browser and React Native",
5
5
  "homepage": "https://github.com/aws/aws-sdk-js-v3/tree/main/clients/client-bedrock",
6
6
  "license": "Apache-2.0",
@@ -48,7 +48,7 @@
48
48
  "dependencies": {
49
49
  "@aws-sdk/core": "^3.978.0",
50
50
  "@aws-sdk/credential-provider-node": "^3.972.83",
51
- "@aws-sdk/token-providers": "3.1131.0",
51
+ "@aws-sdk/token-providers": "3.1136.0",
52
52
  "@aws-sdk/types": "^3.974.5",
53
53
  "@smithy/core": "^3.33.3",
54
54
  "@smithy/fetch-http-handler": "^5.7.2",
@@ -90,7 +90,7 @@ const commonParams = {
90
90
  UseDualStack: { type: "builtInParams", name: "useDualstackEndpoint" },
91
91
  };
92
92
 
93
- var version = "3.1130.0";
93
+ var version = "3.1135.0";
94
94
  var packageInfo = {
95
95
  version: version};
96
96
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aws-sdk/token-providers",
3
- "version": "3.1131.0",
3
+ "version": "3.1136.0",
4
4
  "description": "A collection of token providers",
5
5
  "keywords": [
6
6
  "aws",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aws-sdk/client-bedrock-runtime",
3
- "version": "3.1131.0",
3
+ "version": "3.1136.0",
4
4
  "description": "AWS SDK for JavaScript Bedrock Runtime Client for Node.js, Browser and React Native",
5
5
  "homepage": "https://github.com/aws/aws-sdk-js-v3/tree/main/clients/client-bedrock-runtime",
6
6
  "license": "Apache-2.0",
@@ -59,7 +59,7 @@
59
59
  "@aws-sdk/eventstream-handler-node": "^3.972.34",
60
60
  "@aws-sdk/middleware-eventstream": "^3.972.29",
61
61
  "@aws-sdk/middleware-websocket": "^3.972.53",
62
- "@aws-sdk/token-providers": "3.1131.0",
62
+ "@aws-sdk/token-providers": "3.1136.0",
63
63
  "@aws-sdk/types": "^3.974.5",
64
64
  "@smithy/core": "^3.33.3",
65
65
  "@smithy/fetch-http-handler": "^5.7.2",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/amazon-bedrock-provider",
3
- "version": "2026.9.6",
3
+ "version": "2026.9.7",
4
4
  "description": "OpenClaw Amazon Bedrock provider plugin with model discovery, embeddings, and guardrail support.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -8,8 +8,8 @@
8
8
  },
9
9
  "type": "module",
10
10
  "dependencies": {
11
- "@aws-sdk/client-bedrock": "3.1131.0",
12
- "@aws-sdk/client-bedrock-runtime": "3.1131.0",
11
+ "@aws-sdk/client-bedrock": "3.1136.0",
12
+ "@aws-sdk/client-bedrock-runtime": "3.1136.0",
13
13
  "@aws-sdk/credential-provider-node": "3.972.83",
14
14
  "@smithy/node-http-handler": "4.12.1",
15
15
  "@smithy/shared-ini-file-loader": "4.7.2",
@@ -26,10 +26,10 @@
26
26
  "minHostVersion": ">=2026.5.12-beta.1"
27
27
  },
28
28
  "compat": {
29
- "pluginApi": ">=2026.9.6"
29
+ "pluginApi": ">=2026.9.7"
30
30
  },
31
31
  "build": {
32
- "openclawVersion": "2026.9.6",
32
+ "openclawVersion": "2026.9.7",
33
33
  "bundledDist": false
34
34
  },
35
35
  "release": {
@@ -48,7 +48,7 @@
48
48
  "assets/activity.svg"
49
49
  ],
50
50
  "peerDependencies": {
51
- "openclaw": ">=2026.9.6"
51
+ "openclaw": ">=2026.9.7"
52
52
  },
53
53
  "peerDependenciesMeta": {
54
54
  "openclaw": {