@happyvertical/ai 0.78.2 → 0.79.0
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/README.md +63 -5
- package/dist/chunks/{anthropic-BRwbhwIl.js → anthropic-2z-82zgr.js} +75 -8
- package/dist/chunks/anthropic-2z-82zgr.js.map +1 -0
- package/dist/chunks/{bedrock-Cf1xUerN.js → bedrock-Dc2eVPUD.js} +153 -41
- package/dist/chunks/bedrock-Dc2eVPUD.js.map +1 -0
- package/dist/chunks/{bifrost-3mXtQsTj.js → bifrost-CEnCsciy.js} +36 -11
- package/dist/chunks/bifrost-CEnCsciy.js.map +1 -0
- package/dist/chunks/{claude-cli-BrHRfkry.js → claude-cli-X1ONjE8K.js} +3 -3
- package/dist/chunks/{claude-cli-BrHRfkry.js.map → claude-cli-X1ONjE8K.js.map} +1 -1
- package/dist/chunks/{gateway-admin-C4GFPbZF.js → gateway-admin-BUhBzXZb.js} +2 -2
- package/dist/chunks/{gateway-admin-C4GFPbZF.js.map → gateway-admin-BUhBzXZb.js.map} +1 -1
- package/dist/chunks/{gemini-BfpHXDIQ.js → gemini-CS56gY0D.js} +138 -32
- package/dist/chunks/gemini-CS56gY0D.js.map +1 -0
- package/dist/chunks/{huggingface-280qv9iv.js → huggingface-wQSfO5xA.js} +64 -19
- package/dist/chunks/huggingface-wQSfO5xA.js.map +1 -0
- package/dist/chunks/{index-BT4thAvS.js → index-DCXO0nZA.js} +383 -24
- package/dist/chunks/index-DCXO0nZA.js.map +1 -0
- package/dist/chunks/{litellm-DhPKa_Jz.js → litellm-BMFTYbWc.js} +36 -11
- package/dist/chunks/litellm-BMFTYbWc.js.map +1 -0
- package/dist/chunks/{ollama-Di1ldur0.js → ollama-DsGDrA-c.js} +171 -60
- package/dist/chunks/ollama-DsGDrA-c.js.map +1 -0
- package/dist/chunks/{openai-5snI2diE.js → openai-CJEo69jb.js} +145 -12
- package/dist/chunks/openai-CJEo69jb.js.map +1 -0
- package/dist/chunks/{qwen-tts-DgPgdXxG.js → qwen-tts-BLYZ6d9s.js} +2 -2
- package/dist/chunks/{qwen-tts-DgPgdXxG.js.map → qwen-tts-BLYZ6d9s.js.map} +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -12
- package/dist/shared/factory.d.ts.map +1 -1
- package/dist/shared/providers/anthropic.d.ts.map +1 -1
- package/dist/shared/providers/bedrock.d.ts.map +1 -1
- package/dist/shared/providers/bifrost.d.ts.map +1 -1
- package/dist/shared/providers/gemini.d.ts +0 -5
- package/dist/shared/providers/gemini.d.ts.map +1 -1
- package/dist/shared/providers/huggingface.d.ts.map +1 -1
- package/dist/shared/providers/litellm.d.ts.map +1 -1
- package/dist/shared/providers/ollama.d.ts +0 -1
- package/dist/shared/providers/ollama.d.ts.map +1 -1
- package/dist/shared/providers/openai.d.ts +2 -2
- package/dist/shared/providers/openai.d.ts.map +1 -1
- package/dist/shared/safety.d.ts +55 -0
- package/dist/shared/safety.d.ts.map +1 -0
- package/dist/shared/types.d.ts +74 -6
- package/dist/shared/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/dist/chunks/anthropic-BRwbhwIl.js.map +0 -1
- package/dist/chunks/bedrock-Cf1xUerN.js.map +0 -1
- package/dist/chunks/bifrost-3mXtQsTj.js.map +0 -1
- package/dist/chunks/gemini-BfpHXDIQ.js.map +0 -1
- package/dist/chunks/huggingface-280qv9iv.js.map +0 -1
- package/dist/chunks/index-BT4thAvS.js.map +0 -1
- package/dist/chunks/litellm-DhPKa_Jz.js.map +0 -1
- package/dist/chunks/ollama-Di1ldur0.js.map +0 -1
- package/dist/chunks/openai-5snI2diE.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as AIError,
|
|
1
|
+
import { b as normalizeBaseAIOptions, A as AIError, n as normalizeChatOptions, p as prepareRequestControls, a as normalizeImageGenerationOptions, f as extractTextContent, d as AuthenticationError, R as RateLimitError, M as ModelNotFoundError, c as ContextLengthError } from "./index-DCXO0nZA.js";
|
|
2
2
|
import { e as emitUsage } from "./usage-DMWiJ2oB.js";
|
|
3
3
|
const BEDROCK_DEFAULT_CHAT_MODEL = "anthropic.claude-3-5-sonnet-20241022-v2:0";
|
|
4
4
|
const BEDROCK_TEXT_EMBEDDING_MODEL = "amazon.titan-embed-text-v2:0";
|
|
@@ -9,10 +9,10 @@ class BedrockProvider {
|
|
|
9
9
|
client;
|
|
10
10
|
// Will be BedrockRuntimeClient instance from @aws-sdk/client-bedrock-runtime
|
|
11
11
|
constructor(options) {
|
|
12
|
-
this.options = {
|
|
12
|
+
this.options = normalizeBaseAIOptions({
|
|
13
13
|
defaultModel: BEDROCK_DEFAULT_CHAT_MODEL,
|
|
14
14
|
...options
|
|
15
|
-
};
|
|
15
|
+
});
|
|
16
16
|
this.initializeClientSync();
|
|
17
17
|
}
|
|
18
18
|
initializeClientSync() {
|
|
@@ -21,7 +21,8 @@ class BedrockProvider {
|
|
|
21
21
|
this.client = new BedrockRuntimeClient({
|
|
22
22
|
region: this.options.region,
|
|
23
23
|
credentials: this.options.credentials,
|
|
24
|
-
endpoint: this.options.endpoint
|
|
24
|
+
endpoint: this.options.endpoint,
|
|
25
|
+
maxAttempts: (this.options.maxRetries || 0) + 1
|
|
25
26
|
});
|
|
26
27
|
}).catch(() => {
|
|
27
28
|
});
|
|
@@ -35,7 +36,8 @@ class BedrockProvider {
|
|
|
35
36
|
this.client = new BedrockRuntimeClient({
|
|
36
37
|
region: this.options.region,
|
|
37
38
|
credentials: this.options.credentials,
|
|
38
|
-
endpoint: this.options.endpoint
|
|
39
|
+
endpoint: this.options.endpoint,
|
|
40
|
+
maxAttempts: (this.options.maxRetries || 0) + 1
|
|
39
41
|
});
|
|
40
42
|
} catch (_error) {
|
|
41
43
|
throw new AIError(
|
|
@@ -48,12 +50,21 @@ class BedrockProvider {
|
|
|
48
50
|
}
|
|
49
51
|
async chat(messages, options = {}) {
|
|
50
52
|
const startTime = Date.now();
|
|
53
|
+
let controls;
|
|
51
54
|
try {
|
|
52
55
|
await this.ensureClient();
|
|
53
56
|
const modelId = options.model || this.options.defaultModel;
|
|
57
|
+
options = normalizeChatOptions(this.options, options, "bedrock", modelId);
|
|
58
|
+
controls = prepareRequestControls(this.options, options);
|
|
54
59
|
const response = this.mapConverseResponse(
|
|
55
60
|
await this.client.converse(
|
|
56
|
-
await this.buildConverseRequest(
|
|
61
|
+
await this.buildConverseRequest(
|
|
62
|
+
messages,
|
|
63
|
+
options,
|
|
64
|
+
modelId,
|
|
65
|
+
controls.signal
|
|
66
|
+
),
|
|
67
|
+
{ abortSignal: controls.signal }
|
|
57
68
|
),
|
|
58
69
|
modelId
|
|
59
70
|
);
|
|
@@ -68,7 +79,25 @@ class BedrockProvider {
|
|
|
68
79
|
);
|
|
69
80
|
return response;
|
|
70
81
|
} catch (error) {
|
|
82
|
+
if (controls?.didTimeout()) {
|
|
83
|
+
throw new AIError(
|
|
84
|
+
`AI request timed out after ${controls.timeout}ms`,
|
|
85
|
+
"AI_TIMEOUT",
|
|
86
|
+
"bedrock",
|
|
87
|
+
options.model
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
if (options.signal?.aborted) {
|
|
91
|
+
throw new AIError(
|
|
92
|
+
"AI request aborted by caller",
|
|
93
|
+
"AI_ABORTED",
|
|
94
|
+
"bedrock",
|
|
95
|
+
options.model
|
|
96
|
+
);
|
|
97
|
+
}
|
|
71
98
|
throw this.mapError(error);
|
|
99
|
+
} finally {
|
|
100
|
+
controls?.cleanup();
|
|
72
101
|
}
|
|
73
102
|
}
|
|
74
103
|
async complete(prompt, options = {}) {
|
|
@@ -81,6 +110,9 @@ class BedrockProvider {
|
|
|
81
110
|
stop: options.stop,
|
|
82
111
|
stream: options.stream,
|
|
83
112
|
onProgress: options.onProgress,
|
|
113
|
+
signal: options.signal,
|
|
114
|
+
timeout: options.timeout,
|
|
115
|
+
reasoning: options.reasoning,
|
|
84
116
|
usageTags: options.usageTags
|
|
85
117
|
});
|
|
86
118
|
}
|
|
@@ -110,6 +142,9 @@ class BedrockProvider {
|
|
|
110
142
|
tools: options.tools,
|
|
111
143
|
toolChoice: options.toolChoice,
|
|
112
144
|
onProgress: options.onProgress,
|
|
145
|
+
signal: options.signal,
|
|
146
|
+
timeout: options.timeout,
|
|
147
|
+
reasoning: options.reasoning,
|
|
113
148
|
usageTags: options.usageTags
|
|
114
149
|
});
|
|
115
150
|
return response.content;
|
|
@@ -200,7 +235,7 @@ class BedrockProvider {
|
|
|
200
235
|
}
|
|
201
236
|
}
|
|
202
237
|
async describeImage(image, prompt, options = {}) {
|
|
203
|
-
const imageUrl = await this.imageToDataUrl(image);
|
|
238
|
+
const imageUrl = await this.imageToDataUrl(image, options.signal);
|
|
204
239
|
const response = await this.chat(
|
|
205
240
|
[
|
|
206
241
|
{
|
|
@@ -219,35 +254,53 @@ class BedrockProvider {
|
|
|
219
254
|
],
|
|
220
255
|
{
|
|
221
256
|
model: options.model || this.options.defaultModel,
|
|
222
|
-
maxTokens: options.maxTokens
|
|
257
|
+
maxTokens: options.maxTokens ?? 500,
|
|
258
|
+
signal: options.signal,
|
|
259
|
+
timeout: options.timeout,
|
|
260
|
+
reasoning: options.reasoning,
|
|
261
|
+
usageTags: options.usageTags
|
|
223
262
|
}
|
|
224
263
|
);
|
|
225
264
|
return response.content;
|
|
226
265
|
}
|
|
227
266
|
async generateImage(prompt, options = {}) {
|
|
267
|
+
let controls;
|
|
228
268
|
try {
|
|
229
269
|
await this.ensureClient();
|
|
230
270
|
const model = options.model || BEDROCK_IMAGE_GENERATION_MODEL;
|
|
271
|
+
options = normalizeImageGenerationOptions(
|
|
272
|
+
this.options,
|
|
273
|
+
options,
|
|
274
|
+
"bedrock",
|
|
275
|
+
model
|
|
276
|
+
);
|
|
277
|
+
controls = prepareRequestControls(this.options, options);
|
|
231
278
|
const size = this.resolveImageSize(options);
|
|
232
|
-
const response = await this.client.invokeModel(
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
279
|
+
const response = await this.client.invokeModel(
|
|
280
|
+
{
|
|
281
|
+
modelId: model,
|
|
282
|
+
contentType: "application/json",
|
|
283
|
+
accept: "application/json",
|
|
284
|
+
body: JSON.stringify({
|
|
285
|
+
taskType: "TEXT_IMAGE",
|
|
286
|
+
textToImageParams: {
|
|
287
|
+
text: prompt,
|
|
288
|
+
...options.imageInput && {
|
|
289
|
+
conditionImage: await this.imageToBase64(
|
|
290
|
+
options.imageInput,
|
|
291
|
+
controls.signal
|
|
292
|
+
)
|
|
293
|
+
}
|
|
294
|
+
},
|
|
295
|
+
imageGenerationConfig: {
|
|
296
|
+
numberOfImages: options.n,
|
|
297
|
+
quality: this.mapImageQuality(options.quality),
|
|
298
|
+
...size
|
|
242
299
|
}
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
...size
|
|
248
|
-
}
|
|
249
|
-
})
|
|
250
|
-
});
|
|
300
|
+
})
|
|
301
|
+
},
|
|
302
|
+
{ abortSignal: controls.signal }
|
|
303
|
+
);
|
|
251
304
|
const payload = await this.parseInvokeModelBody(response.body);
|
|
252
305
|
if (payload.error) {
|
|
253
306
|
throw new AIError(payload.error, "API_ERROR", "bedrock");
|
|
@@ -270,16 +323,43 @@ class BedrockProvider {
|
|
|
270
323
|
model
|
|
271
324
|
};
|
|
272
325
|
} catch (error) {
|
|
326
|
+
if (controls?.didTimeout()) {
|
|
327
|
+
throw new AIError(
|
|
328
|
+
`AI request timed out after ${controls.timeout}ms`,
|
|
329
|
+
"AI_TIMEOUT",
|
|
330
|
+
"bedrock",
|
|
331
|
+
options.model
|
|
332
|
+
);
|
|
333
|
+
}
|
|
334
|
+
if (options.signal?.aborted) {
|
|
335
|
+
throw new AIError(
|
|
336
|
+
"AI request aborted by caller",
|
|
337
|
+
"AI_ABORTED",
|
|
338
|
+
"bedrock",
|
|
339
|
+
options.model
|
|
340
|
+
);
|
|
341
|
+
}
|
|
273
342
|
throw this.mapError(error);
|
|
343
|
+
} finally {
|
|
344
|
+
controls?.cleanup();
|
|
274
345
|
}
|
|
275
346
|
}
|
|
276
347
|
async *stream(messages, options = {}) {
|
|
277
348
|
const startTime = Date.now();
|
|
349
|
+
let controls;
|
|
278
350
|
try {
|
|
279
351
|
await this.ensureClient();
|
|
280
352
|
const modelId = options.model || this.options.defaultModel;
|
|
353
|
+
options = normalizeChatOptions(this.options, options, "bedrock", modelId);
|
|
354
|
+
controls = prepareRequestControls(this.options, options);
|
|
281
355
|
const response = await this.client.converseStream(
|
|
282
|
-
await this.buildConverseRequest(
|
|
356
|
+
await this.buildConverseRequest(
|
|
357
|
+
messages,
|
|
358
|
+
options,
|
|
359
|
+
modelId,
|
|
360
|
+
controls.signal
|
|
361
|
+
),
|
|
362
|
+
{ abortSignal: controls.signal }
|
|
283
363
|
);
|
|
284
364
|
let usage;
|
|
285
365
|
for await (const event of response.stream || []) {
|
|
@@ -308,7 +388,25 @@ class BedrockProvider {
|
|
|
308
388
|
options.usageTags
|
|
309
389
|
);
|
|
310
390
|
} catch (error) {
|
|
391
|
+
if (controls?.didTimeout()) {
|
|
392
|
+
throw new AIError(
|
|
393
|
+
`AI request timed out after ${controls.timeout}ms`,
|
|
394
|
+
"AI_TIMEOUT",
|
|
395
|
+
"bedrock",
|
|
396
|
+
options.model
|
|
397
|
+
);
|
|
398
|
+
}
|
|
399
|
+
if (options.signal?.aborted) {
|
|
400
|
+
throw new AIError(
|
|
401
|
+
"AI request aborted by caller",
|
|
402
|
+
"AI_ABORTED",
|
|
403
|
+
"bedrock",
|
|
404
|
+
options.model
|
|
405
|
+
);
|
|
406
|
+
}
|
|
311
407
|
throw this.mapError(error);
|
|
408
|
+
} finally {
|
|
409
|
+
controls?.cleanup();
|
|
312
410
|
}
|
|
313
411
|
}
|
|
314
412
|
async countTokens(text) {
|
|
@@ -495,15 +593,18 @@ class BedrockProvider {
|
|
|
495
593
|
"bedrock"
|
|
496
594
|
);
|
|
497
595
|
}
|
|
498
|
-
async buildConverseRequest(messages, options, modelId) {
|
|
499
|
-
const { system, bedrockMessages } = await this.mapMessagesToBedrock(
|
|
596
|
+
async buildConverseRequest(messages, options, modelId, signal) {
|
|
597
|
+
const { system, bedrockMessages } = await this.mapMessagesToBedrock(
|
|
598
|
+
messages,
|
|
599
|
+
signal
|
|
600
|
+
);
|
|
500
601
|
const systemPrompt = options.responseFormat?.type === "json_object" ? [
|
|
501
602
|
system,
|
|
502
603
|
"Respond with valid JSON only. Do not include explanatory text outside the JSON object."
|
|
503
604
|
].filter(Boolean).join("\n\n") : system;
|
|
504
605
|
const inferenceConfig = Object.fromEntries(
|
|
505
606
|
Object.entries({
|
|
506
|
-
maxTokens: options.maxTokens
|
|
607
|
+
maxTokens: options.maxTokens,
|
|
507
608
|
temperature: options.temperature,
|
|
508
609
|
topP: options.topP,
|
|
509
610
|
stopSequences: Array.isArray(options.stop) ? options.stop : options.stop ? [options.stop] : void 0
|
|
@@ -515,13 +616,21 @@ class BedrockProvider {
|
|
|
515
616
|
...Object.keys(inferenceConfig).length > 0 && { inferenceConfig },
|
|
516
617
|
...systemPrompt && { system: [{ text: systemPrompt }] }
|
|
517
618
|
};
|
|
619
|
+
if ((options.reasoning?.maxTokens || 0) > 0) {
|
|
620
|
+
request.additionalModelRequestFields = {
|
|
621
|
+
thinking: {
|
|
622
|
+
type: "enabled",
|
|
623
|
+
budget_tokens: options.reasoning?.maxTokens
|
|
624
|
+
}
|
|
625
|
+
};
|
|
626
|
+
}
|
|
518
627
|
const toolConfig = this.mapToolConfig(options);
|
|
519
628
|
if (toolConfig) {
|
|
520
629
|
request.toolConfig = toolConfig;
|
|
521
630
|
}
|
|
522
631
|
return request;
|
|
523
632
|
}
|
|
524
|
-
async mapMessagesToBedrock(messages) {
|
|
633
|
+
async mapMessagesToBedrock(messages, signal) {
|
|
525
634
|
let system;
|
|
526
635
|
const bedrockMessages = [];
|
|
527
636
|
for (const message of messages) {
|
|
@@ -541,7 +650,10 @@ ${textContent}` : textContent;
|
|
|
541
650
|
content.push({ text: part.text });
|
|
542
651
|
continue;
|
|
543
652
|
}
|
|
544
|
-
const image = await this.imageUrlToBedrockImage(
|
|
653
|
+
const image = await this.imageUrlToBedrockImage(
|
|
654
|
+
part.image_url.url,
|
|
655
|
+
signal
|
|
656
|
+
);
|
|
545
657
|
content.push({ image });
|
|
546
658
|
}
|
|
547
659
|
}
|
|
@@ -658,24 +770,24 @@ ${textContent}` : textContent;
|
|
|
658
770
|
}
|
|
659
771
|
return void 0;
|
|
660
772
|
}
|
|
661
|
-
async imageUrlToBedrockImage(imageUrl) {
|
|
662
|
-
const { bytes, mimeType } = await this.imageToBytes(imageUrl);
|
|
773
|
+
async imageUrlToBedrockImage(imageUrl, signal) {
|
|
774
|
+
const { bytes, mimeType } = await this.imageToBytes(imageUrl, signal);
|
|
663
775
|
return {
|
|
664
776
|
format: this.mimeTypeToBedrockImageFormat(mimeType),
|
|
665
777
|
source: { bytes }
|
|
666
778
|
};
|
|
667
779
|
}
|
|
668
|
-
async imageToDataUrl(image) {
|
|
780
|
+
async imageToDataUrl(image, signal) {
|
|
669
781
|
if (Buffer.isBuffer(image)) {
|
|
670
782
|
return `data:image/png;base64,${image.toString("base64")}`;
|
|
671
783
|
}
|
|
672
784
|
if (image.startsWith("data:")) {
|
|
673
785
|
return image;
|
|
674
786
|
}
|
|
675
|
-
const { bytes, mimeType } = await this.imageToBytes(image);
|
|
787
|
+
const { bytes, mimeType } = await this.imageToBytes(image, signal);
|
|
676
788
|
return `data:${mimeType};base64,${Buffer.from(bytes).toString("base64")}`;
|
|
677
789
|
}
|
|
678
|
-
async imageToBase64(image) {
|
|
790
|
+
async imageToBase64(image, signal) {
|
|
679
791
|
if (Buffer.isBuffer(image)) {
|
|
680
792
|
return image.toString("base64");
|
|
681
793
|
}
|
|
@@ -690,10 +802,10 @@ ${textContent}` : textContent;
|
|
|
690
802
|
}
|
|
691
803
|
return match[2];
|
|
692
804
|
}
|
|
693
|
-
const { bytes } = await this.imageToBytes(image);
|
|
805
|
+
const { bytes } = await this.imageToBytes(image, signal);
|
|
694
806
|
return Buffer.from(bytes).toString("base64");
|
|
695
807
|
}
|
|
696
|
-
async imageToBytes(image) {
|
|
808
|
+
async imageToBytes(image, signal) {
|
|
697
809
|
if (image.startsWith("data:")) {
|
|
698
810
|
const match = image.match(/^data:([^;]+);base64,(.+)$/);
|
|
699
811
|
if (!match) {
|
|
@@ -708,7 +820,7 @@ ${textContent}` : textContent;
|
|
|
708
820
|
mimeType: match[1]
|
|
709
821
|
};
|
|
710
822
|
}
|
|
711
|
-
const response = await fetch(image);
|
|
823
|
+
const response = await fetch(image, { signal });
|
|
712
824
|
if (!response.ok) {
|
|
713
825
|
throw new AIError(
|
|
714
826
|
`Failed to fetch image: ${response.status} ${response.statusText}`,
|
|
@@ -805,4 +917,4 @@ ${textContent}` : textContent;
|
|
|
805
917
|
export {
|
|
806
918
|
BedrockProvider
|
|
807
919
|
};
|
|
808
|
-
//# sourceMappingURL=bedrock-
|
|
920
|
+
//# sourceMappingURL=bedrock-Dc2eVPUD.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bedrock-Dc2eVPUD.js","sources":["../../src/shared/providers/bedrock.ts"],"sourcesContent":["/**\n * AWS Bedrock provider implementation\n */\n\nimport {\n normalizeBaseAIOptions,\n normalizeChatOptions,\n normalizeImageGenerationOptions,\n type PreparedRequestControls,\n prepareRequestControls,\n} from '../safety';\nimport type {\n AICapabilities,\n AIInterface,\n AIMessage,\n AIModel,\n AIResponse,\n BedrockOptions,\n ChatOptions,\n CompletionOptions,\n EmbeddingOptions,\n EmbeddingResponse,\n ImageDescriptionOptions,\n ImageEmbeddingOptions,\n ImageGenerationOptions,\n ImageGenerationResponse,\n MessageOptions,\n TokenUsage,\n TTSOptions,\n TTSResponse,\n Voice,\n VoiceCloneOptions,\n VoiceDesignOptions,\n VoiceListOptions,\n} from '../types';\nimport {\n AIError,\n AuthenticationError,\n ContextLengthError,\n extractTextContent,\n ModelNotFoundError,\n RateLimitError,\n} from '../types';\nimport { emitUsage } from './usage';\n\nconst BEDROCK_DEFAULT_CHAT_MODEL = 'anthropic.claude-3-5-sonnet-20241022-v2:0';\nconst BEDROCK_TEXT_EMBEDDING_MODEL = 'amazon.titan-embed-text-v2:0';\nconst BEDROCK_IMAGE_EMBEDDING_MODEL = 'amazon.titan-embed-image-v1';\nconst BEDROCK_IMAGE_GENERATION_MODEL = 'amazon.titan-image-generator-v2:0';\n\nexport class BedrockProvider implements AIInterface {\n private options: BedrockOptions;\n private client: any; // Will be BedrockRuntimeClient instance from @aws-sdk/client-bedrock-runtime\n\n constructor(options: BedrockOptions) {\n this.options = normalizeBaseAIOptions({\n defaultModel: BEDROCK_DEFAULT_CHAT_MODEL,\n ...options,\n });\n\n // Initialize AWS Bedrock client\n this.initializeClientSync();\n }\n\n private initializeClientSync() {\n try {\n // Dynamic import in constructor - this will work if the package is installed\n import('@aws-sdk/client-bedrock-runtime')\n .then(({ BedrockRuntimeClient }) => {\n this.client = new BedrockRuntimeClient({\n region: this.options.region,\n credentials: this.options.credentials,\n endpoint: this.options.endpoint,\n maxAttempts: (this.options.maxRetries || 0) + 1,\n });\n })\n .catch(() => {\n // Client will be null and we'll handle it in methods\n });\n } catch (_error) {\n // Client will be null and we'll handle it in methods\n }\n }\n\n private async ensureClient() {\n if (!this.client) {\n try {\n const { BedrockRuntimeClient } = await import(\n '@aws-sdk/client-bedrock-runtime'\n );\n this.client = new BedrockRuntimeClient({\n region: this.options.region,\n credentials: this.options.credentials,\n endpoint: this.options.endpoint,\n maxAttempts: (this.options.maxRetries || 0) + 1,\n });\n } catch (_error) {\n throw new AIError(\n 'Failed to initialize Bedrock client. Make sure @aws-sdk/client-bedrock-runtime is installed.',\n 'INITIALIZATION_ERROR',\n 'bedrock',\n );\n }\n }\n }\n\n async chat(\n messages: AIMessage[],\n options: ChatOptions = {},\n ): Promise<AIResponse> {\n const startTime = Date.now();\n let controls: PreparedRequestControls | undefined;\n try {\n await this.ensureClient();\n\n const modelId = options.model || this.options.defaultModel;\n options = normalizeChatOptions(this.options, options, 'bedrock', modelId);\n controls = prepareRequestControls(this.options, options);\n const response = this.mapConverseResponse(\n await this.client.converse(\n await this.buildConverseRequest(\n messages,\n options,\n modelId!,\n controls.signal,\n ),\n { abortSignal: controls.signal },\n ),\n modelId!,\n );\n\n emitUsage(\n this.options,\n 'bedrock',\n 'chat',\n response.model || modelId || 'unknown',\n response.usage,\n startTime,\n options.usageTags,\n );\n return response;\n } catch (error) {\n if (controls?.didTimeout()) {\n throw new AIError(\n `AI request timed out after ${controls.timeout}ms`,\n 'AI_TIMEOUT',\n 'bedrock',\n options.model,\n );\n }\n if (options.signal?.aborted) {\n throw new AIError(\n 'AI request aborted by caller',\n 'AI_ABORTED',\n 'bedrock',\n options.model,\n );\n }\n throw this.mapError(error);\n } finally {\n controls?.cleanup();\n }\n }\n\n async complete(\n prompt: string,\n options: CompletionOptions = {},\n ): Promise<AIResponse> {\n return this.chat([{ role: 'user', content: prompt }], {\n model: options.model,\n maxTokens: options.maxTokens,\n temperature: options.temperature,\n topP: options.topP,\n n: options.n,\n stop: options.stop,\n stream: options.stream,\n onProgress: options.onProgress,\n signal: options.signal,\n timeout: options.timeout,\n reasoning: options.reasoning,\n usageTags: options.usageTags,\n });\n }\n\n /**\n * Simple message interface for single-turn interactions with optional history\n *\n * @param text - The message text to send\n * @param options - Configuration options including history, model, etc.\n * @returns Promise resolving to the response content string\n */\n async message(text: string, options: MessageOptions = {}): Promise<string> {\n // Build messages array from history + current message\n const messages: AIMessage[] = [\n ...(options.history || []),\n { role: options.role || 'user', content: text },\n ];\n\n const response = await this.chat(messages, {\n model: options.model,\n maxTokens: options.maxTokens,\n temperature: options.temperature,\n topP: options.topP,\n stop: options.stop,\n stream: options.stream,\n frequencyPenalty: options.frequencyPenalty,\n presencePenalty: options.presencePenalty,\n responseFormat: options.responseFormat,\n seed: options.seed,\n tools: options.tools,\n toolChoice: options.toolChoice,\n onProgress: options.onProgress,\n signal: options.signal,\n timeout: options.timeout,\n reasoning: options.reasoning,\n usageTags: options.usageTags,\n });\n\n return response.content;\n }\n\n async embed(\n text: string | string[],\n options: EmbeddingOptions = {},\n ): Promise<EmbeddingResponse> {\n const startTime = Date.now();\n try {\n await this.ensureClient();\n\n const model = options.model || BEDROCK_TEXT_EMBEDDING_MODEL;\n const inputs = Array.isArray(text) ? text : [text];\n const embeddings: number[][] = [];\n let totalTokens = 0;\n\n for (const inputText of inputs) {\n const response = await this.client.invokeModel({\n modelId: model,\n contentType: 'application/json',\n accept: 'application/json',\n body: JSON.stringify({\n inputText,\n ...(options.dimensions && { dimensions: options.dimensions }),\n normalize: true,\n }),\n });\n\n const payload = await this.parseInvokeModelBody(response.body);\n const embedding = this.extractEmbeddingVector(payload);\n if (embedding) {\n embeddings.push(embedding);\n }\n\n totalTokens +=\n payload.inputTextTokenCount ||\n payload.inputTokenCount ||\n payload.tokenCount ||\n 0;\n }\n\n const usage: TokenUsage | undefined =\n totalTokens > 0\n ? {\n promptTokens: totalTokens,\n completionTokens: 0,\n totalTokens,\n }\n : undefined;\n\n emitUsage(\n this.options,\n 'bedrock',\n 'embed',\n model,\n usage,\n startTime,\n options.usageTags,\n );\n\n return {\n embeddings,\n model,\n usage,\n };\n } catch (error) {\n throw this.mapError(error);\n }\n }\n\n async embedImage(\n image: string | Buffer,\n options: ImageEmbeddingOptions = {},\n ): Promise<EmbeddingResponse> {\n const startTime = Date.now();\n try {\n await this.ensureClient();\n\n const model = options.model || BEDROCK_IMAGE_EMBEDDING_MODEL;\n const response = await this.client.invokeModel({\n modelId: model,\n contentType: 'application/json',\n accept: 'application/json',\n body: JSON.stringify({\n inputImage: await this.imageToBase64(image),\n ...(options.dimensions && {\n embeddingConfig: {\n outputEmbeddingLength: options.dimensions,\n },\n }),\n }),\n });\n\n const payload = await this.parseInvokeModelBody(response.body);\n const embedding = this.extractEmbeddingVector(payload);\n\n emitUsage(\n this.options,\n 'bedrock',\n 'embedImage',\n model,\n undefined,\n startTime,\n );\n\n return {\n embeddings: embedding ? [embedding] : [],\n model,\n };\n } catch (error) {\n throw this.mapError(error);\n }\n }\n\n async describeImage(\n image: string | Buffer,\n prompt?: string,\n options: ImageDescriptionOptions = {},\n ): Promise<string> {\n const imageUrl = await this.imageToDataUrl(image, options.signal);\n const response = await this.chat(\n [\n {\n role: 'user',\n content: [\n {\n type: 'text',\n text:\n prompt ||\n 'Describe this image for a search index. Include objects, mood, lighting, and any visible text.',\n },\n {\n type: 'image_url',\n image_url: { url: imageUrl },\n },\n ],\n },\n ],\n {\n model: options.model || this.options.defaultModel,\n maxTokens: options.maxTokens ?? 500,\n signal: options.signal,\n timeout: options.timeout,\n reasoning: options.reasoning,\n usageTags: options.usageTags,\n },\n );\n\n return response.content;\n }\n\n async generateImage(\n prompt: string,\n options: ImageGenerationOptions = {},\n ): Promise<ImageGenerationResponse> {\n let controls: PreparedRequestControls | undefined;\n try {\n await this.ensureClient();\n\n const model = options.model || BEDROCK_IMAGE_GENERATION_MODEL;\n options = normalizeImageGenerationOptions(\n this.options,\n options,\n 'bedrock',\n model,\n );\n controls = prepareRequestControls(this.options, options);\n const size = this.resolveImageSize(options);\n const response = await this.client.invokeModel(\n {\n modelId: model,\n contentType: 'application/json',\n accept: 'application/json',\n body: JSON.stringify({\n taskType: 'TEXT_IMAGE',\n textToImageParams: {\n text: prompt,\n ...(options.imageInput && {\n conditionImage: await this.imageToBase64(\n options.imageInput,\n controls.signal,\n ),\n }),\n },\n imageGenerationConfig: {\n numberOfImages: options.n,\n quality: this.mapImageQuality(options.quality),\n ...size,\n },\n }),\n },\n { abortSignal: controls.signal },\n );\n\n const payload = await this.parseInvokeModelBody(response.body);\n if (payload.error) {\n throw new AIError(payload.error, 'API_ERROR', 'bedrock');\n }\n\n const images = (payload.images || []).map((encoded: string) => {\n const mimeType = 'image/png';\n if (options.outputFormat === 'base64') {\n return { data: encoded, mimeType };\n }\n if (options.outputFormat === 'url') {\n return { data: `data:${mimeType};base64,${encoded}`, mimeType };\n }\n return {\n data: Buffer.from(encoded, 'base64'),\n mimeType,\n };\n });\n\n return {\n images,\n model,\n };\n } catch (error) {\n if (controls?.didTimeout()) {\n throw new AIError(\n `AI request timed out after ${controls.timeout}ms`,\n 'AI_TIMEOUT',\n 'bedrock',\n options.model,\n );\n }\n if (options.signal?.aborted) {\n throw new AIError(\n 'AI request aborted by caller',\n 'AI_ABORTED',\n 'bedrock',\n options.model,\n );\n }\n throw this.mapError(error);\n } finally {\n controls?.cleanup();\n }\n }\n\n async *stream(\n messages: AIMessage[],\n options: ChatOptions = {},\n ): AsyncIterable<string> {\n const startTime = Date.now();\n let controls: PreparedRequestControls | undefined;\n try {\n await this.ensureClient();\n\n const modelId = options.model || this.options.defaultModel;\n options = normalizeChatOptions(this.options, options, 'bedrock', modelId);\n controls = prepareRequestControls(this.options, options);\n const response = await this.client.converseStream(\n await this.buildConverseRequest(\n messages,\n options,\n modelId!,\n controls.signal,\n ),\n { abortSignal: controls.signal },\n );\n\n let usage: TokenUsage | undefined;\n\n for await (const event of response.stream || []) {\n const text = event.contentBlockDelta?.delta?.text;\n if (text) {\n if (options.onProgress) {\n options.onProgress(text);\n }\n yield text;\n }\n\n if (event.metadata?.usage) {\n usage = {\n promptTokens: event.metadata.usage.inputTokens || 0,\n completionTokens: event.metadata.usage.outputTokens || 0,\n totalTokens: event.metadata.usage.totalTokens || 0,\n };\n }\n }\n\n emitUsage(\n this.options,\n 'bedrock',\n 'stream',\n modelId || 'unknown',\n usage,\n startTime,\n options.usageTags,\n );\n } catch (error) {\n if (controls?.didTimeout()) {\n throw new AIError(\n `AI request timed out after ${controls.timeout}ms`,\n 'AI_TIMEOUT',\n 'bedrock',\n options.model,\n );\n }\n if (options.signal?.aborted) {\n throw new AIError(\n 'AI request aborted by caller',\n 'AI_ABORTED',\n 'bedrock',\n options.model,\n );\n }\n throw this.mapError(error);\n } finally {\n controls?.cleanup();\n }\n }\n\n async countTokens(text: string): Promise<number> {\n try {\n await this.ensureClient();\n\n const modelId = this.options.defaultModel || BEDROCK_DEFAULT_CHAT_MODEL;\n const response = await this.client.countTokens({\n modelId,\n input: {\n converse: {\n messages: [\n {\n role: 'user',\n content: [{ text }],\n },\n ],\n },\n },\n });\n\n return response.inputTokens || Math.ceil(text.length / 4);\n } catch (error) {\n throw this.mapError(error);\n }\n }\n\n async getModels(): Promise<AIModel[]> {\n // Return static list of popular Bedrock models\n return [\n // Anthropic Claude models\n {\n id: 'anthropic.claude-3-5-sonnet-20241022-v2:0',\n name: 'Claude 3.5 Sonnet v2',\n description: 'Latest Claude 3.5 Sonnet model on Bedrock',\n contextLength: 200000,\n capabilities: ['text', 'chat', 'vision', 'functions'],\n supportsFunctions: true,\n supportsVision: true,\n },\n {\n id: 'anthropic.claude-3-opus-20240229-v1:0',\n name: 'Claude 3 Opus',\n description: 'Most powerful Claude model on Bedrock',\n contextLength: 200000,\n capabilities: ['text', 'chat', 'vision'],\n supportsFunctions: false,\n supportsVision: true,\n },\n // Amazon Titan models\n {\n id: 'amazon.titan-text-premier-v1:0',\n name: 'Titan Text Premier',\n description: 'Premier Amazon Titan text model',\n contextLength: 32000,\n capabilities: ['text', 'chat'],\n supportsFunctions: false,\n supportsVision: false,\n },\n {\n id: 'amazon.titan-embed-text-v1',\n name: 'Titan Embeddings Text',\n description: 'Amazon Titan text embeddings model',\n contextLength: 8192,\n capabilities: ['embeddings'],\n supportsFunctions: false,\n supportsVision: false,\n },\n {\n id: BEDROCK_TEXT_EMBEDDING_MODEL,\n name: 'Titan Embeddings Text V2',\n description: 'Amazon Titan text embeddings v2 model',\n contextLength: 8192,\n capabilities: ['embeddings'],\n supportsFunctions: false,\n supportsVision: false,\n },\n {\n id: BEDROCK_IMAGE_EMBEDDING_MODEL,\n name: 'Titan Multimodal Embeddings G1',\n description:\n 'Amazon Titan multimodal embeddings model for image similarity',\n contextLength: 256,\n capabilities: ['embeddings', 'image_embedding'],\n supportsFunctions: false,\n supportsVision: false,\n },\n {\n id: BEDROCK_IMAGE_GENERATION_MODEL,\n name: 'Titan Image Generator V2',\n description: 'Amazon Titan image generation model',\n contextLength: 0,\n capabilities: ['image_generation'],\n supportsFunctions: false,\n supportsVision: false,\n },\n // Cohere models\n {\n id: 'cohere.command-r-plus-v1:0',\n name: 'Command R+',\n description: 'Cohere Command R+ model with advanced capabilities',\n contextLength: 128000,\n capabilities: ['text', 'chat', 'functions'],\n supportsFunctions: true,\n supportsVision: false,\n },\n // Meta Llama models\n {\n id: 'meta.llama3-1-405b-instruct-v1:0',\n name: 'Llama 3.1 405B Instruct',\n description: 'Meta Llama 3.1 405B instruction-tuned model',\n contextLength: 128000,\n capabilities: ['text', 'chat'],\n supportsFunctions: false,\n supportsVision: false,\n },\n ];\n }\n\n async getCapabilities(): Promise<AICapabilities> {\n return {\n chat: true,\n completion: true,\n embeddings: true,\n streaming: true,\n functions: true, // Some models support function calling\n vision: true, // Some models support vision\n fineTuning: true, // Via Bedrock fine-tuning\n imageEmbeddings: true,\n imageGeneration: true,\n tts: false,\n voiceCloning: false,\n voiceDesign: false,\n maxContextLength: 200000,\n supportedOperations: [\n 'chat',\n 'completion',\n 'embedding',\n 'streaming',\n 'functions',\n 'vision',\n 'image_embedding',\n 'image_generation',\n ],\n };\n }\n\n // ============================================================================\n // TTS Methods (Not supported - use Qwen3-TTS provider)\n // ============================================================================\n\n async synthesizeSpeech(\n _text: string,\n _options?: TTSOptions,\n ): Promise<TTSResponse> {\n throw new AIError(\n 'TTS is not supported by Bedrock provider. Use Qwen3-TTS provider.',\n 'NOT_IMPLEMENTED',\n 'bedrock',\n );\n }\n\n streamSpeech(_text: string, _options?: TTSOptions): AsyncIterable<Buffer> {\n const error = new AIError(\n 'TTS streaming is not supported by Bedrock provider. Use Qwen3-TTS provider.',\n 'NOT_IMPLEMENTED',\n 'bedrock',\n );\n return {\n [Symbol.asyncIterator]: () => ({\n next: () => Promise.reject(error),\n }),\n };\n }\n\n async cloneVoice(_options: VoiceCloneOptions): Promise<Voice> {\n throw new AIError(\n 'Voice cloning is not supported by Bedrock provider. Use Qwen3-TTS provider.',\n 'NOT_IMPLEMENTED',\n 'bedrock',\n );\n }\n\n async designVoice(_options: VoiceDesignOptions): Promise<Voice> {\n throw new AIError(\n 'Voice design is not supported by Bedrock provider. Use Qwen3-TTS provider.',\n 'NOT_IMPLEMENTED',\n 'bedrock',\n );\n }\n\n async getVoices(_options?: VoiceListOptions): Promise<Voice[]> {\n throw new AIError(\n 'Voice listing is not supported by Bedrock provider. Use Qwen3-TTS provider.',\n 'NOT_IMPLEMENTED',\n 'bedrock',\n );\n }\n\n private async buildConverseRequest(\n messages: AIMessage[],\n options: ChatOptions,\n modelId: string,\n signal?: AbortSignal,\n ): Promise<Record<string, any>> {\n const { system, bedrockMessages } = await this.mapMessagesToBedrock(\n messages,\n signal,\n );\n const systemPrompt =\n options.responseFormat?.type === 'json_object'\n ? [\n system,\n 'Respond with valid JSON only. Do not include explanatory text outside the JSON object.',\n ]\n .filter(Boolean)\n .join('\\n\\n')\n : system;\n\n const inferenceConfig = Object.fromEntries(\n Object.entries({\n maxTokens: options.maxTokens,\n temperature: options.temperature,\n topP: options.topP,\n stopSequences: Array.isArray(options.stop)\n ? options.stop\n : options.stop\n ? [options.stop]\n : undefined,\n }).filter(([, value]) => value !== undefined),\n );\n\n const request: Record<string, any> = {\n modelId,\n messages: bedrockMessages,\n ...(Object.keys(inferenceConfig).length > 0 && { inferenceConfig }),\n ...(systemPrompt && { system: [{ text: systemPrompt }] }),\n };\n if ((options.reasoning?.maxTokens || 0) > 0) {\n request.additionalModelRequestFields = {\n thinking: {\n type: 'enabled',\n budget_tokens: options.reasoning?.maxTokens,\n },\n };\n }\n\n const toolConfig = this.mapToolConfig(options);\n if (toolConfig) {\n request.toolConfig = toolConfig;\n }\n\n return request;\n }\n\n private async mapMessagesToBedrock(\n messages: AIMessage[],\n signal?: AbortSignal,\n ): Promise<{\n system?: string;\n bedrockMessages: Array<{ role: 'user' | 'assistant'; content: any[] }>;\n }> {\n let system: string | undefined;\n const bedrockMessages: Array<{\n role: 'user' | 'assistant';\n content: any[];\n }> = [];\n\n for (const message of messages) {\n const textContent = extractTextContent(message.content);\n if (message.role === 'system') {\n system = system ? `${system}\\n\\n${textContent}` : textContent;\n continue;\n }\n\n const content: any[] = [];\n if (typeof message.content === 'string') {\n content.push({ text: message.content });\n } else {\n for (const part of message.content) {\n if (part.type === 'text') {\n content.push({ text: part.text });\n continue;\n }\n\n const image = await this.imageUrlToBedrockImage(\n part.image_url.url,\n signal,\n );\n content.push({ image });\n }\n }\n\n if (message.role === 'assistant' && message.tool_calls) {\n for (const toolCall of message.tool_calls) {\n content.push({\n toolUse: {\n toolUseId: toolCall.id,\n name: toolCall.function.name,\n input: this.safeJsonParse(toolCall.function.arguments),\n },\n });\n }\n }\n\n if (content.length === 0 && textContent) {\n content.push({ text: textContent });\n }\n\n bedrockMessages.push({\n role: message.role === 'assistant' ? 'assistant' : 'user',\n content,\n });\n }\n\n return { system, bedrockMessages };\n }\n\n private mapConverseResponse(response: any, modelId: string): AIResponse {\n const contentBlocks = response.output?.message?.content || [];\n const textContent = contentBlocks\n .filter((block: any) => typeof block.text === 'string')\n .map((block: any) => block.text)\n .join('');\n\n const toolCalls = contentBlocks\n .filter((block: any) => block.toolUse)\n .map((block: any) => ({\n id: block.toolUse.toolUseId,\n type: 'function' as const,\n function: {\n name: block.toolUse.name,\n arguments: JSON.stringify(block.toolUse.input || {}),\n },\n }));\n\n const usage =\n response.usage &&\n ({\n promptTokens: response.usage.inputTokens || 0,\n completionTokens: response.usage.outputTokens || 0,\n totalTokens: response.usage.totalTokens || 0,\n } satisfies TokenUsage);\n\n return {\n content: textContent,\n model: modelId,\n finishReason: this.mapBedrockFinishReason(response.stopReason),\n usage,\n toolCalls: toolCalls.length > 0 ? toolCalls : undefined,\n };\n }\n\n private mapBedrockFinishReason(\n reason: string | null | undefined,\n ): AIResponse['finishReason'] {\n switch (reason) {\n case 'end_turn':\n return 'stop';\n case 'max_tokens':\n return 'length';\n case 'stop_sequence':\n return 'stop';\n case 'tool_use':\n return 'tool_calls';\n default:\n return 'stop';\n }\n }\n\n private mapToolConfig(options: ChatOptions): Record<string, any> | undefined {\n if (!options.tools || options.tools.length === 0) {\n return undefined;\n }\n\n if (options.toolChoice === 'none') {\n return undefined;\n }\n\n return {\n tools: options.tools.map((tool) => ({\n toolSpec: {\n name: tool.function.name,\n description: tool.function.description || '',\n inputSchema: {\n json: tool.function.parameters || { type: 'object' },\n },\n },\n })),\n ...(options.toolChoice && {\n toolChoice: this.mapToolChoice(options.toolChoice),\n }),\n };\n }\n\n private mapToolChoice(\n toolChoice?:\n | 'auto'\n | 'none'\n | { type: 'function'; function: { name: string } },\n ): Record<string, any> | undefined {\n if (!toolChoice || toolChoice === 'auto') {\n return { auto: {} };\n }\n\n if (toolChoice === 'none') {\n return undefined;\n }\n\n return {\n tool: {\n name: toolChoice.function.name,\n },\n };\n }\n\n private async parseInvokeModelBody(body: unknown): Promise<any> {\n const bytes =\n typeof (body as any)?.transformToByteArray === 'function'\n ? await (body as any).transformToByteArray()\n : body instanceof Uint8Array\n ? body\n : Buffer.isBuffer(body)\n ? body\n : new Uint8Array(body as ArrayBuffer);\n return JSON.parse(new TextDecoder().decode(bytes));\n }\n\n private extractEmbeddingVector(payload: any): number[] | undefined {\n if (Array.isArray(payload.embedding)) {\n return payload.embedding;\n }\n\n if (Array.isArray(payload.embeddings?.[0])) {\n return payload.embeddings[0];\n }\n\n if (Array.isArray(payload.embeddingsByType?.float)) {\n return payload.embeddingsByType.float;\n }\n\n if (Array.isArray(payload.vector)) {\n return payload.vector;\n }\n\n return undefined;\n }\n\n private async imageUrlToBedrockImage(\n imageUrl: string,\n signal?: AbortSignal,\n ): Promise<any> {\n const { bytes, mimeType } = await this.imageToBytes(imageUrl, signal);\n return {\n format: this.mimeTypeToBedrockImageFormat(mimeType),\n source: { bytes },\n };\n }\n\n private async imageToDataUrl(\n image: string | Buffer,\n signal?: AbortSignal,\n ): Promise<string> {\n if (Buffer.isBuffer(image)) {\n return `data:image/png;base64,${image.toString('base64')}`;\n }\n if (image.startsWith('data:')) {\n return image;\n }\n\n const { bytes, mimeType } = await this.imageToBytes(image, signal);\n return `data:${mimeType};base64,${Buffer.from(bytes).toString('base64')}`;\n }\n\n private async imageToBase64(\n image: string | Buffer,\n signal?: AbortSignal,\n ): Promise<string> {\n if (Buffer.isBuffer(image)) {\n return image.toString('base64');\n }\n if (image.startsWith('data:')) {\n const match = image.match(/^data:([^;]+);base64,(.+)$/);\n if (!match) {\n throw new AIError(\n 'Invalid base64 data URL format',\n 'INVALID_INPUT',\n 'bedrock',\n );\n }\n return match[2];\n }\n\n const { bytes } = await this.imageToBytes(image, signal);\n return Buffer.from(bytes).toString('base64');\n }\n\n private async imageToBytes(\n image: string,\n signal?: AbortSignal,\n ): Promise<{ bytes: Uint8Array; mimeType: string }> {\n if (image.startsWith('data:')) {\n const match = image.match(/^data:([^;]+);base64,(.+)$/);\n if (!match) {\n throw new AIError(\n 'Invalid base64 data URL format',\n 'INVALID_INPUT',\n 'bedrock',\n );\n }\n\n return {\n bytes: Uint8Array.from(Buffer.from(match[2], 'base64')),\n mimeType: match[1],\n };\n }\n\n const response = await fetch(image, { signal });\n if (!response.ok) {\n throw new AIError(\n `Failed to fetch image: ${response.status} ${response.statusText}`,\n 'IMAGE_FETCH_ERROR',\n 'bedrock',\n );\n }\n\n const arrayBuffer = await response.arrayBuffer();\n return {\n bytes: new Uint8Array(arrayBuffer),\n mimeType: response.headers.get('content-type') || 'image/png',\n };\n }\n\n private mimeTypeToBedrockImageFormat(mimeType: string): string {\n if (mimeType.includes('png')) return 'png';\n if (mimeType.includes('jpeg') || mimeType.includes('jpg')) return 'jpeg';\n if (mimeType.includes('gif')) return 'gif';\n if (mimeType.includes('webp')) return 'webp';\n\n throw new AIError(\n `Unsupported image format for Bedrock: ${mimeType}`,\n 'INVALID_INPUT',\n 'bedrock',\n );\n }\n\n private resolveImageSize(options: ImageGenerationOptions): {\n width: number;\n height: number;\n } {\n if (options.size) {\n const [width, height] = options.size.split('x').map(Number);\n if (Number.isFinite(width) && Number.isFinite(height)) {\n return { width, height };\n }\n }\n\n const aspectRatioSizes: Record<string, { width: number; height: number }> =\n {\n '1:1': { width: 1024, height: 1024 },\n '2:3': { width: 768, height: 1152 },\n '3:2': { width: 1152, height: 768 },\n '3:5': { width: 768, height: 1280 },\n '5:3': { width: 1280, height: 768 },\n '7:9': { width: 896, height: 1152 },\n '9:7': { width: 1152, height: 896 },\n '6:11': { width: 768, height: 1408 },\n '11:6': { width: 1408, height: 768 },\n '5:11': { width: 640, height: 1408 },\n '11:5': { width: 1408, height: 640 },\n '9:5': { width: 1152, height: 640 },\n '16:9': { width: 1173, height: 640 },\n };\n\n return (\n aspectRatioSizes[options.aspectRatio || ''] || {\n width: 1024,\n height: 1024,\n }\n );\n }\n\n private mapImageQuality(quality?: string): string {\n if (!quality || quality === 'standard') {\n return 'standard';\n }\n\n if (quality === 'hd') {\n return 'premium';\n }\n\n return quality;\n }\n\n private safeJsonParse(input: string): any {\n try {\n return JSON.parse(input);\n } catch {\n return { rawArguments: input };\n }\n }\n\n private mapError(error: unknown): AIError {\n if (error instanceof AIError) {\n return error;\n }\n\n // Map common AWS error codes\n if (typeof error === 'object' && error !== null) {\n const awsError = error as { name?: string; message?: string };\n\n if (awsError.name === 'AccessDeniedException') {\n return new AuthenticationError('bedrock');\n }\n\n if (awsError.name === 'ThrottlingException') {\n return new RateLimitError('bedrock');\n }\n\n if (awsError.name === 'ResourceNotFoundException') {\n return new ModelNotFoundError(\n awsError.message || 'Model not found',\n 'bedrock',\n );\n }\n\n if (\n awsError.name === 'ValidationException' &&\n awsError.message?.includes('input is too long')\n ) {\n return new ContextLengthError('bedrock');\n }\n }\n\n const errorMessage =\n error instanceof Error ? error.message : 'Unknown Bedrock error occurred';\n return new AIError(errorMessage, 'UNKNOWN_ERROR', 'bedrock');\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ValidationError } from "@happyvertical/utils";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { n as normalizeChatOptions, a as normalizeImageGenerationOptions } from "./index-DCXO0nZA.js";
|
|
3
|
+
import { B as BifrostAdmin, r as resolveGatewayAdminBaseUrl, n as normalizeGatewayBaseUrl } from "./gateway-admin-BUhBzXZb.js";
|
|
4
|
+
import { OpenAIProvider } from "./openai-CJEo69jb.js";
|
|
4
5
|
const BIFROST_CAPABILITIES = {
|
|
5
6
|
chat: true,
|
|
6
7
|
completion: true,
|
|
@@ -191,21 +192,39 @@ class BifrostProvider extends OpenAIProvider {
|
|
|
191
192
|
return model.id;
|
|
192
193
|
}
|
|
193
194
|
async chat(messages, options = {}) {
|
|
195
|
+
const safe = normalizeChatOptions(
|
|
196
|
+
this.options,
|
|
197
|
+
options,
|
|
198
|
+
"bifrost",
|
|
199
|
+
options.model || this.options.defaultModel
|
|
200
|
+
);
|
|
194
201
|
return super.chat(messages, {
|
|
195
|
-
...
|
|
196
|
-
model: await this.resolveModel("chat",
|
|
202
|
+
...safe,
|
|
203
|
+
model: await this.resolveModel("chat", safe.model)
|
|
197
204
|
});
|
|
198
205
|
}
|
|
199
206
|
async *stream(messages, options = {}) {
|
|
207
|
+
const safe = normalizeChatOptions(
|
|
208
|
+
this.options,
|
|
209
|
+
options,
|
|
210
|
+
"bifrost",
|
|
211
|
+
options.model || this.options.defaultModel
|
|
212
|
+
);
|
|
200
213
|
yield* super.stream(messages, {
|
|
201
|
-
...
|
|
202
|
-
model: await this.resolveModel("chat",
|
|
214
|
+
...safe,
|
|
215
|
+
model: await this.resolveModel("chat", safe.model)
|
|
203
216
|
});
|
|
204
217
|
}
|
|
205
218
|
async describeImage(image, prompt, options = {}) {
|
|
219
|
+
const safe = normalizeChatOptions(
|
|
220
|
+
this.options,
|
|
221
|
+
options,
|
|
222
|
+
"bifrost",
|
|
223
|
+
options.model || this.options.defaultModel
|
|
224
|
+
);
|
|
206
225
|
return super.describeImage(image, prompt, {
|
|
207
|
-
...
|
|
208
|
-
model: await this.resolveModel("vision",
|
|
226
|
+
...safe,
|
|
227
|
+
model: await this.resolveModel("vision", safe.model)
|
|
209
228
|
});
|
|
210
229
|
}
|
|
211
230
|
async embed(text, options = {}) {
|
|
@@ -221,13 +240,19 @@ class BifrostProvider extends OpenAIProvider {
|
|
|
221
240
|
});
|
|
222
241
|
}
|
|
223
242
|
async generateImage(prompt, options = {}) {
|
|
243
|
+
const safe = normalizeImageGenerationOptions(
|
|
244
|
+
this.options,
|
|
245
|
+
options,
|
|
246
|
+
"bifrost",
|
|
247
|
+
options.model
|
|
248
|
+
);
|
|
224
249
|
return super.generateImage(prompt, {
|
|
225
|
-
...
|
|
226
|
-
model: await this.resolveModel("image_generation",
|
|
250
|
+
...safe,
|
|
251
|
+
model: await this.resolveModel("image_generation", safe.model)
|
|
227
252
|
});
|
|
228
253
|
}
|
|
229
254
|
}
|
|
230
255
|
export {
|
|
231
256
|
BifrostProvider
|
|
232
257
|
};
|
|
233
|
-
//# sourceMappingURL=bifrost-
|
|
258
|
+
//# sourceMappingURL=bifrost-CEnCsciy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bifrost-CEnCsciy.js","sources":["../../src/shared/providers/bifrost.ts"],"sourcesContent":["import { ValidationError } from '@happyvertical/utils';\n\nimport {\n normalizeChatOptions,\n normalizeImageGenerationOptions,\n} from '../safety';\nimport type {\n AICapabilities,\n AIMessage,\n AIModel,\n AIResponse,\n BifrostOptions,\n ChatOptions,\n EmbeddingOptions,\n EmbeddingResponse,\n ImageDescriptionOptions,\n ImageEmbeddingOptions,\n ImageGenerationOptions,\n ImageGenerationResponse,\n} from '../types';\nimport {\n BifrostAdmin,\n normalizeGatewayBaseUrl,\n resolveGatewayAdminBaseUrl,\n} from './gateway-admin';\nimport { type OpenAICompatibleProfile, OpenAIProvider } from './openai';\n\nconst BIFROST_CAPABILITIES: AICapabilities = {\n chat: true,\n completion: true,\n embeddings: true,\n streaming: true,\n functions: true,\n vision: true,\n fineTuning: false,\n imageEmbeddings: true,\n imageGeneration: true,\n tts: false,\n voiceCloning: false,\n voiceDesign: false,\n maxContextLength: 128000,\n supportedOperations: [\n 'chat',\n 'completion',\n 'embedding',\n 'streaming',\n 'functions',\n 'vision',\n 'image_embedding',\n 'image_generation',\n ],\n};\n\nfunction isEmbeddingModel(modelId: string): boolean {\n return /embed/i.test(modelId);\n}\n\nfunction isImageEmbeddingModel(modelId: string): boolean {\n return /titan-embed-image|multimodalembedding|image[-_]?embed|clip/i.test(\n modelId,\n );\n}\n\nfunction isImageGenerationModel(modelId: string): boolean {\n return /gpt-image|dall-e|imagen|stable[-_ ]diffusion|sdxl|flux|titan-image|image-generator/i.test(\n modelId,\n );\n}\n\nfunction isFilteredBifrostModel(modelId: string): boolean {\n return /moderation|transcrib|whisper|speech|tts|rerank/i.test(modelId);\n}\n\nfunction inferBifrostContextLength(modelId: string): number {\n if (isEmbeddingModel(modelId)) return 8192;\n if (/gemini-1\\.5|gemini-2\\.0|gemini-2\\.5|gemini-3/i.test(modelId)) {\n return 1000000;\n }\n if (/claude/i.test(modelId)) return 200000;\n if (/gpt-4o|gpt-4\\.1|o1|o3|o4|llama|mistral|qwen|deepseek/i.test(modelId)) {\n return 128000;\n }\n return 32768;\n}\n\nfunction inferBifrostFunctions(modelId: string): boolean {\n if (isEmbeddingModel(modelId)) return false;\n return /gpt|claude|gemini|command|llama|mistral|qwen|deepseek|o1|o3|o4/i.test(\n modelId,\n );\n}\n\nfunction inferBifrostVision(modelId: string): boolean {\n return /gpt-4o|gpt-4\\.1|vision|claude-3|gemini|pixtral|llava|qwen.*vl|vl-/i.test(\n modelId,\n );\n}\n\nfunction inferBifrostCapabilities(modelId: string): string[] {\n if (isImageGenerationModel(modelId)) {\n return ['image_generation'];\n }\n\n if (isImageEmbeddingModel(modelId)) {\n return ['embeddings', 'image_embedding'];\n }\n\n if (isEmbeddingModel(modelId)) {\n return ['embeddings'];\n }\n\n const capabilities = ['text', 'chat'];\n\n if (inferBifrostFunctions(modelId)) {\n capabilities.push('functions');\n }\n\n if (inferBifrostVision(modelId)) {\n capabilities.push('vision');\n }\n\n return capabilities;\n}\n\nfunction ensureBifrostOptions(options: BifrostOptions): BifrostOptions {\n if (!options.baseUrl?.trim()) {\n throw new ValidationError('Bifrost baseUrl is required', {\n provider: 'bifrost',\n hint: 'Pass baseUrl like http://localhost:8080, http://localhost:8080/openai, or http://localhost:8080/v1 and optionally adminBaseUrl for governance endpoints',\n });\n }\n\n const baseUrl = normalizeGatewayBaseUrl(options.baseUrl);\n const inferenceBaseUrl = /\\/(?:openai|v1|pydanticai\\/v1)$/.test(baseUrl)\n ? baseUrl\n : `${baseUrl}/openai`;\n const headers = options.apiKey\n ? {\n ...options.headers,\n 'x-bf-vk': options.apiKey,\n 'x-api-key': options.apiKey,\n }\n : options.headers;\n\n return {\n ...options,\n baseUrl: inferenceBaseUrl,\n headers,\n };\n}\n\nconst BIFROST_PROFILE: OpenAICompatibleProfile = {\n providerLabel: 'Bifrost',\n providerName: 'bifrost',\n defaultModel: 'openai/gpt-4o-mini',\n capabilities: BIFROST_CAPABILITIES,\n describeModel: (modelId) => `Bifrost model: ${modelId}`,\n getContextLength: inferBifrostContextLength,\n getModelCapabilities: inferBifrostCapabilities,\n shouldIncludeModel: (modelId) => !isFilteredBifrostModel(modelId),\n supportsFunctions: inferBifrostFunctions,\n supportsVision: inferBifrostVision,\n};\n\ntype BifrostResolvedCapability =\n | 'chat'\n | 'vision'\n | 'embeddings'\n | 'image_generation';\n\nfunction supportsCapability(\n model: AIModel,\n capability: BifrostResolvedCapability,\n): boolean {\n if (capability === 'vision') {\n return (\n model.capabilities.includes('vision') || model.supportsVision === true\n );\n }\n\n if (capability === 'embeddings') {\n return model.capabilities.includes('embeddings');\n }\n\n if (capability === 'image_generation') {\n return model.capabilities.includes('image_generation');\n }\n\n return model.capabilities.includes('chat');\n}\n\n/**\n * Bifrost provider implementation.\n *\n * Bifrost exposes OpenAI-compatible inference and governance admin APIs. This\n * provider reuses the OpenAI-compatible transport for inference and exposes\n * `admin` for tenant project and virtual-key provisioning.\n */\nexport class BifrostProvider extends OpenAIProvider {\n readonly admin: BifrostAdmin;\n private readonly configuredDefaultModel?: string;\n private readonly resolvedModelCache = new Map<\n BifrostResolvedCapability,\n Promise<string>\n >();\n\n constructor(options: BifrostOptions) {\n const normalized = ensureBifrostOptions(options);\n super(normalized, BIFROST_PROFILE);\n const adminKey = normalized.adminApiKey || normalized.apiKey;\n const adminUsername = normalized.adminUser || normalized.adminUsername;\n this.admin = new BifrostAdmin({\n provider: 'bifrost',\n baseUrl: resolveGatewayAdminBaseUrl(\n normalized.baseUrl,\n normalized.adminUrl || normalized.adminBaseUrl,\n 'bifrost',\n ),\n apiKey: adminKey,\n username: adminUsername,\n password: normalized.adminPassword,\n headers:\n adminKey && !(adminUsername && normalized.adminPassword)\n ? {\n ...normalized.adminHeaders,\n 'x-bf-vk': adminKey,\n 'x-api-key': adminKey,\n }\n : normalized.adminHeaders,\n timeout: normalized.timeout,\n });\n this.configuredDefaultModel = normalized.defaultModel;\n }\n\n private async resolveModel(\n capability: BifrostResolvedCapability,\n explicitModel?: string,\n ): Promise<string> {\n if (explicitModel) {\n return explicitModel;\n }\n\n if (\n this.configuredDefaultModel &&\n (capability === 'chat' || capability === 'vision')\n ) {\n return this.configuredDefaultModel;\n }\n\n const cached = this.resolvedModelCache.get(capability);\n if (cached) {\n return cached;\n }\n\n const pending = this.selectModel(capability).catch((error) => {\n this.resolvedModelCache.delete(capability);\n throw error;\n });\n this.resolvedModelCache.set(capability, pending);\n return pending;\n }\n\n private async selectModel(\n capability: BifrostResolvedCapability,\n ): Promise<string> {\n const models = await super.getModels();\n const model = models.find((candidate) =>\n supportsCapability(candidate, capability),\n );\n\n if (!model) {\n throw new ValidationError(\n `No ${capability} model is available from the Bifrost gateway`,\n {\n provider: 'bifrost',\n capability,\n hint: 'Pass defaultModel explicitly or ensure the gateway returns a compatible model for this key',\n },\n );\n }\n\n return model.id;\n }\n\n async chat(\n messages: AIMessage[],\n options: ChatOptions = {},\n ): Promise<AIResponse> {\n const safe = normalizeChatOptions(\n this.options,\n options,\n 'bifrost',\n options.model || this.options.defaultModel,\n );\n return super.chat(messages, {\n ...safe,\n model: await this.resolveModel('chat', safe.model),\n });\n }\n\n async *stream(\n messages: AIMessage[],\n options: ChatOptions = {},\n ): AsyncIterable<string> {\n const safe = normalizeChatOptions(\n this.options,\n options,\n 'bifrost',\n options.model || this.options.defaultModel,\n );\n yield* super.stream(messages, {\n ...safe,\n model: await this.resolveModel('chat', safe.model),\n });\n }\n\n async describeImage(\n image: string | Buffer,\n prompt?: string,\n options: ImageDescriptionOptions = {},\n ): Promise<string> {\n const safe = normalizeChatOptions(\n this.options,\n options,\n 'bifrost',\n options.model || this.options.defaultModel,\n );\n return super.describeImage(image, prompt, {\n ...safe,\n model: await this.resolveModel('vision', safe.model),\n });\n }\n\n async embed(\n text: string | string[],\n options: EmbeddingOptions = {},\n ): Promise<EmbeddingResponse> {\n return super.embed(text, {\n ...options,\n model: await this.resolveModel('embeddings', options.model),\n });\n }\n\n async embedImage(\n image: string | Buffer,\n options: ImageEmbeddingOptions = {},\n ): Promise<EmbeddingResponse> {\n return super.embedImage(image, {\n ...options,\n model: await this.resolveModel('embeddings', options.model),\n });\n }\n\n async generateImage(\n prompt: string,\n options: ImageGenerationOptions = {},\n ): Promise<ImageGenerationResponse> {\n const safe = normalizeImageGenerationOptions(\n this.options,\n options,\n 'bifrost',\n options.model,\n );\n return super.generateImage(prompt, {\n ...safe,\n model: await this.resolveModel('image_generation', safe.model),\n });\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { spawn, exec } from "node:child_process";
|
|
2
2
|
import { promisify } from "node:util";
|
|
3
|
-
import { A as AIError,
|
|
3
|
+
import { A as AIError, f as extractTextContent, d as AuthenticationError, R as RateLimitError, c as ContextLengthError } from "./index-DCXO0nZA.js";
|
|
4
4
|
import { e as emitUsage } from "./usage-DMWiJ2oB.js";
|
|
5
5
|
const execAsync = promisify(exec);
|
|
6
6
|
class ClaudeCliProvider {
|
|
@@ -29,7 +29,7 @@ class ClaudeCliProvider {
|
|
|
29
29
|
if (!apiKey) {
|
|
30
30
|
return;
|
|
31
31
|
}
|
|
32
|
-
const { AnthropicProvider } = await import("./anthropic-
|
|
32
|
+
const { AnthropicProvider } = await import("./anthropic-2z-82zgr.js");
|
|
33
33
|
const modelMap = {
|
|
34
34
|
sonnet: "claude-3-5-sonnet-20241022",
|
|
35
35
|
opus: "claude-3-opus-20240229",
|
|
@@ -600,4 +600,4 @@ ${textContent}` : textContent;
|
|
|
600
600
|
export {
|
|
601
601
|
ClaudeCliProvider
|
|
602
602
|
};
|
|
603
|
-
//# sourceMappingURL=claude-cli-
|
|
603
|
+
//# sourceMappingURL=claude-cli-X1ONjE8K.js.map
|