@happyvertical/ai 0.80.0 → 0.80.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.
Files changed (61) hide show
  1. package/dist/chunks/anthropic-DA8sdt12.js +438 -0
  2. package/dist/chunks/anthropic-DA8sdt12.js.map +1 -0
  3. package/dist/chunks/bedrock-DDiYFUw0.js +699 -0
  4. package/dist/chunks/bedrock-DDiYFUw0.js.map +1 -0
  5. package/dist/chunks/bifrost-fM9FpW_w.js +198 -0
  6. package/dist/chunks/bifrost-fM9FpW_w.js.map +1 -0
  7. package/dist/chunks/claude-cli-CnJh5KQT.js +498 -0
  8. package/dist/chunks/claude-cli-CnJh5KQT.js.map +1 -0
  9. package/dist/chunks/gateway-admin-CiKvHst7.js +283 -0
  10. package/dist/chunks/gateway-admin-CiKvHst7.js.map +1 -0
  11. package/dist/chunks/gemini-Bu7Fke7c.js +593 -0
  12. package/dist/chunks/gemini-Bu7Fke7c.js.map +1 -0
  13. package/dist/chunks/huggingface-B07_6wHW.js +295 -0
  14. package/dist/chunks/huggingface-B07_6wHW.js.map +1 -0
  15. package/dist/chunks/litellm-D_Oo9OQ_.js +185 -0
  16. package/dist/chunks/litellm-D_Oo9OQ_.js.map +1 -0
  17. package/dist/chunks/ollama-D4ksOTO8.js +626 -0
  18. package/dist/chunks/ollama-D4ksOTO8.js.map +1 -0
  19. package/dist/chunks/openai--F38QHiJ.js +691 -0
  20. package/dist/chunks/openai--F38QHiJ.js.map +1 -0
  21. package/dist/chunks/qwen-tts-DRRbOrhA.js +333 -0
  22. package/dist/chunks/qwen-tts-DRRbOrhA.js.map +1 -0
  23. package/dist/chunks/rate-limit-BwyPGXFW.js +199 -0
  24. package/dist/chunks/rate-limit-BwyPGXFW.js.map +1 -0
  25. package/dist/chunks/safety-CEnoJS6X.js +260 -0
  26. package/dist/chunks/safety-CEnoJS6X.js.map +1 -0
  27. package/dist/chunks/types-FHs-KbGL.js +117 -0
  28. package/dist/chunks/types-FHs-KbGL.js.map +1 -0
  29. package/dist/chunks/usage-C1Y1Nlg4.js +35 -0
  30. package/dist/chunks/usage-C1Y1Nlg4.js.map +1 -0
  31. package/dist/cli/claude-context.js +17 -17
  32. package/dist/cli/claude-context.js.map +1 -1
  33. package/dist/index.js +717 -23
  34. package/dist/index.js.map +1 -1
  35. package/package.json +5 -5
  36. package/dist/chunks/anthropic-2z-82zgr.js +0 -530
  37. package/dist/chunks/anthropic-2z-82zgr.js.map +0 -1
  38. package/dist/chunks/bedrock-Dc2eVPUD.js +0 -920
  39. package/dist/chunks/bedrock-Dc2eVPUD.js.map +0 -1
  40. package/dist/chunks/bifrost-CEnCsciy.js +0 -258
  41. package/dist/chunks/bifrost-CEnCsciy.js.map +0 -1
  42. package/dist/chunks/claude-cli-X1ONjE8K.js +0 -603
  43. package/dist/chunks/claude-cli-X1ONjE8K.js.map +0 -1
  44. package/dist/chunks/gateway-admin-BUhBzXZb.js +0 -359
  45. package/dist/chunks/gateway-admin-BUhBzXZb.js.map +0 -1
  46. package/dist/chunks/gemini-CS56gY0D.js +0 -768
  47. package/dist/chunks/gemini-CS56gY0D.js.map +0 -1
  48. package/dist/chunks/huggingface-wQSfO5xA.js +0 -411
  49. package/dist/chunks/huggingface-wQSfO5xA.js.map +0 -1
  50. package/dist/chunks/index-DCXO0nZA.js +0 -1293
  51. package/dist/chunks/index-DCXO0nZA.js.map +0 -1
  52. package/dist/chunks/litellm-BMFTYbWc.js +0 -245
  53. package/dist/chunks/litellm-BMFTYbWc.js.map +0 -1
  54. package/dist/chunks/ollama-DsGDrA-c.js +0 -962
  55. package/dist/chunks/ollama-DsGDrA-c.js.map +0 -1
  56. package/dist/chunks/openai-CJEo69jb.js +0 -882
  57. package/dist/chunks/openai-CJEo69jb.js.map +0 -1
  58. package/dist/chunks/qwen-tts-BLYZ6d9s.js +0 -365
  59. package/dist/chunks/qwen-tts-BLYZ6d9s.js.map +0 -1
  60. package/dist/chunks/usage-DMWiJ2oB.js +0 -21
  61. package/dist/chunks/usage-DMWiJ2oB.js.map +0 -1
