@openclaw/amazon-bedrock-provider 2026.9.6 → 2026.9.8
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 +0 -0
- package/dist/.setup/config-compat-C0KbKqqH.mjs +258 -0
- package/dist/aws-credential-refresh.js +1 -13
- package/dist/config-compat.js +1 -80
- package/dist/discovery.js +2 -5
- package/dist/index.js +1 -3
- package/dist/provider-policy-api.js +1 -25
- package/dist/register.sync.runtime.js +15 -41
- package/dist/setup-api.js +1 -1
- package/dist/stream.runtime.js +20 -44
- package/node_modules/@aws-sdk/client-bedrock/dist-cjs/index.js +1 -1
- package/node_modules/@aws-sdk/client-bedrock/node_modules/@aws-sdk/token-providers/package.json +1 -1
- package/node_modules/@aws-sdk/client-bedrock/package.json +2 -2
- package/node_modules/@aws-sdk/client-bedrock-runtime/dist-cjs/index.js +1 -1
- package/node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/token-providers/package.json +1 -1
- package/node_modules/@aws-sdk/client-bedrock-runtime/package.json +2 -2
- package/package.json +6 -6
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 (
|
|
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
|
}
|
package/dist/config-compat.js
CHANGED
|
@@ -1,81 +1,2 @@
|
|
|
1
|
-
import {
|
|
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 =
|
|
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 =
|
|
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
|
|
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
|
-
|
|
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
|
|
78
|
-
return (
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
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 =
|
|
292
|
+
let wrapped = baseWrapStreamFn({
|
|
298
293
|
modelId,
|
|
299
294
|
model,
|
|
300
295
|
streamFn
|
|
301
|
-
})
|
|
302
|
-
|
|
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
|
|
335
|
+
if (heuristicMatch || traits?.cacheEligible) injectBedrockCachePoints(payloadRecord, cacheRetention, context, streamModel);
|
|
362
336
|
if (shouldPatchMaxThinking) patchMaxThinkingEffort(payloadRecord);
|
|
363
|
-
if (
|
|
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
|
/**
|
package/dist/stream.runtime.js
CHANGED
|
@@ -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 (!
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
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
|
-
|
|
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) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aws-sdk/client-bedrock",
|
|
3
|
-
"version": "3.
|
|
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.
|
|
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",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aws-sdk/client-bedrock-runtime",
|
|
3
|
-
"version": "3.
|
|
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.
|
|
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.
|
|
3
|
+
"version": "2026.9.8",
|
|
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.
|
|
12
|
-
"@aws-sdk/client-bedrock-runtime": "3.
|
|
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.
|
|
29
|
+
"pluginApi": ">=2026.9.8"
|
|
30
30
|
},
|
|
31
31
|
"build": {
|
|
32
|
-
"openclawVersion": "2026.9.
|
|
32
|
+
"openclawVersion": "2026.9.8",
|
|
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.
|
|
51
|
+
"openclaw": ">=2026.9.8"
|
|
52
52
|
},
|
|
53
53
|
"peerDependenciesMeta": {
|
|
54
54
|
"openclaw": {
|