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