@@ -0,0 +1,699 @@
1
+ import { a as ContextLengthError, c as extractTextContent, o as ModelNotFoundError, r as AuthenticationError, s as RateLimitError, t as AIError } from "./types-FHs-KbGL.js";
2
+ import { a as normalizeBaseAIOptions, c as prepareRequestControls, o as normalizeChatOptions, s as normalizeImageGenerationOptions } from "./safety-CEnoJS6X.js";
3
+ import { t as emitUsage } from "./usage-C1Y1Nlg4.js";
4
+ //#region src/shared/providers/bedrock.ts
5
+ /**
6
+ * AWS Bedrock provider implementation
7
+ */
8
+ var BEDROCK_DEFAULT_CHAT_MODEL = "anthropic.claude-3-5-sonnet-20241022-v2:0";
9
+ var BEDROCK_TEXT_EMBEDDING_MODEL = "amazon.titan-embed-text-v2:0";
10
+ var BEDROCK_IMAGE_EMBEDDING_MODEL = "amazon.titan-embed-image-v1";
11
+ var BEDROCK_IMAGE_GENERATION_MODEL = "amazon.titan-image-generator-v2:0";
12
+ var BedrockProvider = class {
13
+ options;
14
+ client;
15
+ constructor(options) {
16
+ this.options = normalizeBaseAIOptions({
17
+ defaultModel: BEDROCK_DEFAULT_CHAT_MODEL,
18
+ ...options
19
+ });
20
+ this.initializeClientSync();
21
+ }
22
+ initializeClientSync() {
23
+ try {
24
+ import("@aws-sdk/client-bedrock-runtime").then(({ BedrockRuntimeClient }) => {
25
+ this.client = new BedrockRuntimeClient({
26
+ region: this.options.region,
27
+ credentials: this.options.credentials,
28
+ endpoint: this.options.endpoint,
29
+ maxAttempts: (this.options.maxRetries || 0) + 1
30
+ });
31
+ }).catch(() => {});
32
+ } catch (_error) {}
33
+ }
34
+ async ensureClient() {
35
+ if (!this.client) try {
36
+ const { BedrockRuntimeClient } = await import("@aws-sdk/client-bedrock-runtime");
37
+ this.client = new BedrockRuntimeClient({
38
+ region: this.options.region,
39
+ credentials: this.options.credentials,
40
+ endpoint: this.options.endpoint,
41
+ maxAttempts: (this.options.maxRetries || 0) + 1
42
+ });
43
+ } catch (_error) {
44
+ throw new AIError("Failed to initialize Bedrock client. Make sure @aws-sdk/client-bedrock-runtime is installed.", "INITIALIZATION_ERROR", "bedrock");
45
+ }
46
+ }
47
+ async chat(messages, options = {}) {
48
+ const startTime = Date.now();
49
+ let controls;
50
+ try {
51
+ await this.ensureClient();
52
+ const modelId = options.model || this.options.defaultModel;
53
+ options = normalizeChatOptions(this.options, options, "bedrock", modelId);
54
+ controls = prepareRequestControls(this.options, options);
55
+ const response = this.mapConverseResponse(await this.client.converse(await this.buildConverseRequest(messages, options, modelId, controls.signal), { abortSignal: controls.signal }), modelId);
56
+ emitUsage(this.options, "bedrock", "chat", response.model || modelId || "unknown", response.usage, startTime, options.usageTags);
57
+ return response;
58
+ } catch (error) {
59
+ if (controls?.didTimeout()) throw new AIError(`AI request timed out after ${controls.timeout}ms`, "AI_TIMEOUT", "bedrock", options.model);
60
+ if (options.signal?.aborted) throw new AIError("AI request aborted by caller", "AI_ABORTED", "bedrock", options.model);
61
+ throw this.mapError(error);
62
+ } finally {
63
+ controls?.cleanup();
64
+ }
65
+ }
66
+ async complete(prompt, options = {}) {
67
+ return this.chat([{
68
+ role: "user",
69
+ content: prompt
70
+ }], {
71
+ model: options.model,
72
+ maxTokens: options.maxTokens,
73
+ temperature: options.temperature,
74
+ topP: options.topP,
75
+ n: options.n,
76
+ stop: options.stop,
77
+ stream: options.stream,
78
+ onProgress: options.onProgress,
79
+ signal: options.signal,
80
+ timeout: options.timeout,
81
+ reasoning: options.reasoning,
82
+ usageTags: options.usageTags
83
+ });
84
+ }
85
+ /**
86
+ * Simple message interface for single-turn interactions with optional history
87
+ *
88
+ * @param text - The message text to send
89
+ * @param options - Configuration options including history, model, etc.
90
+ * @returns Promise resolving to the response content string
91
+ */
92
+ async message(text, options = {}) {
93
+ const messages = [...options.history || [], {
94
+ role: options.role || "user",
95
+ content: text
96
+ }];
97
+ return (await this.chat(messages, {
98
+ model: options.model,
99
+ maxTokens: options.maxTokens,
100
+ temperature: options.temperature,
101
+ topP: options.topP,
102
+ stop: options.stop,
103
+ stream: options.stream,
104
+ frequencyPenalty: options.frequencyPenalty,
105
+ presencePenalty: options.presencePenalty,
106
+ responseFormat: options.responseFormat,
107
+ seed: options.seed,
108
+ tools: options.tools,
109
+ toolChoice: options.toolChoice,
110
+ onProgress: options.onProgress,
111
+ signal: options.signal,
112
+ timeout: options.timeout,
113
+ reasoning: options.reasoning,
114
+ usageTags: options.usageTags
115
+ })).content;
116
+ }
117
+ async embed(text, options = {}) {
118
+ const startTime = Date.now();
119
+ try {
120
+ await this.ensureClient();
121
+ const model = options.model || BEDROCK_TEXT_EMBEDDING_MODEL;
122
+ const inputs = Array.isArray(text) ? text : [text];
123
+ const embeddings = [];
124
+ let totalTokens = 0;
125
+ for (const inputText of inputs) {
126
+ const response = await this.client.invokeModel({
127
+ modelId: model,
128
+ contentType: "application/json",
129
+ accept: "application/json",
130
+ body: JSON.stringify({
131
+ inputText,
132
+ ...options.dimensions && { dimensions: options.dimensions },
133
+ normalize: true
134
+ })
135
+ });
136
+ const payload = await this.parseInvokeModelBody(response.body);
137
+ const embedding = this.extractEmbeddingVector(payload);
138
+ if (embedding) embeddings.push(embedding);
139
+ totalTokens += payload.inputTextTokenCount || payload.inputTokenCount || payload.tokenCount || 0;
140
+ }
141
+ const usage = totalTokens > 0 ? {
142
+ promptTokens: totalTokens,
143
+ completionTokens: 0,
144
+ totalTokens
145
+ } : void 0;
146
+ emitUsage(this.options, "bedrock", "embed", model, usage, startTime, options.usageTags);
147
+ return {
148
+ embeddings,
149
+ model,
150
+ usage
151
+ };
152
+ } catch (error) {
153
+ throw this.mapError(error);
154
+ }
155
+ }
156
+ async embedImage(image, options = {}) {
157
+ const startTime = Date.now();
158
+ try {
159
+ await this.ensureClient();
160
+ const model = options.model || BEDROCK_IMAGE_EMBEDDING_MODEL;
161
+ const response = await this.client.invokeModel({
162
+ modelId: model,
163
+ contentType: "application/json",
164
+ accept: "application/json",
165
+ body: JSON.stringify({
166
+ inputImage: await this.imageToBase64(image),
167
+ ...options.dimensions && { embeddingConfig: { outputEmbeddingLength: options.dimensions } }
168
+ })
169
+ });
170
+ const payload = await this.parseInvokeModelBody(response.body);
171
+ const embedding = this.extractEmbeddingVector(payload);
172
+ emitUsage(this.options, "bedrock", "embedImage", model, void 0, startTime);
173
+ return {
174
+ embeddings: embedding ? [embedding] : [],
175
+ model
176
+ };
177
+ } catch (error) {
178
+ throw this.mapError(error);
179
+ }
180
+ }
181
+ async describeImage(image, prompt, options = {}) {
182
+ const imageUrl = await this.imageToDataUrl(image, options.signal);
183
+ return (await this.chat([{
184
+ role: "user",
185
+ content: [{
186
+ type: "text",
187
+ text: prompt || "Describe this image for a search index. Include objects, mood, lighting, and any visible text."
188
+ }, {
189
+ type: "image_url",
190
+ image_url: { url: imageUrl }
191
+ }]
192
+ }], {
193
+ model: options.model || this.options.defaultModel,
194
+ maxTokens: options.maxTokens ?? 500,
195
+ signal: options.signal,
196
+ timeout: options.timeout,
197
+ reasoning: options.reasoning,
198
+ usageTags: options.usageTags
199
+ })).content;
200
+ }
201
+ async generateImage(prompt, options = {}) {
202
+ let controls;
203
+ try {
204
+ await this.ensureClient();
205
+ const model = options.model || BEDROCK_IMAGE_GENERATION_MODEL;
206
+ options = normalizeImageGenerationOptions(this.options, options, "bedrock", model);
207
+ controls = prepareRequestControls(this.options, options);
208
+ const size = this.resolveImageSize(options);
209
+ const response = await this.client.invokeModel({
210
+ modelId: model,
211
+ contentType: "application/json",
212
+ accept: "application/json",
213
+ body: JSON.stringify({
214
+ taskType: "TEXT_IMAGE",
215
+ textToImageParams: {
216
+ text: prompt,
217
+ ...options.imageInput && { conditionImage: await this.imageToBase64(options.imageInput, controls.signal) }
218
+ },
219
+ imageGenerationConfig: {
220
+ numberOfImages: options.n,
221
+ quality: this.mapImageQuality(options.quality),
222
+ ...size
223
+ }
224
+ })
225
+ }, { abortSignal: controls.signal });
226
+ const payload = await this.parseInvokeModelBody(response.body);
227
+ if (payload.error) throw new AIError(payload.error, "API_ERROR", "bedrock");
228
+ return {
229
+ images: (payload.images || []).map((encoded) => {
230
+ const mimeType = "image/png";
231
+ if (options.outputFormat === "base64") return {
232
+ data: encoded,
233
+ mimeType
234
+ };
235
+ if (options.outputFormat === "url") return {
236
+ data: `data:${mimeType};base64,${encoded}`,
237
+ mimeType
238
+ };
239
+ return {
240
+ data: Buffer.from(encoded, "base64"),
241
+ mimeType
242
+ };
243
+ }),
244
+ model
245
+ };
246
+ } catch (error) {
247
+ if (controls?.didTimeout()) throw new AIError(`AI request timed out after ${controls.timeout}ms`, "AI_TIMEOUT", "bedrock", options.model);
248
+ if (options.signal?.aborted) throw new AIError("AI request aborted by caller", "AI_ABORTED", "bedrock", options.model);
249
+ throw this.mapError(error);
250
+ } finally {
251
+ controls?.cleanup();
252
+ }
253
+ }
254
+ async *stream(messages, options = {}) {
255
+ const startTime = Date.now();
256
+ let controls;
257
+ try {
258
+ await this.ensureClient();
259
+ const modelId = options.model || this.options.defaultModel;
260
+ options = normalizeChatOptions(this.options, options, "bedrock", modelId);
261
+ controls = prepareRequestControls(this.options, options);
262
+ const response = await this.client.converseStream(await this.buildConverseRequest(messages, options, modelId, controls.signal), { abortSignal: controls.signal });
263
+ let usage;
264
+ for await (const event of response.stream || []) {
265
+ const text = event.contentBlockDelta?.delta?.text;
266
+ if (text) {
267
+ if (options.onProgress) options.onProgress(text);
268
+ yield text;
269
+ }
270
+ if (event.metadata?.usage) usage = {
271
+ promptTokens: event.metadata.usage.inputTokens || 0,
272
+ completionTokens: event.metadata.usage.outputTokens || 0,
273
+ totalTokens: event.metadata.usage.totalTokens || 0
274
+ };
275
+ }
276
+ emitUsage(this.options, "bedrock", "stream", modelId || "unknown", usage, startTime, options.usageTags);
277
+ } catch (error) {
278
+ if (controls?.didTimeout()) throw new AIError(`AI request timed out after ${controls.timeout}ms`, "AI_TIMEOUT", "bedrock", options.model);
279
+ if (options.signal?.aborted) throw new AIError("AI request aborted by caller", "AI_ABORTED", "bedrock", options.model);
280
+ throw this.mapError(error);
281
+ } finally {
282
+ controls?.cleanup();
283
+ }
284
+ }
285
+ async countTokens(text) {
286
+ try {
287
+ await this.ensureClient();
288
+ const modelId = this.options.defaultModel || BEDROCK_DEFAULT_CHAT_MODEL;
289
+ return (await this.client.countTokens({
290
+ modelId,
291
+ input: { converse: { messages: [{
292
+ role: "user",
293
+ content: [{ text }]
294
+ }] } }
295
+ })).inputTokens || Math.ceil(text.length / 4);
296
+ } catch (error) {
297
+ throw this.mapError(error);
298
+ }
299
+ }
300
+ async getModels() {
301
+ return [
302
+ {
303
+ id: "anthropic.claude-3-5-sonnet-20241022-v2:0",
304
+ name: "Claude 3.5 Sonnet v2",
305
+ description: "Latest Claude 3.5 Sonnet model on Bedrock",
306
+ contextLength: 2e5,
307
+ capabilities: [
308
+ "text",
309
+ "chat",
310
+ "vision",
311
+ "functions"
312
+ ],
313
+ supportsFunctions: true,
314
+ supportsVision: true
315
+ },
316
+ {
317
+ id: "anthropic.claude-3-opus-20240229-v1:0",
318
+ name: "Claude 3 Opus",
319
+ description: "Most powerful Claude model on Bedrock",
320
+ contextLength: 2e5,
321
+ capabilities: [
322
+ "text",
323
+ "chat",
324
+ "vision"
325
+ ],
326
+ supportsFunctions: false,
327
+ supportsVision: true
328
+ },
329
+ {
330
+ id: "amazon.titan-text-premier-v1:0",
331
+ name: "Titan Text Premier",
332
+ description: "Premier Amazon Titan text model",
333
+ contextLength: 32e3,
334
+ capabilities: ["text", "chat"],
335
+ supportsFunctions: false,
336
+ supportsVision: false
337
+ },
338
+ {
339
+ id: "amazon.titan-embed-text-v1",
340
+ name: "Titan Embeddings Text",
341
+ description: "Amazon Titan text embeddings model",
342
+ contextLength: 8192,
343
+ capabilities: ["embeddings"],
344
+ supportsFunctions: false,
345
+ supportsVision: false
346
+ },
347
+ {
348
+ id: BEDROCK_TEXT_EMBEDDING_MODEL,
349
+ name: "Titan Embeddings Text V2",
350
+ description: "Amazon Titan text embeddings v2 model",
351
+ contextLength: 8192,
352
+ capabilities: ["embeddings"],
353
+ supportsFunctions: false,
354
+ supportsVision: false
355
+ },
356
+ {
357
+ id: BEDROCK_IMAGE_EMBEDDING_MODEL,
358
+ name: "Titan Multimodal Embeddings G1",
359
+ description: "Amazon Titan multimodal embeddings model for image similarity",
360
+ contextLength: 256,
361
+ capabilities: ["embeddings", "image_embedding"],
362
+ supportsFunctions: false,
363
+ supportsVision: false
364
+ },
365
+ {
366
+ id: BEDROCK_IMAGE_GENERATION_MODEL,
367
+ name: "Titan Image Generator V2",
368
+ description: "Amazon Titan image generation model",
369
+ contextLength: 0,
370
+ capabilities: ["image_generation"],
371
+ supportsFunctions: false,
372
+ supportsVision: false
373
+ },
374
+ {
375
+ id: "cohere.command-r-plus-v1:0",
376
+ name: "Command R+",
377
+ description: "Cohere Command R+ model with advanced capabilities",
378
+ contextLength: 128e3,
379
+ capabilities: [
380
+ "text",
381
+ "chat",
382
+ "functions"
383
+ ],
384
+ supportsFunctions: true,
385
+ supportsVision: false
386
+ },
387
+ {
388
+ id: "meta.llama3-1-405b-instruct-v1:0",
389
+ name: "Llama 3.1 405B Instruct",
390
+ description: "Meta Llama 3.1 405B instruction-tuned model",
391
+ contextLength: 128e3,
392
+ capabilities: ["text", "chat"],
393
+ supportsFunctions: false,
394
+ supportsVision: false
395
+ }
396
+ ];
397
+ }
398
+ async getCapabilities() {
399
+ return {
400
+ chat: true,
401
+ completion: true,
402
+ embeddings: true,
403
+ streaming: true,
404
+ functions: true,
405
+ vision: true,
406
+ fineTuning: true,
407
+ imageEmbeddings: true,
408
+ imageGeneration: true,
409
+ tts: false,
410
+ voiceCloning: false,
411
+ voiceDesign: false,
412
+ maxContextLength: 2e5,
413
+ supportedOperations: [
414
+ "chat",
415
+ "completion",
416
+ "embedding",
417
+ "streaming",
418
+ "functions",
419
+ "vision",
420
+ "image_embedding",
421
+ "image_generation"
422
+ ]
423
+ };
424
+ }
425
+ async synthesizeSpeech(_text, _options) {
426
+ throw new AIError("TTS is not supported by Bedrock provider. Use Qwen3-TTS provider.", "NOT_IMPLEMENTED", "bedrock");
427
+ }
428
+ streamSpeech(_text, _options) {
429
+ const error = new AIError("TTS streaming is not supported by Bedrock provider. Use Qwen3-TTS provider.", "NOT_IMPLEMENTED", "bedrock");
430
+ return { [Symbol.asyncIterator]: () => ({ next: () => Promise.reject(error) }) };
431
+ }
432
+ async cloneVoice(_options) {
433
+ throw new AIError("Voice cloning is not supported by Bedrock provider. Use Qwen3-TTS provider.", "NOT_IMPLEMENTED", "bedrock");
434
+ }
435
+ async designVoice(_options) {
436
+ throw new AIError("Voice design is not supported by Bedrock provider. Use Qwen3-TTS provider.", "NOT_IMPLEMENTED", "bedrock");
437
+ }
438
+ async getVoices(_options) {
439
+ throw new AIError("Voice listing is not supported by Bedrock provider. Use Qwen3-TTS provider.", "NOT_IMPLEMENTED", "bedrock");
440
+ }
441
+ async buildConverseRequest(messages, options, modelId, signal) {
442
+ const { system, bedrockMessages } = await this.mapMessagesToBedrock(messages, signal);
443
+ const systemPrompt = options.responseFormat?.type === "json_object" ? [system, "Respond with valid JSON only. Do not include explanatory text outside the JSON object."].filter(Boolean).join("\n\n") : system;
444
+ const inferenceConfig = Object.fromEntries(Object.entries({
445
+ maxTokens: options.maxTokens,
446
+ temperature: options.temperature,
447
+ topP: options.topP,
448
+ stopSequences: Array.isArray(options.stop) ? options.stop : options.stop ? [options.stop] : void 0
449
+ }).filter(([, value]) => value !== void 0));
450
+ const request = {
451
+ modelId,
452
+ messages: bedrockMessages,
453
+ ...Object.keys(inferenceConfig).length > 0 && { inferenceConfig },
454
+ ...systemPrompt && { system: [{ text: systemPrompt }] }
455
+ };
456
+ if ((options.reasoning?.maxTokens || 0) > 0) request.additionalModelRequestFields = { thinking: {
457
+ type: "enabled",
458
+ budget_tokens: options.reasoning?.maxTokens
459
+ } };
460
+ const toolConfig = this.mapToolConfig(options);
461
+ if (toolConfig) request.toolConfig = toolConfig;
462
+ return request;
463
+ }
464
+ async mapMessagesToBedrock(messages, signal) {
465
+ let system;
466
+ const bedrockMessages = [];
467
+ for (const message of messages) {
468
+ const textContent = extractTextContent(message.content);
469
+ if (message.role === "system") {
470
+ system = system ? `${system}\n\n${textContent}` : textContent;
471
+ continue;
472
+ }
473
+ const content = [];
474
+ if (typeof message.content === "string") content.push({ text: message.content });
475
+ else for (const part of message.content) {
476
+ if (part.type === "text") {
477
+ content.push({ text: part.text });
478
+ continue;
479
+ }
480
+ const image = await this.imageUrlToBedrockImage(part.image_url.url, signal);
481
+ content.push({ image });
482
+ }
483
+ if (message.role === "assistant" && message.tool_calls) for (const toolCall of message.tool_calls) content.push({ toolUse: {
484
+ toolUseId: toolCall.id,
485
+ name: toolCall.function.name,
486
+ input: this.safeJsonParse(toolCall.function.arguments)
487
+ } });
488
+ if (content.length === 0 && textContent) content.push({ text: textContent });
489
+ bedrockMessages.push({
490
+ role: message.role === "assistant" ? "assistant" : "user",
491
+ content
492
+ });
493
+ }
494
+ return {
495
+ system,
496
+ bedrockMessages
497
+ };
498
+ }
499
+ mapConverseResponse(response, modelId) {
500
+ const contentBlocks = response.output?.message?.content || [];
501
+ const textContent = contentBlocks.filter((block) => typeof block.text === "string").map((block) => block.text).join("");
502
+ const toolCalls = contentBlocks.filter((block) => block.toolUse).map((block) => ({
503
+ id: block.toolUse.toolUseId,
504
+ type: "function",
505
+ function: {
506
+ name: block.toolUse.name,
507
+ arguments: JSON.stringify(block.toolUse.input || {})
508
+ }
509
+ }));
510
+ const usage = response.usage && {
511
+ promptTokens: response.usage.inputTokens || 0,
512
+ completionTokens: response.usage.outputTokens || 0,
513
+ totalTokens: response.usage.totalTokens || 0
514
+ };
515
+ return {
516
+ content: textContent,
517
+ model: modelId,
518
+ finishReason: this.mapBedrockFinishReason(response.stopReason),
519
+ usage,
520
+ toolCalls: toolCalls.length > 0 ? toolCalls : void 0
521
+ };
522
+ }
523
+ mapBedrockFinishReason(reason) {
524
+ switch (reason) {
525
+ case "end_turn": return "stop";
526
+ case "max_tokens": return "length";
527
+ case "stop_sequence": return "stop";
528
+ case "tool_use": return "tool_calls";
529
+ default: return "stop";
530
+ }
531
+ }
532
+ mapToolConfig(options) {
533
+ if (!options.tools || options.tools.length === 0) return;
534
+ if (options.toolChoice === "none") return;
535
+ return {
536
+ tools: options.tools.map((tool) => ({ toolSpec: {
537
+ name: tool.function.name,
538
+ description: tool.function.description || "",
539
+ inputSchema: { json: tool.function.parameters || { type: "object" } }
540
+ } })),
541
+ ...options.toolChoice && { toolChoice: this.mapToolChoice(options.toolChoice) }
542
+ };
543
+ }
544
+ mapToolChoice(toolChoice) {
545
+ if (!toolChoice || toolChoice === "auto") return { auto: {} };
546
+ if (toolChoice === "none") return;
547
+ return { tool: { name: toolChoice.function.name } };
548
+ }
549
+ async parseInvokeModelBody(body) {
550
+ const bytes = typeof body?.transformToByteArray === "function" ? await body.transformToByteArray() : body instanceof Uint8Array ? body : Buffer.isBuffer(body) ? body : new Uint8Array(body);
551
+ return JSON.parse(new TextDecoder().decode(bytes));
552
+ }
553
+ extractEmbeddingVector(payload) {
554
+ if (Array.isArray(payload.embedding)) return payload.embedding;
555
+ if (Array.isArray(payload.embeddings?.[0])) return payload.embeddings[0];
556
+ if (Array.isArray(payload.embeddingsByType?.float)) return payload.embeddingsByType.float;
557
+ if (Array.isArray(payload.vector)) return payload.vector;
558
+ }
559
+ async imageUrlToBedrockImage(imageUrl, signal) {
560
+ const { bytes, mimeType } = await this.imageToBytes(imageUrl, signal);
561
+ return {
562
+ format: this.mimeTypeToBedrockImageFormat(mimeType),
563
+ source: { bytes }
564
+ };
565
+ }
566
+ async imageToDataUrl(image, signal) {
567
+ if (Buffer.isBuffer(image)) return `data:image/png;base64,${image.toString("base64")}`;
568
+ if (image.startsWith("data:")) return image;
569
+ const { bytes, mimeType } = await this.imageToBytes(image, signal);
570
+ return `data:${mimeType};base64,${Buffer.from(bytes).toString("base64")}`;
571
+ }
572
+ async imageToBase64(image, signal) {
573
+ if (Buffer.isBuffer(image)) return image.toString("base64");
574
+ if (image.startsWith("data:")) {
575
+ const match = image.match(/^data:([^;]+);base64,(.+)$/);
576
+ if (!match) throw new AIError("Invalid base64 data URL format", "INVALID_INPUT", "bedrock");
577
+ return match[2];
578
+ }
579
+ const { bytes } = await this.imageToBytes(image, signal);
580
+ return Buffer.from(bytes).toString("base64");
581
+ }
582
+ async imageToBytes(image, signal) {
583
+ if (image.startsWith("data:")) {
584
+ const match = image.match(/^data:([^;]+);base64,(.+)$/);
585
+ if (!match) throw new AIError("Invalid base64 data URL format", "INVALID_INPUT", "bedrock");
586
+ return {
587
+ bytes: Uint8Array.from(Buffer.from(match[2], "base64")),
588
+ mimeType: match[1]
589
+ };
590
+ }
591
+ const response = await fetch(image, { signal });
592
+ if (!response.ok) throw new AIError(`Failed to fetch image: ${response.status} ${response.statusText}`, "IMAGE_FETCH_ERROR", "bedrock");
593
+ const arrayBuffer = await response.arrayBuffer();
594
+ return {
595
+ bytes: new Uint8Array(arrayBuffer),
596
+ mimeType: response.headers.get("content-type") || "image/png"
597
+ };
598
+ }
599
+ mimeTypeToBedrockImageFormat(mimeType) {
600
+ if (mimeType.includes("png")) return "png";
601
+ if (mimeType.includes("jpeg") || mimeType.includes("jpg")) return "jpeg";
602
+ if (mimeType.includes("gif")) return "gif";
603
+ if (mimeType.includes("webp")) return "webp";
604
+ throw new AIError(`Unsupported image format for Bedrock: ${mimeType}`, "INVALID_INPUT", "bedrock");
605
+ }
606
+ resolveImageSize(options) {
607
+ if (options.size) {
608
+ const [width, height] = options.size.split("x").map(Number);
609
+ if (Number.isFinite(width) && Number.isFinite(height)) return {
610
+ width,
611
+ height
612
+ };
613
+ }
614
+ return {
615
+ "1:1": {
616
+ width: 1024,
617
+ height: 1024
618
+ },
619
+ "2:3": {
620
+ width: 768,
621
+ height: 1152
622
+ },
623
+ "3:2": {
624
+ width: 1152,
625
+ height: 768
626
+ },
627
+ "3:5": {
628
+ width: 768,
629
+ height: 1280
630
+ },
631
+ "5:3": {
632
+ width: 1280,
633
+ height: 768
634
+ },
635
+ "7:9": {
636
+ width: 896,
637
+ height: 1152
638
+ },
639
+ "9:7": {
640
+ width: 1152,
641
+ height: 896
642
+ },
643
+ "6:11": {
644
+ width: 768,
645
+ height: 1408
646
+ },
647
+ "11:6": {
648
+ width: 1408,
649
+ height: 768
650
+ },
651
+ "5:11": {
652
+ width: 640,
653
+ height: 1408
654
+ },
655
+ "11:5": {
656
+ width: 1408,
657
+ height: 640
658
+ },
659
+ "9:5": {
660
+ width: 1152,
661
+ height: 640
662
+ },
663
+ "16:9": {
664
+ width: 1173,
665
+ height: 640
666
+ }
667
+ }[options.aspectRatio || ""] || {
668
+ width: 1024,
669
+ height: 1024
670
+ };
671
+ }
672
+ mapImageQuality(quality) {
673
+ if (!quality || quality === "standard") return "standard";
674
+ if (quality === "hd") return "premium";
675
+ return quality;
676
+ }
677
+ safeJsonParse(input) {
678
+ try {
679
+ return JSON.parse(input);
680
+ } catch {
681
+ return { rawArguments: input };
682
+ }
683
+ }
684
+ mapError(error) {
685
+ if (error instanceof AIError) return error;
686
+ if (typeof error === "object" && error !== null) {
687
+ const awsError = error;
688
+ if (awsError.name === "AccessDeniedException") return new AuthenticationError("bedrock");
689
+ if (awsError.name === "ThrottlingException") return new RateLimitError("bedrock");
690
+ if (awsError.name === "ResourceNotFoundException") return new ModelNotFoundError(awsError.message || "Model not found", "bedrock");
691
+ if (awsError.name === "ValidationException" && awsError.message?.includes("input is too long")) return new ContextLengthError("bedrock");
692
+ }
693
+ return new AIError(error instanceof Error ? error.message : "Unknown Bedrock error occurred", "UNKNOWN_ERROR", "bedrock");
694
+ }
695
+ };
696
+ //#endregion
697
+ export { BedrockProvider };
698
+
699
+ //# sourceMappingURL=bedrock-DDiYFUw0.js.map