@warlock.js/ai-bedrock 4.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cjs/index.cjs +808 -0
- package/cjs/index.cjs.map +1 -0
- package/esm/config.type.d.mts +90 -0
- package/esm/config.type.d.mts.map +1 -0
- package/esm/embedder.mjs +117 -0
- package/esm/embedder.mjs.map +1 -0
- package/esm/index.d.mts +3 -0
- package/esm/index.mjs +3 -0
- package/esm/known-vision-models.mjs +50 -0
- package/esm/known-vision-models.mjs.map +1 -0
- package/esm/model.mjs +290 -0
- package/esm/model.mjs.map +1 -0
- package/esm/sdk.d.mts +66 -0
- package/esm/sdk.d.mts.map +1 -0
- package/esm/sdk.mjs +82 -0
- package/esm/sdk.mjs.map +1 -0
- package/esm/utils/index.mjs +6 -0
- package/esm/utils/map-stop-reason.mjs +31 -0
- package/esm/utils/map-stop-reason.mjs.map +1 -0
- package/esm/utils/to-bedrock-messages.mjs +111 -0
- package/esm/utils/to-bedrock-messages.mjs.map +1 -0
- package/esm/utils/to-bedrock-tools.mjs +41 -0
- package/esm/utils/to-bedrock-tools.mjs.map +1 -0
- package/esm/utils/wrap-bedrock-error.mjs +121 -0
- package/esm/utils/wrap-bedrock-error.mjs.map +1 -0
- package/llms-full.txt +153 -0
- package/llms.txt +9 -0
- package/package.json +39 -0
- package/skills/README.md +9 -0
- package/skills/setup-bedrock/SKILL.md +143 -0
package/cjs/index.cjs
ADDED
|
@@ -0,0 +1,808 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
let _aws_sdk_client_bedrock_runtime = require("@aws-sdk/client-bedrock-runtime");
|
|
3
|
+
let _warlock_js_ai = require("@warlock.js/ai");
|
|
4
|
+
let _warlock_js_logger = require("@warlock.js/logger");
|
|
5
|
+
|
|
6
|
+
//#region ../../@warlock.js/ai-bedrock/src/utils/map-stop-reason.ts
|
|
7
|
+
const stopReasonMap = {
|
|
8
|
+
end_turn: "stop",
|
|
9
|
+
stop_sequence: "stop",
|
|
10
|
+
max_tokens: "length",
|
|
11
|
+
tool_use: "tool_calls"
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Map Bedrock Converse's `stopReason` to the normalized `FinishReason`
|
|
15
|
+
* union.
|
|
16
|
+
*
|
|
17
|
+
* `end_turn` / `stop_sequence` are natural stops. `max_tokens` maps to
|
|
18
|
+
* `length`. `tool_use` maps to `tool_calls`. Everything else —
|
|
19
|
+
* `content_filtered`, `guardrail_intervened`, `malformed_tool_use`,
|
|
20
|
+
* `malformed_model_output`, `model_context_window_exceeded`, `null`,
|
|
21
|
+
* or any future value — falls through to `"error"`: none produced a
|
|
22
|
+
* clean terminal answer, so the agent must not treat them as success.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* mapStopReason("end_turn"); // "stop"
|
|
26
|
+
* mapStopReason("tool_use"); // "tool_calls"
|
|
27
|
+
* mapStopReason("guardrail_intervened"); // "error"
|
|
28
|
+
* mapStopReason(undefined); // "error"
|
|
29
|
+
*/
|
|
30
|
+
function mapStopReason(raw) {
|
|
31
|
+
return stopReasonMap[raw ?? ""] ?? "error";
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
//#endregion
|
|
35
|
+
//#region ../../@warlock.js/ai-bedrock/src/utils/to-bedrock-messages.ts
|
|
36
|
+
const MEDIA_TYPE_TO_FORMAT = {
|
|
37
|
+
"image/jpeg": "jpeg",
|
|
38
|
+
"image/png": "png",
|
|
39
|
+
"image/gif": "gif",
|
|
40
|
+
"image/webp": "webp"
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Convert vendor-neutral `Message[]` into Bedrock Converse's request
|
|
44
|
+
* shape.
|
|
45
|
+
*
|
|
46
|
+
* Converse differs from the OpenAI Chat protocol in three ways this
|
|
47
|
+
* function absorbs:
|
|
48
|
+
*
|
|
49
|
+
* 1. **No `system` role.** System messages become a separate
|
|
50
|
+
* `SystemContentBlock[]` (one `{ text }` block each).
|
|
51
|
+
* 2. **Tool results are `user` turns.** A neutral `tool` message
|
|
52
|
+
* becomes a `user` message carrying a single `toolResult` block.
|
|
53
|
+
* 3. **Tool calls are `toolUse` content blocks.** An assistant message
|
|
54
|
+
* with `toolCalls` becomes an `assistant` message: an optional
|
|
55
|
+
* leading `text` block followed by one `toolUse` block per call.
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* const { system, messages } = toBedrockMessages([
|
|
59
|
+
* { role: "system", content: "Be concise." },
|
|
60
|
+
* { role: "user", content: "Hi" },
|
|
61
|
+
* ]);
|
|
62
|
+
*/
|
|
63
|
+
function toBedrockMessages(messages) {
|
|
64
|
+
const system = [];
|
|
65
|
+
const mapped = [];
|
|
66
|
+
for (const message of messages) {
|
|
67
|
+
if (message.role === "system") {
|
|
68
|
+
system.push({ text: stringifyContent(message.content) });
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
if (message.role === "tool") {
|
|
72
|
+
mapped.push({
|
|
73
|
+
role: "user",
|
|
74
|
+
content: [{ toolResult: {
|
|
75
|
+
toolUseId: message.toolCallId ?? "",
|
|
76
|
+
content: [{ text: stringifyContent(message.content) }]
|
|
77
|
+
} }]
|
|
78
|
+
});
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
if (message.role === "assistant" && message.toolCalls && message.toolCalls.length > 0) {
|
|
82
|
+
const blocks = [];
|
|
83
|
+
const text = stringifyContent(message.content);
|
|
84
|
+
if (text) blocks.push({ text });
|
|
85
|
+
for (const toolCall of message.toolCalls) blocks.push({ toolUse: {
|
|
86
|
+
toolUseId: toolCall.id,
|
|
87
|
+
name: toolCall.name,
|
|
88
|
+
input: toolCall.input ?? {}
|
|
89
|
+
} });
|
|
90
|
+
mapped.push({
|
|
91
|
+
role: "assistant",
|
|
92
|
+
content: blocks
|
|
93
|
+
});
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
if (message.role === "user" && Array.isArray(message.content)) {
|
|
97
|
+
mapped.push({
|
|
98
|
+
role: "user",
|
|
99
|
+
content: message.content.map(toBedrockContentBlock)
|
|
100
|
+
});
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
mapped.push({
|
|
104
|
+
role: message.role === "assistant" ? "assistant" : "user",
|
|
105
|
+
content: [{ text: stringifyContent(message.content) }]
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
return {
|
|
109
|
+
system: system.length > 0 ? system : void 0,
|
|
110
|
+
messages: mapped
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Multipart content is only meaningful on user messages — for any other
|
|
115
|
+
* role collapse a `ContentPart[]` to its concatenated text. Plain
|
|
116
|
+
* strings pass through unchanged.
|
|
117
|
+
*/
|
|
118
|
+
function stringifyContent(content) {
|
|
119
|
+
if (typeof content === "string") return content;
|
|
120
|
+
return content.filter((part) => part.type === "text").map((part) => part.text).join("");
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Map a resolved `ContentPart` to a Bedrock `ContentBlock`. Bedrock's
|
|
124
|
+
* `ImageSource` only accepts raw bytes or an S3 location — there is no
|
|
125
|
+
* remote-URL source. A neutral `{ url }` image therefore cannot be
|
|
126
|
+
* sent and surfaces a typed `InvalidRequestError` upfront rather than
|
|
127
|
+
* a downstream Bedrock validation fault. The agent has already
|
|
128
|
+
* resolved attachments, so this never fetches or reads anything.
|
|
129
|
+
*/
|
|
130
|
+
function toBedrockContentBlock(part) {
|
|
131
|
+
if (part.type === "text") return { text: part.text };
|
|
132
|
+
if ("url" in part.source) throw new _warlock_js_ai.InvalidRequestError("Bedrock Converse does not support remote-URL image sources; supply base64 image bytes instead.");
|
|
133
|
+
const format = MEDIA_TYPE_TO_FORMAT[part.source.mediaType];
|
|
134
|
+
if (!format) throw new _warlock_js_ai.InvalidRequestError(`Unsupported image media type for Bedrock: "${part.source.mediaType}" (expected image/jpeg, image/png, image/gif, or image/webp).`);
|
|
135
|
+
return { image: {
|
|
136
|
+
format,
|
|
137
|
+
source: { bytes: Buffer.from(part.source.base64, "base64") }
|
|
138
|
+
} };
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
//#endregion
|
|
142
|
+
//#region ../../@warlock.js/ai-bedrock/src/utils/to-bedrock-tools.ts
|
|
143
|
+
/**
|
|
144
|
+
* Convert vendor-neutral `ToolConfig[]` into Bedrock Converse's
|
|
145
|
+
* `ToolConfiguration`. Each tool becomes a `toolSpec` with a JSON
|
|
146
|
+
* `inputSchema`. Bedrock requires the schema root to be an object —
|
|
147
|
+
* a non-object extraction degrades to a parameterless object schema
|
|
148
|
+
* so registration never fails.
|
|
149
|
+
*
|
|
150
|
+
* Returns `undefined` when there are no tools so the caller can omit
|
|
151
|
+
* `toolConfig` from the request entirely (Bedrock rejects an empty
|
|
152
|
+
* `tools` array).
|
|
153
|
+
*
|
|
154
|
+
* @example
|
|
155
|
+
* const toolConfig = toBedrockToolConfig([weatherTool]);
|
|
156
|
+
* await client.send(new ConverseCommand({ modelId, messages, toolConfig }));
|
|
157
|
+
*/
|
|
158
|
+
function toBedrockToolConfig(tools) {
|
|
159
|
+
if (!tools || tools.length === 0) return;
|
|
160
|
+
return { tools: tools.map((tool) => ({ toolSpec: {
|
|
161
|
+
name: tool.name,
|
|
162
|
+
description: tool.description,
|
|
163
|
+
inputSchema: { json: toJsonSchema(tool.input) }
|
|
164
|
+
} })) };
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Resolve a tool's input schema to a JSON-Schema object. Bedrock's
|
|
168
|
+
* `ToolInputSchema.json` requires an object root; anything else (or a
|
|
169
|
+
* failed extraction) degrades to a parameterless object so the tool
|
|
170
|
+
* still registers.
|
|
171
|
+
*/
|
|
172
|
+
function toJsonSchema(input) {
|
|
173
|
+
const schema = (0, _warlock_js_ai.extractJsonSchema)(input);
|
|
174
|
+
if (schema && schema.type === "object") return schema;
|
|
175
|
+
return { type: "object" };
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
//#endregion
|
|
179
|
+
//#region ../../@warlock.js/ai-bedrock/src/utils/wrap-bedrock-error.ts
|
|
180
|
+
const TIMEOUT_NAMES = new Set([
|
|
181
|
+
"ModelTimeoutException",
|
|
182
|
+
"TimeoutError",
|
|
183
|
+
"RequestTimeout",
|
|
184
|
+
"RequestTimeoutException"
|
|
185
|
+
]);
|
|
186
|
+
/**
|
|
187
|
+
* Wrap any thrown value caught inside the Bedrock adapter into the
|
|
188
|
+
* appropriate `@warlock.js/ai` `AIError` subclass.
|
|
189
|
+
*
|
|
190
|
+
* **Dispatch strategy.** AWS errors carry no provider machine `code`;
|
|
191
|
+
* the stable identifier is the Smithy exception `name`. Dispatch keys
|
|
192
|
+
* on `name`, falls back to `$metadata.httpStatusCode` when the name is
|
|
193
|
+
* missing (flattened/proxied errors). `ValidationException` is split:
|
|
194
|
+
* the "input is too long / exceeds context window" phrasing maps to
|
|
195
|
+
* `ContextLengthExceededError`, everything else to
|
|
196
|
+
* `InvalidRequestError`.
|
|
197
|
+
*
|
|
198
|
+
* `AIError` instances pass through unchanged so `catch/throw wrap(e)`
|
|
199
|
+
* pipelines never double-wrap.
|
|
200
|
+
*
|
|
201
|
+
* @example
|
|
202
|
+
* try {
|
|
203
|
+
* return await this.client.send(new ConverseCommand(...));
|
|
204
|
+
* } catch (thrown) {
|
|
205
|
+
* throw wrapBedrockError(thrown);
|
|
206
|
+
* }
|
|
207
|
+
*/
|
|
208
|
+
function wrapBedrockError(thrown) {
|
|
209
|
+
if (thrown instanceof _warlock_js_ai.AIError) return thrown;
|
|
210
|
+
const shape = toShape(thrown);
|
|
211
|
+
const context = buildContext(shape);
|
|
212
|
+
const message = shape.message ?? (thrown instanceof Error ? thrown.message : String(thrown));
|
|
213
|
+
if (isTimeout(shape)) return new _warlock_js_ai.ProviderTimeoutError(message, {
|
|
214
|
+
cause: thrown,
|
|
215
|
+
context
|
|
216
|
+
});
|
|
217
|
+
if (shape.name === "AccessDeniedException" || shape.httpStatusCode === 403) return new _warlock_js_ai.ProviderAuthError(message, {
|
|
218
|
+
cause: thrown,
|
|
219
|
+
context
|
|
220
|
+
});
|
|
221
|
+
if (shape.httpStatusCode === 401) return new _warlock_js_ai.ProviderAuthError(message, {
|
|
222
|
+
cause: thrown,
|
|
223
|
+
context
|
|
224
|
+
});
|
|
225
|
+
if (shape.name === "ServiceQuotaExceededException") return new _warlock_js_ai.QuotaExceededError(message, {
|
|
226
|
+
cause: thrown,
|
|
227
|
+
context
|
|
228
|
+
});
|
|
229
|
+
if (shape.name === "ThrottlingException" || shape.httpStatusCode === 429) return new _warlock_js_ai.ProviderRateLimitError(message, {
|
|
230
|
+
cause: thrown,
|
|
231
|
+
context
|
|
232
|
+
});
|
|
233
|
+
if (shape.name === "ValidationException") {
|
|
234
|
+
if (/too long|context window|maximum context|exceeds the maximum/i.test(message)) return new _warlock_js_ai.ContextLengthExceededError(message, {
|
|
235
|
+
cause: thrown,
|
|
236
|
+
context
|
|
237
|
+
});
|
|
238
|
+
return new _warlock_js_ai.InvalidRequestError(message, {
|
|
239
|
+
cause: thrown,
|
|
240
|
+
context
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
if (shape.name === "ResourceNotFoundException" || shape.name === "ConflictException" || isClientStatus(shape.httpStatusCode)) return new _warlock_js_ai.InvalidRequestError(message, {
|
|
244
|
+
cause: thrown,
|
|
245
|
+
context
|
|
246
|
+
});
|
|
247
|
+
return new _warlock_js_ai.ProviderError(message, {
|
|
248
|
+
cause: thrown,
|
|
249
|
+
context
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Read the raw error shape without depending on `instanceof`. AWS
|
|
254
|
+
* exceptions expose `$metadata`; plain/proxied errors may carry
|
|
255
|
+
* `status` / `code` instead.
|
|
256
|
+
*/
|
|
257
|
+
function toShape(thrown) {
|
|
258
|
+
if (typeof thrown !== "object" || thrown === null) return {};
|
|
259
|
+
const raw = thrown;
|
|
260
|
+
const metadata = raw.$metadata;
|
|
261
|
+
return {
|
|
262
|
+
name: typeof raw.name === "string" ? raw.name : void 0,
|
|
263
|
+
message: typeof raw.message === "string" ? raw.message : void 0,
|
|
264
|
+
httpStatusCode: metadata && typeof metadata.httpStatusCode === "number" ? metadata.httpStatusCode : typeof raw.status === "number" ? raw.status : void 0,
|
|
265
|
+
requestId: metadata && typeof metadata.requestId === "string" ? metadata.requestId : void 0,
|
|
266
|
+
code: typeof raw.code === "string" ? raw.code : void 0
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Decide whether the error is a timeout. Bedrock surfaces
|
|
271
|
+
* `ModelTimeoutException`; the AWS transport layer surfaces
|
|
272
|
+
* `TimeoutError` / `ETIMEDOUT` / `ECONNABORTED`.
|
|
273
|
+
*/
|
|
274
|
+
function isTimeout(shape) {
|
|
275
|
+
if (shape.name && TIMEOUT_NAMES.has(shape.name)) return true;
|
|
276
|
+
return shape.code === "ETIMEDOUT" || shape.code === "ECONNABORTED";
|
|
277
|
+
}
|
|
278
|
+
/** True for HTTP 4xx — a client-side request problem, not a server fault. */
|
|
279
|
+
function isClientStatus(status) {
|
|
280
|
+
return typeof status === "number" && status >= 400 && status < 500;
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Attach the raw diagnostic fields to `error.context`. The Smithy
|
|
284
|
+
* exception `name` is the closest thing Bedrock has to a stable error
|
|
285
|
+
* code, so it lands on `context.code`.
|
|
286
|
+
*/
|
|
287
|
+
function buildContext(shape) {
|
|
288
|
+
const context = {};
|
|
289
|
+
if (shape.httpStatusCode !== void 0) context.status = shape.httpStatusCode;
|
|
290
|
+
if (shape.name) context.code = shape.name;
|
|
291
|
+
if (shape.requestId) context.requestId = shape.requestId;
|
|
292
|
+
return context;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
//#endregion
|
|
296
|
+
//#region ../../@warlock.js/ai-bedrock/src/embedder.ts
|
|
297
|
+
const LOG_MODULE$1 = "ai.bedrock";
|
|
298
|
+
/**
|
|
299
|
+
* Bedrock-backed implementation of `EmbedderContract`, targeting the
|
|
300
|
+
* Amazon Titan Text Embeddings family
|
|
301
|
+
* (`amazon.titan-embed-text-v2:0` / v1) via `InvokeModel`.
|
|
302
|
+
*
|
|
303
|
+
* **Role.** Converts text into floating-point vectors. Standalone
|
|
304
|
+
* primitive — unrelated to Converse / tools / the agent loop.
|
|
305
|
+
*
|
|
306
|
+
* **Single-input only upstream.** Titan's `InvokeModel` body accepts
|
|
307
|
+
* one `inputText` per call — there is no batch endpoint. `embedMany`
|
|
308
|
+
* therefore issues one request per input sequentially and aggregates
|
|
309
|
+
* token usage. This is a deliberate, documented trade-off: a real
|
|
310
|
+
* batch API does not exist for Titan on Bedrock, so the alternative
|
|
311
|
+
* (failing `embedMany`) would be worse. Cohere embeddings on Bedrock
|
|
312
|
+
* *do* batch but use an incompatible body shape — out of scope; use
|
|
313
|
+
* the OpenAI adapter or a future Cohere adapter when batch throughput
|
|
314
|
+
* matters.
|
|
315
|
+
*
|
|
316
|
+
* **Dimensions.** When no `dimensions` override is given,
|
|
317
|
+
* `this.dimensions` starts at `0` and is populated from the first
|
|
318
|
+
* response's vector length, then cached. Passing `dimensions` forwards
|
|
319
|
+
* Titan v2's truncation hint (256 / 512 / 1024) and sets the initial
|
|
320
|
+
* value immediately.
|
|
321
|
+
*
|
|
322
|
+
* @example
|
|
323
|
+
* const embedder = new BedrockEmbedder(client, { name: "amazon.titan-embed-text-v2:0" });
|
|
324
|
+
* const { vector } = await embedder.embed("Hello world");
|
|
325
|
+
* const { vectors } = await embedder.embedMany(["doc 1", "doc 2"]);
|
|
326
|
+
*/
|
|
327
|
+
var BedrockEmbedder = class {
|
|
328
|
+
constructor(client, config, provider = "bedrock") {
|
|
329
|
+
this.logger = _warlock_js_logger.log;
|
|
330
|
+
this.client = client;
|
|
331
|
+
this.name = config.name;
|
|
332
|
+
this.provider = provider;
|
|
333
|
+
this.configuredDimensions = config.dimensions;
|
|
334
|
+
this.dimensions = config.dimensions ?? 0;
|
|
335
|
+
}
|
|
336
|
+
async embed(input) {
|
|
337
|
+
const { vector, tokens } = await this.invoke(input);
|
|
338
|
+
return {
|
|
339
|
+
vector,
|
|
340
|
+
dimensions: this.dimensions,
|
|
341
|
+
usage: {
|
|
342
|
+
promptTokens: tokens,
|
|
343
|
+
totalTokens: tokens
|
|
344
|
+
}
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
async embedMany(inputs) {
|
|
348
|
+
const vectors = [];
|
|
349
|
+
let tokens = 0;
|
|
350
|
+
for (const input of inputs) {
|
|
351
|
+
const result = await this.invoke(input);
|
|
352
|
+
vectors.push(result.vector);
|
|
353
|
+
tokens += result.tokens;
|
|
354
|
+
}
|
|
355
|
+
const usage = {
|
|
356
|
+
promptTokens: tokens,
|
|
357
|
+
totalTokens: tokens
|
|
358
|
+
};
|
|
359
|
+
return {
|
|
360
|
+
vectors,
|
|
361
|
+
dimensions: this.dimensions,
|
|
362
|
+
usage
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Issue a single Titan `InvokeModel` embedding request: encode the
|
|
367
|
+
* JSON body, send, wrap provider errors, decode the response, and
|
|
368
|
+
* cache `dimensions` on the first successful call.
|
|
369
|
+
*/
|
|
370
|
+
async invoke(input) {
|
|
371
|
+
this.logger.debug(LOG_MODULE$1, "embedder.request", "InvokeModel embeddings", { model: this.name });
|
|
372
|
+
const body = JSON.stringify({
|
|
373
|
+
inputText: input,
|
|
374
|
+
...this.configuredDimensions !== void 0 ? { dimensions: this.configuredDimensions } : {}
|
|
375
|
+
});
|
|
376
|
+
let raw;
|
|
377
|
+
try {
|
|
378
|
+
raw = await this.client.send(new _aws_sdk_client_bedrock_runtime.InvokeModelCommand({
|
|
379
|
+
modelId: this.name,
|
|
380
|
+
contentType: "application/json",
|
|
381
|
+
accept: "application/json",
|
|
382
|
+
body: new TextEncoder().encode(body)
|
|
383
|
+
}));
|
|
384
|
+
} catch (thrown) {
|
|
385
|
+
const wrapped = wrapBedrockError(thrown);
|
|
386
|
+
this.logger.error(LOG_MODULE$1, "embedder.error", wrapped.message, {
|
|
387
|
+
code: wrapped.code,
|
|
388
|
+
context: wrapped.context
|
|
389
|
+
});
|
|
390
|
+
throw wrapped;
|
|
391
|
+
}
|
|
392
|
+
const decoded = JSON.parse(new TextDecoder().decode(raw.body));
|
|
393
|
+
if (this.dimensions === 0) this.dimensions = decoded.embedding.length;
|
|
394
|
+
this.logger.debug(LOG_MODULE$1, "embedder.response", "InvokeModel embeddings returned", {
|
|
395
|
+
dimensions: decoded.embedding.length,
|
|
396
|
+
tokens: decoded.inputTextTokenCount
|
|
397
|
+
});
|
|
398
|
+
return {
|
|
399
|
+
vector: decoded.embedding,
|
|
400
|
+
tokens: decoded.inputTextTokenCount
|
|
401
|
+
};
|
|
402
|
+
}
|
|
403
|
+
};
|
|
404
|
+
|
|
405
|
+
//#endregion
|
|
406
|
+
//#region ../../@warlock.js/ai-bedrock/src/known-vision-models.ts
|
|
407
|
+
/**
|
|
408
|
+
* Substrings that identify Bedrock model ids whose family accepts image
|
|
409
|
+
* input on the Converse API.
|
|
410
|
+
*
|
|
411
|
+
* Bedrock model ids are provider-prefixed and version-suffixed
|
|
412
|
+
* (`anthropic.claude-3-5-sonnet-20240620-v1:0`, `us.amazon.nova-pro-v1:0`,
|
|
413
|
+
* `meta.llama3-2-90b-instruct-v1:0`), so a substring match is the only
|
|
414
|
+
* robust check across the cross-region inference-profile prefixes
|
|
415
|
+
* (`us.`, `eu.`, `apac.`) and date/version tags.
|
|
416
|
+
*
|
|
417
|
+
* Multimodal families covered: Anthropic Claude 3 / 3.5 / 3.7 / 4,
|
|
418
|
+
* Amazon Nova Lite/Pro/Premier, Meta Llama 3.2 (11B/90B) and Llama 4.
|
|
419
|
+
* Text-only families (Llama 3/3.1, Titan Text, Mistral 7B, Cohere
|
|
420
|
+
* Command) are intentionally absent. Override per-model via
|
|
421
|
+
* `bedrock.model({ name, vision: true | false })`.
|
|
422
|
+
*/
|
|
423
|
+
const VISION_CAPABLE_SUBSTRINGS = [
|
|
424
|
+
"claude-3",
|
|
425
|
+
"claude-sonnet-4",
|
|
426
|
+
"claude-opus-4",
|
|
427
|
+
"claude-haiku-4",
|
|
428
|
+
"nova-lite",
|
|
429
|
+
"nova-pro",
|
|
430
|
+
"nova-premier",
|
|
431
|
+
"llama3-2-11b",
|
|
432
|
+
"llama3-2-90b",
|
|
433
|
+
"llama4"
|
|
434
|
+
];
|
|
435
|
+
/**
|
|
436
|
+
* Infer whether a Bedrock model id supports vision based on the known
|
|
437
|
+
* multimodal-family substrings. Unknown ids default to `false` so that
|
|
438
|
+
* passing an image attachment to an unsupported model surfaces a clear,
|
|
439
|
+
* agent-side capability error instead of an opaque Bedrock validation
|
|
440
|
+
* fault.
|
|
441
|
+
*
|
|
442
|
+
* @example
|
|
443
|
+
* inferVisionCapability("anthropic.claude-3-5-sonnet-20240620-v1:0"); // → true
|
|
444
|
+
* inferVisionCapability("us.amazon.nova-pro-v1:0"); // → true
|
|
445
|
+
* inferVisionCapability("meta.llama3-1-8b-instruct-v1:0"); // → false
|
|
446
|
+
* inferVisionCapability("amazon.titan-text-express-v1"); // → false
|
|
447
|
+
*/
|
|
448
|
+
function inferVisionCapability(modelId) {
|
|
449
|
+
const normalized = modelId.toLowerCase();
|
|
450
|
+
return VISION_CAPABLE_SUBSTRINGS.some((fragment) => normalized.includes(fragment));
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
//#endregion
|
|
454
|
+
//#region ../../@warlock.js/ai-bedrock/src/model.ts
|
|
455
|
+
const LOG_MODULE = "ai.bedrock";
|
|
456
|
+
/**
|
|
457
|
+
* Bedrock-backed implementation of `ModelContract`.
|
|
458
|
+
*
|
|
459
|
+
* **Role.** The provider-facing bridge between the vendor-neutral
|
|
460
|
+
* `@warlock.js/ai` agent runtime and AWS Bedrock's Converse /
|
|
461
|
+
* ConverseStream API. Converse is the model-agnostic surface — one
|
|
462
|
+
* wire mapping covers every Bedrock-hosted family (Anthropic Claude,
|
|
463
|
+
* Amazon Nova, Meta Llama, Mistral, Cohere) instead of per-family
|
|
464
|
+
* `InvokeModel` body shapes.
|
|
465
|
+
*
|
|
466
|
+
* **Responsibility.**
|
|
467
|
+
* - Owns: a long-lived `BedrockRuntimeClient` + frozen `ModelConfig`
|
|
468
|
+
* (modelId, temperature, maxTokens) used as per-call defaults.
|
|
469
|
+
* - Owns: translating vendor-neutral `Message[]` / `ToolConfig[]` into
|
|
470
|
+
* Converse shapes (system hoisting, `toolUse` / `toolResult` blocks,
|
|
471
|
+
* image bytes) on the way out, and Converse's content-block response
|
|
472
|
+
* (text, tool calls, stop reason, token usage) back into the neutral
|
|
473
|
+
* shapes on the way in.
|
|
474
|
+
* - Does NOT own: dispatching tools, looping, history, retries — those
|
|
475
|
+
* are agent concerns. The model is a per-call protocol adapter.
|
|
476
|
+
*
|
|
477
|
+
* Modeled as a class (see §4.2 of code-style.md — "long-lived state
|
|
478
|
+
* across calls"): the AWS client is heavy to construct and reused for
|
|
479
|
+
* the SDK's lifetime.
|
|
480
|
+
*
|
|
481
|
+
* @example
|
|
482
|
+
* import { BedrockRuntimeClient } from "@aws-sdk/client-bedrock-runtime";
|
|
483
|
+
* const client = new BedrockRuntimeClient({ region: "us-east-1" });
|
|
484
|
+
* const model = new BedrockModel(client, {
|
|
485
|
+
* name: "anthropic.claude-sonnet-4-5-20250929-v1:0",
|
|
486
|
+
* });
|
|
487
|
+
*
|
|
488
|
+
* const myAgent = agent({ model, tools: [searchTool] });
|
|
489
|
+
* const result = await myAgent.execute("Summarize today's news.");
|
|
490
|
+
*/
|
|
491
|
+
var BedrockModel = class {
|
|
492
|
+
constructor(client, config, provider = "bedrock") {
|
|
493
|
+
this.logger = _warlock_js_logger.log;
|
|
494
|
+
this.client = client;
|
|
495
|
+
this.config = config;
|
|
496
|
+
this.name = config.name;
|
|
497
|
+
this.provider = provider;
|
|
498
|
+
this.pricing = config.pricing;
|
|
499
|
+
this.capabilities = {
|
|
500
|
+
structuredOutput: config.structuredOutput ?? true,
|
|
501
|
+
vision: config.vision ?? inferVisionCapability(config.name)
|
|
502
|
+
};
|
|
503
|
+
}
|
|
504
|
+
/**
|
|
505
|
+
* Single-shot completion via the Converse API. Sends the full
|
|
506
|
+
* message list, waits for the terminal response, and reshapes it
|
|
507
|
+
* into a vendor-neutral `ModelResponse`. Per-call `options` override
|
|
508
|
+
* the instance defaults for this call only.
|
|
509
|
+
*/
|
|
510
|
+
async complete(messages, options) {
|
|
511
|
+
this.logger.debug(LOG_MODULE, "request", "Starting Converse call", {
|
|
512
|
+
model: this.name,
|
|
513
|
+
messageCount: messages.length,
|
|
514
|
+
streaming: false,
|
|
515
|
+
toolCount: options?.tools?.length ?? 0
|
|
516
|
+
});
|
|
517
|
+
let response;
|
|
518
|
+
try {
|
|
519
|
+
response = await this.client.send(new _aws_sdk_client_bedrock_runtime.ConverseCommand(this.buildRequest(messages, options)), options?.signal ? { abortSignal: options.signal } : void 0);
|
|
520
|
+
} catch (thrown) {
|
|
521
|
+
throw this.logAndWrap(thrown);
|
|
522
|
+
}
|
|
523
|
+
const blocks = response.output?.message?.content ?? [];
|
|
524
|
+
const finishReason = mapStopReason(response.stopReason);
|
|
525
|
+
const usage = this.extractUsage(response.usage);
|
|
526
|
+
const toolCalls = this.extractToolCalls(blocks);
|
|
527
|
+
this.logger.debug(LOG_MODULE, "response", "Converse call succeeded", {
|
|
528
|
+
finishReason,
|
|
529
|
+
usage
|
|
530
|
+
});
|
|
531
|
+
return {
|
|
532
|
+
content: this.extractText(blocks),
|
|
533
|
+
finishReason,
|
|
534
|
+
usage,
|
|
535
|
+
toolCalls
|
|
536
|
+
};
|
|
537
|
+
}
|
|
538
|
+
/**
|
|
539
|
+
* Incremental streaming completion via ConverseStream. Yields neutral
|
|
540
|
+
* `ModelStreamChunk`s — `delta` for text, `tool-call` once a
|
|
541
|
+
* `toolUse` block's accumulated input JSON is complete, and a
|
|
542
|
+
* terminal `done` with the final finish reason + usage totals.
|
|
543
|
+
*/
|
|
544
|
+
async *stream(messages, options) {
|
|
545
|
+
this.logger.debug(LOG_MODULE, "request", "Starting ConverseStream call", {
|
|
546
|
+
model: this.name,
|
|
547
|
+
messageCount: messages.length,
|
|
548
|
+
streaming: true,
|
|
549
|
+
toolCount: options?.tools?.length ?? 0
|
|
550
|
+
});
|
|
551
|
+
let response;
|
|
552
|
+
try {
|
|
553
|
+
response = await this.client.send(new _aws_sdk_client_bedrock_runtime.ConverseStreamCommand(this.buildRequest(messages, options)), options?.signal ? { abortSignal: options.signal } : void 0);
|
|
554
|
+
} catch (thrown) {
|
|
555
|
+
throw this.logAndWrap(thrown);
|
|
556
|
+
}
|
|
557
|
+
let rawStopReason;
|
|
558
|
+
const usage = {
|
|
559
|
+
input: 0,
|
|
560
|
+
output: 0,
|
|
561
|
+
total: 0
|
|
562
|
+
};
|
|
563
|
+
const toolBlocks = /* @__PURE__ */ new Map();
|
|
564
|
+
try {
|
|
565
|
+
for await (const event of response.stream ?? []) {
|
|
566
|
+
if (event.contentBlockStart?.start?.toolUse) {
|
|
567
|
+
const start = event.contentBlockStart.start.toolUse;
|
|
568
|
+
toolBlocks.set(event.contentBlockStart.contentBlockIndex ?? 0, {
|
|
569
|
+
id: start.toolUseId ?? "",
|
|
570
|
+
name: start.name ?? "",
|
|
571
|
+
json: ""
|
|
572
|
+
});
|
|
573
|
+
continue;
|
|
574
|
+
}
|
|
575
|
+
if (event.contentBlockDelta?.delta) {
|
|
576
|
+
const delta = event.contentBlockDelta.delta;
|
|
577
|
+
if (delta.text) yield {
|
|
578
|
+
type: "delta",
|
|
579
|
+
content: delta.text
|
|
580
|
+
};
|
|
581
|
+
else if (delta.toolUse) {
|
|
582
|
+
const accumulator = toolBlocks.get(event.contentBlockDelta.contentBlockIndex ?? 0);
|
|
583
|
+
if (accumulator) accumulator.json += delta.toolUse.input ?? "";
|
|
584
|
+
}
|
|
585
|
+
continue;
|
|
586
|
+
}
|
|
587
|
+
if (event.contentBlockStop) {
|
|
588
|
+
const accumulator = toolBlocks.get(event.contentBlockStop.contentBlockIndex ?? 0);
|
|
589
|
+
if (accumulator) {
|
|
590
|
+
yield {
|
|
591
|
+
type: "tool-call",
|
|
592
|
+
id: accumulator.id,
|
|
593
|
+
name: accumulator.name,
|
|
594
|
+
input: (0, _warlock_js_ai.safeJsonParse)(accumulator.json, {})
|
|
595
|
+
};
|
|
596
|
+
toolBlocks.delete(event.contentBlockStop.contentBlockIndex ?? 0);
|
|
597
|
+
}
|
|
598
|
+
continue;
|
|
599
|
+
}
|
|
600
|
+
if (event.messageStop) rawStopReason = event.messageStop.stopReason;
|
|
601
|
+
if (event.metadata?.usage) {
|
|
602
|
+
const raw = event.metadata.usage;
|
|
603
|
+
usage.input = raw.inputTokens ?? 0;
|
|
604
|
+
usage.output = raw.outputTokens ?? 0;
|
|
605
|
+
usage.total = raw.totalTokens ?? usage.input + usage.output;
|
|
606
|
+
if (raw.cacheReadInputTokens && raw.cacheReadInputTokens > 0) usage.cachedTokens = raw.cacheReadInputTokens;
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
} catch (thrown) {
|
|
610
|
+
throw this.logAndWrap(thrown);
|
|
611
|
+
}
|
|
612
|
+
const finishReason = mapStopReason(rawStopReason);
|
|
613
|
+
this.logger.debug(LOG_MODULE, "response", "ConverseStream call succeeded", {
|
|
614
|
+
finishReason,
|
|
615
|
+
usage
|
|
616
|
+
});
|
|
617
|
+
yield {
|
|
618
|
+
type: "done",
|
|
619
|
+
finishReason,
|
|
620
|
+
usage
|
|
621
|
+
};
|
|
622
|
+
}
|
|
623
|
+
/**
|
|
624
|
+
* Assemble the Converse request shared by `complete()` and
|
|
625
|
+
* `stream()` (both command shapes take the same input). Hoists the
|
|
626
|
+
* system prompt, maps inference params, and conditionally attaches
|
|
627
|
+
* tools and native structured output.
|
|
628
|
+
*/
|
|
629
|
+
buildRequest(messages, options) {
|
|
630
|
+
const { system, messages: bedrockMessages } = toBedrockMessages(messages);
|
|
631
|
+
const maxTokens = options?.maxTokens ?? this.config.maxTokens;
|
|
632
|
+
const temperature = options?.temperature ?? this.config.temperature;
|
|
633
|
+
return {
|
|
634
|
+
modelId: this.name,
|
|
635
|
+
messages: bedrockMessages,
|
|
636
|
+
...system ? { system } : {},
|
|
637
|
+
inferenceConfig: {
|
|
638
|
+
...maxTokens !== void 0 ? { maxTokens } : {},
|
|
639
|
+
...temperature !== void 0 ? { temperature } : {}
|
|
640
|
+
},
|
|
641
|
+
...this.buildToolConfig(options?.tools),
|
|
642
|
+
...this.buildOutputConfig(options?.responseSchema)
|
|
643
|
+
};
|
|
644
|
+
}
|
|
645
|
+
/**
|
|
646
|
+
* Spread-friendly tool fragment. Returns an empty object when no
|
|
647
|
+
* tools were supplied (Bedrock rejects an empty `tools` array).
|
|
648
|
+
*/
|
|
649
|
+
buildToolConfig(tools) {
|
|
650
|
+
const toolConfig = toBedrockToolConfig(tools);
|
|
651
|
+
return toolConfig ? { toolConfig } : {};
|
|
652
|
+
}
|
|
653
|
+
/**
|
|
654
|
+
* Translate the neutral `responseSchema` into Converse's native
|
|
655
|
+
* `outputConfig.textFormat` (JSON-schema structured output). Bedrock
|
|
656
|
+
* requires the schema as a stringified JSON document and only
|
|
657
|
+
* accepts an object root. Emitted only when the model is
|
|
658
|
+
* `structuredOutput`-capable and the schema is an object — otherwise
|
|
659
|
+
* the agent's soft system-prompt hint + client-side `validate()`
|
|
660
|
+
* carry shape (same degradation philosophy as the OpenAI adapter).
|
|
661
|
+
*/
|
|
662
|
+
buildOutputConfig(responseSchema) {
|
|
663
|
+
if (!responseSchema || !this.capabilities.structuredOutput) return {};
|
|
664
|
+
if (responseSchema.type !== "object" || typeof responseSchema.properties !== "object") return {};
|
|
665
|
+
return { outputConfig: { textFormat: {
|
|
666
|
+
type: "json_schema",
|
|
667
|
+
structure: { jsonSchema: {
|
|
668
|
+
name: "response",
|
|
669
|
+
schema: JSON.stringify(responseSchema)
|
|
670
|
+
} }
|
|
671
|
+
} } };
|
|
672
|
+
}
|
|
673
|
+
/**
|
|
674
|
+
* Concatenate every `text` content block into the single neutral
|
|
675
|
+
* `content` string. `toolUse` and other block types are surfaced
|
|
676
|
+
* separately via `extractToolCalls`.
|
|
677
|
+
*/
|
|
678
|
+
extractText(blocks) {
|
|
679
|
+
return blocks.map((block) => "text" in block && typeof block.text === "string" ? block.text : "").join("");
|
|
680
|
+
}
|
|
681
|
+
/**
|
|
682
|
+
* Reshape Converse `toolUse` content blocks into the neutral
|
|
683
|
+
* `ModelToolCallRequest[]`. Returns `undefined` when no tools were
|
|
684
|
+
* requested so callers can branch on presence.
|
|
685
|
+
*/
|
|
686
|
+
extractToolCalls(blocks) {
|
|
687
|
+
const toolCalls = [];
|
|
688
|
+
for (const block of blocks) if ("toolUse" in block && block.toolUse) toolCalls.push({
|
|
689
|
+
id: block.toolUse.toolUseId ?? "",
|
|
690
|
+
name: block.toolUse.name ?? "",
|
|
691
|
+
input: block.toolUse.input ?? {}
|
|
692
|
+
});
|
|
693
|
+
return toolCalls.length > 0 ? toolCalls : void 0;
|
|
694
|
+
}
|
|
695
|
+
/**
|
|
696
|
+
* Normalize Converse's `TokenUsage` into the neutral `Usage` shape.
|
|
697
|
+
* Bedrock supplies a pre-summed `totalTokens`; cache-read tokens are
|
|
698
|
+
* surfaced as `cachedTokens` only when non-zero.
|
|
699
|
+
*/
|
|
700
|
+
extractUsage(raw) {
|
|
701
|
+
if (!raw) return {
|
|
702
|
+
input: 0,
|
|
703
|
+
output: 0,
|
|
704
|
+
total: 0
|
|
705
|
+
};
|
|
706
|
+
const input = raw.inputTokens ?? 0;
|
|
707
|
+
const output = raw.outputTokens ?? 0;
|
|
708
|
+
const cached = raw.cacheReadInputTokens;
|
|
709
|
+
return {
|
|
710
|
+
input,
|
|
711
|
+
output,
|
|
712
|
+
total: raw.totalTokens ?? input + output,
|
|
713
|
+
...cached && cached > 0 ? { cachedTokens: cached } : {}
|
|
714
|
+
};
|
|
715
|
+
}
|
|
716
|
+
/**
|
|
717
|
+
* Wrap a thrown provider error into the typed `AIError` hierarchy
|
|
718
|
+
* and emit the standard error log line before it propagates. Shared
|
|
719
|
+
* by every catch site so the log shape stays identical.
|
|
720
|
+
*/
|
|
721
|
+
logAndWrap(thrown) {
|
|
722
|
+
const wrapped = wrapBedrockError(thrown);
|
|
723
|
+
this.logger.error(LOG_MODULE, "error", wrapped.message, {
|
|
724
|
+
code: wrapped.code,
|
|
725
|
+
context: wrapped.context
|
|
726
|
+
});
|
|
727
|
+
return wrapped;
|
|
728
|
+
}
|
|
729
|
+
};
|
|
730
|
+
|
|
731
|
+
//#endregion
|
|
732
|
+
//#region ../../@warlock.js/ai-bedrock/src/sdk.ts
|
|
733
|
+
/**
|
|
734
|
+
* AWS Bedrock-backed implementation of `SDKAdapterContract`.
|
|
735
|
+
*
|
|
736
|
+
* **Role.** The package entry point for any Bedrock-hosted model via
|
|
737
|
+
* the Converse API. A single `BedrockSDK` holds one live
|
|
738
|
+
* `BedrockRuntimeClient`, shared by every `ModelContract` and
|
|
739
|
+
* `EmbedderContract` it produces. Construct one SDK per AWS
|
|
740
|
+
* account/region and reuse it everywhere.
|
|
741
|
+
*
|
|
742
|
+
* **Responsibility.**
|
|
743
|
+
* - Owns: a long-lived `BedrockRuntimeClient` (region, credential
|
|
744
|
+
* chain) and its lifetime. Factory for `BedrockModel` /
|
|
745
|
+
* `BedrockEmbedder` instances sharing that client.
|
|
746
|
+
* - Does NOT own: anything per-call — those live in `BedrockModel` /
|
|
747
|
+
* `BedrockEmbedder` and the agent runtime.
|
|
748
|
+
*
|
|
749
|
+
* Modeled as a class (see §4.2 of code-style.md — "long-lived state
|
|
750
|
+
* across many calls"): the AWS client is heavy to construct and
|
|
751
|
+
* designed for reuse; keeping it on `this` aligns with the
|
|
752
|
+
* `new BedrockRuntimeClient(...)` upstream convention.
|
|
753
|
+
*
|
|
754
|
+
* @example
|
|
755
|
+
* const bedrock = new BedrockSDK({ region: "us-east-1" });
|
|
756
|
+
* const model = bedrock.model({ name: "anthropic.claude-sonnet-4-5-20250929-v1:0" });
|
|
757
|
+
* const embedder = bedrock.embedder({ name: "amazon.titan-embed-text-v2:0" });
|
|
758
|
+
*/
|
|
759
|
+
var BedrockSDK = class {
|
|
760
|
+
constructor(config) {
|
|
761
|
+
const { provider, pricing, ...clientConfig } = config;
|
|
762
|
+
this.client = new _aws_sdk_client_bedrock_runtime.BedrockRuntimeClient(clientConfig);
|
|
763
|
+
this.provider = provider ?? "bedrock";
|
|
764
|
+
this.pricing = pricing;
|
|
765
|
+
}
|
|
766
|
+
/**
|
|
767
|
+
* Build a `BedrockModel` bound to this SDK's client. Each call
|
|
768
|
+
* returns a fresh instance; all instances share the underlying AWS
|
|
769
|
+
* client so connection pools, credential refresh, and retry config
|
|
770
|
+
* stay unified. The SDK's `provider` label is forwarded.
|
|
771
|
+
*
|
|
772
|
+
* Pricing resolution: per-model `config.pricing` wins; otherwise the
|
|
773
|
+
* SDK-level registry entry keyed by `config.name`; otherwise
|
|
774
|
+
* `undefined` (no cost computed).
|
|
775
|
+
*/
|
|
776
|
+
model(config) {
|
|
777
|
+
const resolvedPricing = config.pricing ?? this.pricing?.[config.name];
|
|
778
|
+
const resolvedConfig = resolvedPricing === config.pricing ? config : {
|
|
779
|
+
...config,
|
|
780
|
+
pricing: resolvedPricing
|
|
781
|
+
};
|
|
782
|
+
return new BedrockModel(this.client, resolvedConfig, this.provider);
|
|
783
|
+
}
|
|
784
|
+
/**
|
|
785
|
+
* Rough token-count estimate. Uses the character-heuristic
|
|
786
|
+
* (`approximateTokenCount`) from the core package — Bedrock has no
|
|
787
|
+
* offline tokenizer and the per-model tokenizers differ; good enough
|
|
788
|
+
* for budgeting and quota guards, not for billing.
|
|
789
|
+
*/
|
|
790
|
+
async count(text, _model) {
|
|
791
|
+
return (0, _warlock_js_ai.approximateTokenCount)(text);
|
|
792
|
+
}
|
|
793
|
+
/**
|
|
794
|
+
* Build a `BedrockEmbedder` (Amazon Titan Text Embeddings) bound to
|
|
795
|
+
* this SDK's client.
|
|
796
|
+
*
|
|
797
|
+
* @example
|
|
798
|
+
* const embedder = bedrock.embedder({ name: "amazon.titan-embed-text-v2:0" });
|
|
799
|
+
* const { vector } = await embedder.embed("Hello world");
|
|
800
|
+
*/
|
|
801
|
+
embedder(config) {
|
|
802
|
+
return new BedrockEmbedder(this.client, config, this.provider);
|
|
803
|
+
}
|
|
804
|
+
};
|
|
805
|
+
|
|
806
|
+
//#endregion
|
|
807
|
+
exports.BedrockSDK = BedrockSDK;
|
|
808
|
+
//# sourceMappingURL=index.cjs.map
|