@llumiverse/drivers 0.16.0 → 0.18.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 +1 -1
- package/lib/cjs/bedrock/converse.js +65 -15
- package/lib/cjs/bedrock/converse.js.map +1 -1
- package/lib/cjs/bedrock/index.js +191 -51
- package/lib/cjs/bedrock/index.js.map +1 -1
- package/lib/cjs/bedrock/nova-image-payload.js.map +1 -1
- package/lib/cjs/bedrock/s3.js +47 -0
- package/lib/cjs/bedrock/s3.js.map +1 -1
- package/lib/cjs/groq/index.js +4 -4
- package/lib/cjs/groq/index.js.map +1 -1
- package/lib/cjs/mistral/index.js +4 -4
- package/lib/cjs/mistral/index.js.map +1 -1
- package/lib/cjs/openai/azure.js +1 -1
- package/lib/cjs/openai/azure.js.map +1 -1
- package/lib/cjs/openai/index.js +218 -83
- package/lib/cjs/openai/index.js.map +1 -1
- package/lib/cjs/replicate.js +4 -17
- package/lib/cjs/replicate.js.map +1 -1
- package/lib/cjs/togetherai/index.js +2 -2
- package/lib/cjs/vertexai/embeddings/embeddings-image.js +2 -1
- package/lib/cjs/vertexai/embeddings/embeddings-image.js.map +1 -1
- package/lib/cjs/vertexai/embeddings/embeddings-text.js +2 -1
- package/lib/cjs/vertexai/embeddings/embeddings-text.js.map +1 -1
- package/lib/cjs/vertexai/index.js +117 -52
- package/lib/cjs/vertexai/index.js.map +1 -1
- package/lib/cjs/vertexai/models/claude.js +51 -17
- package/lib/cjs/vertexai/models/claude.js.map +1 -1
- package/lib/cjs/vertexai/models/gemini.js +42 -20
- package/lib/cjs/vertexai/models/gemini.js.map +1 -1
- package/lib/cjs/vertexai/models/imagen.js.map +1 -1
- package/lib/cjs/watsonx/index.js +12 -6
- package/lib/cjs/watsonx/index.js.map +1 -1
- package/lib/esm/bedrock/converse.js +63 -14
- package/lib/esm/bedrock/converse.js.map +1 -1
- package/lib/esm/bedrock/index.js +193 -50
- package/lib/esm/bedrock/index.js.map +1 -1
- package/lib/esm/bedrock/nova-image-payload.js.map +1 -1
- package/lib/esm/bedrock/s3.js +46 -0
- package/lib/esm/bedrock/s3.js.map +1 -1
- package/lib/esm/groq/index.js +4 -4
- package/lib/esm/groq/index.js.map +1 -1
- package/lib/esm/mistral/index.js +4 -4
- package/lib/esm/mistral/index.js.map +1 -1
- package/lib/esm/openai/azure.js +1 -1
- package/lib/esm/openai/azure.js.map +1 -1
- package/lib/esm/openai/index.js +219 -85
- package/lib/esm/openai/index.js.map +1 -1
- package/lib/esm/replicate.js +3 -16
- package/lib/esm/replicate.js.map +1 -1
- package/lib/esm/togetherai/index.js +2 -2
- package/lib/esm/vertexai/embeddings/embeddings-image.js +2 -1
- package/lib/esm/vertexai/embeddings/embeddings-image.js.map +1 -1
- package/lib/esm/vertexai/embeddings/embeddings-text.js +2 -1
- package/lib/esm/vertexai/embeddings/embeddings-text.js.map +1 -1
- package/lib/esm/vertexai/index.js +120 -55
- package/lib/esm/vertexai/index.js.map +1 -1
- package/lib/esm/vertexai/models/claude.js +52 -18
- package/lib/esm/vertexai/models/claude.js.map +1 -1
- package/lib/esm/vertexai/models/gemini.js +42 -20
- package/lib/esm/vertexai/models/gemini.js.map +1 -1
- package/lib/esm/vertexai/models/imagen.js.map +1 -1
- package/lib/esm/watsonx/index.js +12 -6
- package/lib/esm/watsonx/index.js.map +1 -1
- package/lib/types/bedrock/converse.d.ts +3 -2
- package/lib/types/bedrock/converse.d.ts.map +1 -1
- package/lib/types/bedrock/index.d.ts +5 -16
- package/lib/types/bedrock/index.d.ts.map +1 -1
- package/lib/types/bedrock/nova-image-payload.d.ts.map +1 -1
- package/lib/types/bedrock/s3.d.ts +6 -0
- package/lib/types/bedrock/s3.d.ts.map +1 -1
- package/lib/types/openai/index.d.ts +8 -5
- package/lib/types/openai/index.d.ts.map +1 -1
- package/lib/types/togetherai/interfaces.d.ts +3 -3
- package/lib/types/togetherai/interfaces.d.ts.map +1 -1
- package/lib/types/vertexai/embeddings/embeddings-image.d.ts.map +1 -1
- package/lib/types/vertexai/embeddings/embeddings-text.d.ts.map +1 -1
- package/lib/types/vertexai/index.d.ts +11 -6
- package/lib/types/vertexai/index.d.ts.map +1 -1
- package/lib/types/vertexai/models/claude.d.ts.map +1 -1
- package/lib/types/vertexai/models/gemini.d.ts.map +1 -1
- package/lib/types/vertexai/models/imagen.d.ts.map +1 -1
- package/lib/types/vertexai/models.d.ts +1 -1
- package/lib/types/vertexai/models.d.ts.map +1 -1
- package/lib/types/watsonx/index.d.ts.map +1 -1
- package/lib/types/watsonx/interfaces.d.ts +4 -0
- package/lib/types/watsonx/interfaces.d.ts.map +1 -1
- package/package.json +19 -21
- package/src/bedrock/converse.ts +69 -20
- package/src/bedrock/index.ts +231 -62
- package/src/bedrock/nova-image-payload.ts +1 -2
- package/src/bedrock/s3.ts +48 -0
- package/src/groq/index.ts +4 -4
- package/src/mistral/index.ts +4 -4
- package/src/openai/azure.ts +2 -2
- package/src/openai/index.ts +269 -93
- package/src/openai/openai.ts +1 -1
- package/src/replicate.ts +4 -16
- package/src/togetherai/index.ts +2 -2
- package/src/togetherai/interfaces.ts +3 -3
- package/src/vertexai/embeddings/embeddings-image.ts +5 -3
- package/src/vertexai/embeddings/embeddings-text.ts +5 -3
- package/src/vertexai/index.ts +168 -67
- package/src/vertexai/models/claude.ts +71 -32
- package/src/vertexai/models/gemini.ts +47 -23
- package/src/vertexai/models/imagen.ts +4 -3
- package/src/vertexai/models.ts +1 -1
- package/src/watsonx/index.ts +12 -6
- package/src/watsonx/interfaces.ts +4 -0
package/src/bedrock/index.ts
CHANGED
|
@@ -1,18 +1,24 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
Bedrock, CreateModelCustomizationJobCommand, FoundationModelSummary, GetModelCustomizationJobCommand,
|
|
3
|
+
GetModelCustomizationJobCommandOutput, ModelCustomizationJobStatus, ModelModality, StopModelCustomizationJobCommand
|
|
4
|
+
} from "@aws-sdk/client-bedrock";
|
|
5
|
+
import { BedrockRuntime, ConverseRequest, ConverseResponse, ConverseStreamOutput, InferenceConfiguration, Tool } from "@aws-sdk/client-bedrock-runtime";
|
|
3
6
|
import { S3Client } from "@aws-sdk/client-s3";
|
|
4
|
-
import {
|
|
7
|
+
import { AwsCredentialIdentity, Provider } from "@aws-sdk/types";
|
|
8
|
+
import {
|
|
9
|
+
AbstractDriver, AIModel, Completion, CompletionChunkObject, DataSource, DriverOptions, EmbeddingsOptions, EmbeddingsResult,
|
|
10
|
+
ExecutionOptions, ExecutionTokenUsage, ImageGeneration, Modalities, PromptOptions, PromptSegment,
|
|
11
|
+
TextFallbackOptions, ToolDefinition, ToolUse, TrainingJob, TrainingJobStatus, TrainingOptions,
|
|
12
|
+
BedrockClaudeOptions, BedrockPalmyraOptions, getMaxTokensLimit, NovaCanvasOptions,
|
|
13
|
+
modelModalitiesToArray, getModelCapabilities
|
|
14
|
+
} from "@llumiverse/core";
|
|
5
15
|
import { transformAsyncIterator } from "@llumiverse/core/async";
|
|
6
16
|
import { formatNovaPrompt, NovaMessagesPrompt } from "@llumiverse/core/formatters";
|
|
7
|
-
import {
|
|
8
|
-
import
|
|
9
|
-
import { BedrockClaudeOptions, NovaCanvasOptions } from "../../../core/src/options/bedrock.js";
|
|
10
|
-
import { converseConcatMessages, converseRemoveJSONprefill, converseSystemToMessages, fortmatConversePrompt } from "./converse.js";
|
|
17
|
+
import { LRUCache } from "mnemonist";
|
|
18
|
+
import { converseConcatMessages, converseJSONprefill, converseSystemToMessages, formatConversePrompt } from "./converse.js";
|
|
11
19
|
import { formatNovaImageGenerationPayload, NovaImageGenerationTaskType } from "./nova-image-payload.js";
|
|
12
20
|
import { forceUploadFile } from "./s3.js";
|
|
13
21
|
|
|
14
|
-
const { LRUCache } = mnemonist;
|
|
15
|
-
|
|
16
22
|
const supportStreamingCache = new LRUCache<string, boolean>(4096);
|
|
17
23
|
|
|
18
24
|
enum BedrockModelType {
|
|
@@ -44,8 +50,8 @@ export interface BedrockDriverOptions extends DriverOptions {
|
|
|
44
50
|
*/
|
|
45
51
|
region: string;
|
|
46
52
|
/**
|
|
47
|
-
*
|
|
48
|
-
* It will be created
|
|
53
|
+
* The bucket name to be used for training.
|
|
54
|
+
* It will be created if does not already exist.
|
|
49
55
|
*/
|
|
50
56
|
training_bucket?: string;
|
|
51
57
|
|
|
@@ -105,10 +111,10 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
105
111
|
if (opts.model.includes("canvas")) {
|
|
106
112
|
return await formatNovaPrompt(segments, opts.result_schema);
|
|
107
113
|
}
|
|
108
|
-
return await
|
|
114
|
+
return await formatConversePrompt(segments, opts.result_schema);
|
|
109
115
|
}
|
|
110
116
|
|
|
111
|
-
static
|
|
117
|
+
static getExtractedExecution(result: ConverseResponse, _prompt?: BedrockPrompt): CompletionChunkObject {
|
|
112
118
|
return {
|
|
113
119
|
result: result.output?.message?.content?.map(c => c.text).join("\n") ?? "",
|
|
114
120
|
token_usage: {
|
|
@@ -145,18 +151,45 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
145
151
|
};
|
|
146
152
|
|
|
147
153
|
async requestTextCompletion(prompt: ConverseRequest, options: ExecutionOptions): Promise<Completion> {
|
|
154
|
+
let conversation = updateConversation(options.conversation as ConverseRequest, prompt);
|
|
148
155
|
|
|
149
|
-
const payload = this.preparePayload(
|
|
156
|
+
const payload = this.preparePayload(conversation, options);
|
|
150
157
|
const executor = this.getExecutor();
|
|
151
158
|
|
|
152
159
|
const res = await executor.converse({
|
|
153
160
|
...payload,
|
|
154
161
|
});
|
|
155
162
|
|
|
163
|
+
conversation = updateConversation(conversation, {
|
|
164
|
+
messages: [res.output?.message ?? { content: [{ text: "" }], role: "assistant" }],
|
|
165
|
+
modelId: prompt.modelId,
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
let tool_use: ToolUse[] | undefined = undefined;
|
|
169
|
+
//Get tool requests
|
|
170
|
+
if (res.stopReason == "tool_use") {
|
|
171
|
+
tool_use = res.output?.message?.content?.reduce((tools: ToolUse[], c) => {
|
|
172
|
+
if (c.toolUse) {
|
|
173
|
+
tools.push({
|
|
174
|
+
tool_name: c.toolUse.name ?? "",
|
|
175
|
+
tool_input: c.toolUse.input as any,
|
|
176
|
+
id: c.toolUse.toolUseId ?? "",
|
|
177
|
+
} satisfies ToolUse);
|
|
178
|
+
}
|
|
179
|
+
return tools;
|
|
180
|
+
}, []);
|
|
181
|
+
//If no tools were used, set to undefined
|
|
182
|
+
if (tool_use && tool_use.length == 0) {
|
|
183
|
+
tool_use = undefined;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
156
187
|
const completion = {
|
|
157
|
-
...BedrockDriver.
|
|
188
|
+
...BedrockDriver.getExtractedExecution(res, prompt),
|
|
158
189
|
original_response: options.include_original_response ? res : undefined,
|
|
159
|
-
|
|
190
|
+
conversation: conversation,
|
|
191
|
+
tool_use: tool_use,
|
|
192
|
+
};
|
|
160
193
|
|
|
161
194
|
return completion;
|
|
162
195
|
}
|
|
@@ -167,13 +200,13 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
167
200
|
if (arnMatch) {
|
|
168
201
|
return arnMatch[1];
|
|
169
202
|
}
|
|
170
|
-
|
|
203
|
+
|
|
171
204
|
// Match common AWS regions directly in string
|
|
172
205
|
const regionMatch = modelString.match(/(?:us|eu|ap|sa|ca|me|af)[-](east|west|central|south|north|southeast|southwest|northeast|northwest)[-][1-9]/);
|
|
173
206
|
if (regionMatch) {
|
|
174
207
|
return regionMatch[0];
|
|
175
208
|
}
|
|
176
|
-
|
|
209
|
+
|
|
177
210
|
return defaultRegion;
|
|
178
211
|
}
|
|
179
212
|
|
|
@@ -267,11 +300,17 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
267
300
|
let additionalField = {};
|
|
268
301
|
|
|
269
302
|
if (options.model.includes("amazon")) {
|
|
303
|
+
if (options.result_schema) {
|
|
304
|
+
prompt.messages = converseJSONprefill(prompt.messages);
|
|
305
|
+
}
|
|
270
306
|
//Titan models also exists but does not support any additional options
|
|
271
307
|
if (options.model.includes("nova")) {
|
|
272
308
|
additionalField = { inferenceConfig: { topK: model_options?.top_k } };
|
|
273
309
|
}
|
|
274
310
|
} else if (options.model.includes("claude")) {
|
|
311
|
+
if (options.result_schema) {
|
|
312
|
+
prompt.messages = converseJSONprefill(prompt.messages);
|
|
313
|
+
}
|
|
275
314
|
if (options.model.includes("claude-3-7")) {
|
|
276
315
|
const thinking_options = options.model_options as BedrockClaudeOptions;
|
|
277
316
|
const thinking = thinking_options?.thinking_mode ?? false;
|
|
@@ -279,13 +318,13 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
279
318
|
model_options.max_tokens = thinking ? 128000 : 8192;
|
|
280
319
|
}
|
|
281
320
|
additionalField = {
|
|
282
|
-
|
|
321
|
+
...additionalField,
|
|
283
322
|
reasoning_config: {
|
|
284
323
|
type: thinking ? "enabled" : "disabled",
|
|
285
324
|
budget_tokens: thinking_options?.thinking_budget_tokens,
|
|
286
325
|
}
|
|
287
326
|
};
|
|
288
|
-
if(thinking && (thinking_options?.thinking_budget_tokens ?? 0) > 64000){
|
|
327
|
+
if (thinking && (thinking_options?.thinking_budget_tokens ?? 0) > 64000) {
|
|
289
328
|
additionalField = {
|
|
290
329
|
...additionalField,
|
|
291
330
|
anthorpic_beta: ["output-128k-2025-02-19"]
|
|
@@ -294,22 +333,11 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
294
333
|
}
|
|
295
334
|
//Needs max_tokens to be set
|
|
296
335
|
if (!model_options?.max_tokens) {
|
|
297
|
-
|
|
298
|
-
model_options.max_tokens = 8192;
|
|
299
|
-
|
|
300
|
-
//Bug with AWS Converse Sonnet 3.5, does not effect Haiku.
|
|
301
|
-
//See https://github.com/boto/boto3/issues/4279
|
|
302
|
-
if (options.model.includes("claude-3-5-sonnet")) {
|
|
303
|
-
model_options.max_tokens = 4096;
|
|
304
|
-
}
|
|
305
|
-
} else {
|
|
306
|
-
model_options.max_tokens = 4096;
|
|
307
|
-
}
|
|
336
|
+
model_options.max_tokens = getMaxTokensLimit(options.model, model_options);
|
|
308
337
|
}
|
|
309
|
-
additionalField = { top_k: model_options?.top_k };
|
|
338
|
+
additionalField = { ...additionalField, top_k: model_options?.top_k };
|
|
310
339
|
} else if (options.model.includes("meta")) {
|
|
311
|
-
//
|
|
312
|
-
prompt.messages = converseRemoveJSONprefill(prompt.messages);
|
|
340
|
+
//LLaMA models support no additional options
|
|
313
341
|
} else if (options.model.includes("mistral")) {
|
|
314
342
|
//7B instruct and 8x7B instruct
|
|
315
343
|
if (options.model.includes("7b")) {
|
|
@@ -320,14 +348,14 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
320
348
|
prompt.system = undefined;
|
|
321
349
|
prompt.messages = converseConcatMessages(prompt.messages);
|
|
322
350
|
}
|
|
351
|
+
if (options.result_schema) {
|
|
352
|
+
prompt.messages = converseJSONprefill(prompt.messages);
|
|
353
|
+
}
|
|
323
354
|
} else {
|
|
324
355
|
//Other models such as Mistral Small,Large and Large 2
|
|
325
356
|
//Support no additional fields.
|
|
326
|
-
prompt.messages = converseRemoveJSONprefill(prompt.messages);
|
|
327
357
|
}
|
|
328
358
|
} else if (options.model.includes("ai21")) {
|
|
329
|
-
//If last message is "```json", remove it. Model requires the final message to be a user message
|
|
330
|
-
prompt.messages = converseRemoveJSONprefill(prompt.messages);
|
|
331
359
|
//Jamba models support no additional options
|
|
332
360
|
//Jurassic 2 models do.
|
|
333
361
|
if (options.model.includes("j2")) {
|
|
@@ -344,8 +372,6 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
344
372
|
}
|
|
345
373
|
} else if (options.model.includes("cohere.command")) {
|
|
346
374
|
// If last message is "```json", remove it.
|
|
347
|
-
// Model requires the final message to be a user message or does not support assistant messages
|
|
348
|
-
prompt.messages = converseRemoveJSONprefill(prompt.messages);
|
|
349
375
|
//Command R and R plus
|
|
350
376
|
if (options.model.includes("cohere.command-r")) {
|
|
351
377
|
additionalField = {
|
|
@@ -363,6 +389,16 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
363
389
|
prompt.messages = converseConcatMessages(prompt.messages);
|
|
364
390
|
}
|
|
365
391
|
}
|
|
392
|
+
} else if (options.model.includes("palmyra")) {
|
|
393
|
+
const palmyraOptions = options.model_options as BedrockPalmyraOptions;
|
|
394
|
+
additionalField = {
|
|
395
|
+
seed: palmyraOptions?.seed,
|
|
396
|
+
presence_penalty: palmyraOptions?.presence_penalty,
|
|
397
|
+
frequency_penalty: palmyraOptions?.frequency_penalty,
|
|
398
|
+
min_tokens: palmyraOptions?.min_tokens,
|
|
399
|
+
}
|
|
400
|
+
} else if (options.model.includes("deepseek")) {
|
|
401
|
+
//DeepSeek models support no additional options
|
|
366
402
|
}
|
|
367
403
|
|
|
368
404
|
//If last message is "```json", add corresponding ``` as a stop sequence.
|
|
@@ -378,7 +414,9 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
378
414
|
}
|
|
379
415
|
}
|
|
380
416
|
|
|
381
|
-
|
|
417
|
+
const tool_defs = getToolDefinitions(options.tools);
|
|
418
|
+
|
|
419
|
+
const request: ConverseRequest = {
|
|
382
420
|
messages: prompt.messages,
|
|
383
421
|
system: prompt.system,
|
|
384
422
|
modelId: options.model,
|
|
@@ -390,8 +428,17 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
390
428
|
} satisfies InferenceConfiguration,
|
|
391
429
|
additionalModelRequestFields: {
|
|
392
430
|
...additionalField,
|
|
393
|
-
}
|
|
394
|
-
}
|
|
431
|
+
}
|
|
432
|
+
};
|
|
433
|
+
|
|
434
|
+
//Only add tools if they are defined
|
|
435
|
+
if (tool_defs) {
|
|
436
|
+
request.toolConfig = {
|
|
437
|
+
tools: tool_defs,
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
return request;
|
|
395
442
|
}
|
|
396
443
|
|
|
397
444
|
|
|
@@ -400,7 +447,7 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
400
447
|
throw new Error(`Image generation requires image output_modality`);
|
|
401
448
|
}
|
|
402
449
|
if (options.model_options?._option_id !== "bedrock-nova-canvas") {
|
|
403
|
-
this.logger.warn("Invalid model options", {options: options.model_options });
|
|
450
|
+
this.logger.warn("Invalid model options", { options: options.model_options });
|
|
404
451
|
}
|
|
405
452
|
const model_options = options.model_options as NovaCanvasOptions;
|
|
406
453
|
|
|
@@ -522,7 +569,7 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
522
569
|
|
|
523
570
|
async _listModels(foundationFilter?: (m: FoundationModelSummary) => boolean): Promise<AIModel[]> {
|
|
524
571
|
const service = this.getService();
|
|
525
|
-
const [
|
|
572
|
+
const [foundationModelsList, customModelsList, inferenceProfilesList] = await Promise.all([
|
|
526
573
|
service.listFoundationModels({}).catch(() => {
|
|
527
574
|
this.logger.warn("[Bedrock] Can't list foundation models. Check if the user has the right permissions.");
|
|
528
575
|
return undefined
|
|
@@ -537,21 +584,65 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
537
584
|
}),
|
|
538
585
|
]);
|
|
539
586
|
|
|
540
|
-
if (!
|
|
587
|
+
if (!foundationModelsList?.modelSummaries) {
|
|
541
588
|
throw new Error("Foundation models not found");
|
|
542
589
|
}
|
|
543
590
|
|
|
544
|
-
let
|
|
591
|
+
let foundationModels = foundationModelsList.modelSummaries || [];
|
|
545
592
|
if (foundationFilter) {
|
|
546
|
-
|
|
593
|
+
foundationModels = foundationModels.filter(foundationFilter);
|
|
547
594
|
}
|
|
548
595
|
|
|
549
|
-
const
|
|
596
|
+
const supportedPublishers = ["amazon", "anthropic", "cohere", "ai21", "mistral", "meta", "deepseek", "writer"];
|
|
597
|
+
const unsupportedModelsByPublisher = {
|
|
598
|
+
amazon: ["titan-image-generator", "nova-reel", "nova-sonic", "rerank"],
|
|
599
|
+
anthropic: [],
|
|
600
|
+
cohere: ["rerank"],
|
|
601
|
+
ai21: [],
|
|
602
|
+
mistral: [],
|
|
603
|
+
meta: [],
|
|
604
|
+
deepseek: [],
|
|
605
|
+
writer: [],
|
|
606
|
+
};
|
|
607
|
+
|
|
608
|
+
// Helper function to check if model should be filtered out
|
|
609
|
+
const shouldIncludeModel = (modelId?: string, providerName?: string): boolean => {
|
|
610
|
+
if (!modelId || !providerName) return false;
|
|
611
|
+
|
|
612
|
+
const normalizedProvider = providerName.toLowerCase();
|
|
613
|
+
|
|
614
|
+
// Check if provider is supported
|
|
615
|
+
const isProviderSupported = supportedPublishers.some(provider =>
|
|
616
|
+
normalizedProvider.includes(provider)
|
|
617
|
+
);
|
|
618
|
+
|
|
619
|
+
if (!isProviderSupported) return false;
|
|
620
|
+
|
|
621
|
+
// Check if model is in the unsupported list for its provider
|
|
622
|
+
for (const provider of supportedPublishers) {
|
|
623
|
+
if (normalizedProvider.includes(provider)) {
|
|
624
|
+
const unsupportedModels = unsupportedModelsByPublisher[provider as keyof typeof unsupportedModelsByPublisher] || [];
|
|
625
|
+
return !unsupportedModels.some(unsupported =>
|
|
626
|
+
modelId.toLowerCase().includes(unsupported)
|
|
627
|
+
);
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
return true;
|
|
632
|
+
};
|
|
633
|
+
|
|
634
|
+
foundationModels = foundationModels.filter(m =>
|
|
635
|
+
shouldIncludeModel(m.modelId, m.providerName)
|
|
636
|
+
);
|
|
637
|
+
|
|
638
|
+
const aiModels: AIModel[] = foundationModels.map((m) => {
|
|
550
639
|
|
|
551
640
|
if (!m.modelId) {
|
|
552
641
|
throw new Error("modelId not found");
|
|
553
642
|
}
|
|
554
643
|
|
|
644
|
+
const modelCapability = getModelCapabilities(m.modelArn ?? m.modelId, this.provider);
|
|
645
|
+
|
|
555
646
|
const model: AIModel = {
|
|
556
647
|
id: m.modelArn ?? m.modelId,
|
|
557
648
|
name: `${m.providerName} ${m.modelName}`,
|
|
@@ -559,52 +650,78 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
559
650
|
//description: ``,
|
|
560
651
|
owner: m.providerName,
|
|
561
652
|
can_stream: m.responseStreamingSupported ?? false,
|
|
562
|
-
|
|
563
|
-
|
|
653
|
+
input_modalities: m.inputModalities ? formatAmazonModalities(m.inputModalities) : modelModalitiesToArray(modelCapability.input),
|
|
654
|
+
output_modalities: m.outputModalities ? formatAmazonModalities(m.outputModalities) : modelModalitiesToArray(modelCapability.input),
|
|
655
|
+
tool_support: modelCapability.tool_support,
|
|
564
656
|
};
|
|
565
657
|
|
|
566
658
|
return model;
|
|
567
659
|
});
|
|
568
660
|
|
|
569
661
|
//add custom models
|
|
570
|
-
if (
|
|
571
|
-
|
|
662
|
+
if (customModelsList?.modelSummaries) {
|
|
663
|
+
customModelsList.modelSummaries.forEach((m) => {
|
|
572
664
|
|
|
573
665
|
if (!m.modelArn) {
|
|
574
666
|
throw new Error("Model ID not found");
|
|
575
667
|
}
|
|
576
668
|
|
|
669
|
+
const modelCapability = getModelCapabilities(m.modelArn, this.provider);
|
|
670
|
+
|
|
577
671
|
const model: AIModel = {
|
|
578
672
|
id: m.modelArn,
|
|
579
673
|
name: m.modelName ?? m.modelArn,
|
|
580
674
|
provider: this.provider,
|
|
581
675
|
description: `Custom model from ${m.baseModelName}`,
|
|
582
676
|
is_custom: true,
|
|
677
|
+
input_modalities: modelModalitiesToArray(modelCapability.input),
|
|
678
|
+
output_modalities: modelModalitiesToArray(modelCapability.output),
|
|
679
|
+
tool_support: modelCapability.tool_support,
|
|
583
680
|
};
|
|
584
681
|
|
|
585
|
-
|
|
682
|
+
aiModels.push(model);
|
|
586
683
|
this.validateConnection;
|
|
587
684
|
});
|
|
588
685
|
}
|
|
589
686
|
|
|
590
687
|
//add inference profiles
|
|
591
|
-
if (
|
|
592
|
-
|
|
688
|
+
if (inferenceProfilesList?.inferenceProfileSummaries) {
|
|
689
|
+
inferenceProfilesList.inferenceProfileSummaries.forEach((p) => {
|
|
593
690
|
if (!p.inferenceProfileArn) {
|
|
594
691
|
throw new Error("Profile ARN not found");
|
|
595
692
|
}
|
|
596
693
|
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
694
|
+
// Apply the same filtering logic to inference profiles based on their name
|
|
695
|
+
const profileId = p.inferenceProfileId || "";
|
|
696
|
+
const profileName = p.inferenceProfileName || "";
|
|
697
|
+
|
|
698
|
+
// Extract provider name from profile name or ID
|
|
699
|
+
let providerName = "";
|
|
700
|
+
for (const provider of supportedPublishers) {
|
|
701
|
+
if (profileName.toLowerCase().includes(provider) || profileId.toLowerCase().includes(provider)) {
|
|
702
|
+
providerName = provider;
|
|
703
|
+
break;
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
const modelCapability = getModelCapabilities(p.inferenceProfileArn ?? p.inferenceProfileId, this.provider);
|
|
708
|
+
|
|
709
|
+
if (providerName && shouldIncludeModel(profileId, providerName)) {
|
|
710
|
+
const model: AIModel = {
|
|
711
|
+
id: p.inferenceProfileArn ?? p.inferenceProfileId,
|
|
712
|
+
name: p.inferenceProfileName ?? p.inferenceProfileArn,
|
|
713
|
+
provider: this.provider,
|
|
714
|
+
input_modalities: modelModalitiesToArray(modelCapability.input),
|
|
715
|
+
output_modalities: modelModalitiesToArray(modelCapability.output),
|
|
716
|
+
tool_support: modelCapability.tool_support,
|
|
717
|
+
};
|
|
602
718
|
|
|
603
|
-
|
|
719
|
+
aiModels.push(model);
|
|
720
|
+
}
|
|
604
721
|
});
|
|
605
722
|
}
|
|
606
723
|
|
|
607
|
-
return
|
|
724
|
+
return aiModels;
|
|
608
725
|
}
|
|
609
726
|
|
|
610
727
|
async generateEmbeddings({ text, image, model }: EmbeddingsOptions): Promise<EmbeddingsResult> {
|
|
@@ -666,4 +783,56 @@ function jobInfo(job: GetModelCustomizationJobCommandOutput, jobId: string): Tra
|
|
|
666
783
|
status,
|
|
667
784
|
details
|
|
668
785
|
}
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
function getToolDefinitions(tools?: ToolDefinition[]): Tool[] | undefined {
|
|
789
|
+
return tools ? tools.map(getToolDefinition) : undefined;
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
function getToolDefinition(tool: ToolDefinition): Tool.ToolSpecMember {
|
|
793
|
+
return {
|
|
794
|
+
toolSpec: {
|
|
795
|
+
name: tool.name,
|
|
796
|
+
description: tool.description,
|
|
797
|
+
inputSchema: {
|
|
798
|
+
json: tool.input_schema as any,
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
/**
|
|
805
|
+
* Update the conversation messages
|
|
806
|
+
* @param prompt
|
|
807
|
+
* @param response
|
|
808
|
+
* @returns
|
|
809
|
+
*/
|
|
810
|
+
function updateConversation(conversation: ConverseRequest, prompt: ConverseRequest): ConverseRequest {
|
|
811
|
+
return {
|
|
812
|
+
...conversation,
|
|
813
|
+
...prompt,
|
|
814
|
+
messages: [...(conversation?.messages || []), ...(prompt.messages || [])],
|
|
815
|
+
system: prompt.system || conversation?.system,
|
|
816
|
+
};
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
function formatAmazonModalities(modalities: ModelModality[]): string[] {
|
|
820
|
+
const standardizedModalities: string[] = [];
|
|
821
|
+
for (const modality of modalities) {
|
|
822
|
+
if (modality === ModelModality.TEXT) {
|
|
823
|
+
standardizedModalities.push("text");
|
|
824
|
+
} else if (modality === ModelModality.IMAGE) {
|
|
825
|
+
standardizedModalities.push("image");
|
|
826
|
+
} else if (modality === ModelModality.EMBEDDING) {
|
|
827
|
+
standardizedModalities.push("embedding");
|
|
828
|
+
} else if (modality == "SPEECH") {
|
|
829
|
+
standardizedModalities.push("audio");
|
|
830
|
+
} else if (modality == "VIDEO") {
|
|
831
|
+
standardizedModalities.push("video");
|
|
832
|
+
} else {
|
|
833
|
+
// Handle other modalities as needed
|
|
834
|
+
standardizedModalities.push((modality as string).toString().toLowerCase());
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
return standardizedModalities;
|
|
669
838
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { ExecutionOptions } from "@llumiverse/core";
|
|
1
|
+
import { ExecutionOptions, NovaCanvasOptions } from "@llumiverse/core";
|
|
2
2
|
import { NovaMessage, NovaMessagesPrompt } from "@llumiverse/core/formatters";
|
|
3
|
-
import { NovaCanvasOptions } from "../../../core/src/options/bedrock.js";
|
|
4
3
|
|
|
5
4
|
function getFirstImageFromPrompt(prompt: NovaMessage[]) {
|
|
6
5
|
|
package/src/bedrock/s3.ts
CHANGED
|
@@ -59,3 +59,51 @@ export async function forceUploadFile(s3: S3Client, source: ReadableStream, buck
|
|
|
59
59
|
await tryCreateBucket(s3, bucketName);
|
|
60
60
|
return uploadFile(s3, source, bucketName, file, onProgress);
|
|
61
61
|
}
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Parse an S3 HTTPS URL into an S3 URI format
|
|
66
|
+
* s3Url - The S3 HTTPS URL (e.g., https://bucket.s3.region.amazonaws.com/key)
|
|
67
|
+
* returns The S3 URI (e.g., s3://bucket/key)
|
|
68
|
+
*/
|
|
69
|
+
export function parseS3UrlToUri(s3Url: URL) {
|
|
70
|
+
try {
|
|
71
|
+
const url = new URL(s3Url);
|
|
72
|
+
|
|
73
|
+
// Extract the hostname which contains the bucket and S3 endpoint
|
|
74
|
+
const hostname = url.hostname;
|
|
75
|
+
|
|
76
|
+
// Parse the hostname to extract the bucket name
|
|
77
|
+
let bucketName;
|
|
78
|
+
if (hostname.endsWith('.amazonaws.com')) {
|
|
79
|
+
if (hostname.includes('.s3.')) {
|
|
80
|
+
// Format: bucket-name.s3.region.amazonaws.com
|
|
81
|
+
bucketName = hostname.split('.s3.')[0];
|
|
82
|
+
} else if (hostname.startsWith('s3.')) {
|
|
83
|
+
// Format: s3.region.amazonaws.com/bucket-name
|
|
84
|
+
// In this case, the bucket is actually in the first segment of the pathname
|
|
85
|
+
bucketName = url.pathname.split('/')[1];
|
|
86
|
+
// Adjust the pathname to remove the bucket name
|
|
87
|
+
const pathParts = url.pathname.split('/').slice(2);
|
|
88
|
+
url.pathname = '/' + pathParts.join('/');
|
|
89
|
+
} else {
|
|
90
|
+
throw new Error('Unable to determine bucket name from URL');
|
|
91
|
+
}
|
|
92
|
+
} else {
|
|
93
|
+
throw new Error('Unable to determine bucket name from URL');
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// The key is the pathname without the leading slash
|
|
97
|
+
// If we had the bucket name in the path, it's already been removed above
|
|
98
|
+
let key = url.pathname;
|
|
99
|
+
if (key.startsWith('/')) {
|
|
100
|
+
key = key.substring(1);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Construct the S3 URI
|
|
104
|
+
return `s3://${bucketName}/${key}`;
|
|
105
|
+
} catch (error) {
|
|
106
|
+
console.error('Error parsing S3 URL:', error);
|
|
107
|
+
throw error;
|
|
108
|
+
}
|
|
109
|
+
}
|
package/src/groq/index.ts
CHANGED
|
@@ -28,7 +28,7 @@ export class GroqDriver extends AbstractDriver<GroqDriverOptions, OpenAITextMess
|
|
|
28
28
|
|
|
29
29
|
// protected canStream(options: ExecutionOptions): Promise<boolean> {
|
|
30
30
|
// if (options.result_schema) {
|
|
31
|
-
// // not yet
|
|
31
|
+
// // not yet streaming json responses
|
|
32
32
|
// return Promise.resolve(false);
|
|
33
33
|
// } else {
|
|
34
34
|
// return Promise.resolve(true);
|
|
@@ -59,7 +59,7 @@ export class GroqDriver extends AbstractDriver<GroqDriverOptions, OpenAITextMess
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
async requestTextCompletion(messages: OpenAITextMessage[], options: ExecutionOptions): Promise<Completion<any>> {
|
|
62
|
-
if (options.model_options?._option_id !== "text-fallback") {
|
|
62
|
+
if (options.model_options?._option_id !== "text-fallback" && options.model_options?._option_id !== "groq-deepseek-thinking") {
|
|
63
63
|
this.logger.warn("Invalid model options", {options: options.model_options });
|
|
64
64
|
}
|
|
65
65
|
options.model_options = options.model_options as TextFallbackOptions;
|
|
@@ -130,7 +130,7 @@ export class GroqDriver extends AbstractDriver<GroqDriverOptions, OpenAITextMess
|
|
|
130
130
|
throw new Error("No models found");
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
-
const
|
|
133
|
+
const aiModels = models.data?.map(m => {
|
|
134
134
|
if (!m.id) {
|
|
135
135
|
throw new Error("Model id is missing");
|
|
136
136
|
}
|
|
@@ -143,7 +143,7 @@ export class GroqDriver extends AbstractDriver<GroqDriverOptions, OpenAITextMess
|
|
|
143
143
|
}
|
|
144
144
|
});
|
|
145
145
|
|
|
146
|
-
return
|
|
146
|
+
return aiModels;
|
|
147
147
|
}
|
|
148
148
|
|
|
149
149
|
validateConnection(): Promise<boolean> {
|
package/src/mistral/index.ts
CHANGED
|
@@ -45,7 +45,7 @@ export class MistralAIDriver extends AbstractDriver<MistralAIDriverOptions, Open
|
|
|
45
45
|
// return _options.result_schema ? responseFormatJson : responseFormatText;
|
|
46
46
|
|
|
47
47
|
//TODO remove this when Mistral properly supports the parameters - it makes an error for now
|
|
48
|
-
// some models like mixtral
|
|
48
|
+
// some models like mixtral mistral tiny or medium are throwing an error when using the response_format parameter
|
|
49
49
|
return undefined
|
|
50
50
|
}
|
|
51
51
|
|
|
@@ -130,7 +130,7 @@ export class MistralAIDriver extends AbstractDriver<MistralAIDriverOptions, Open
|
|
|
130
130
|
async listModels(): Promise<AIModel<string>[]> {
|
|
131
131
|
const models: ListModelsResponse = await this.client.get('v1/models');
|
|
132
132
|
|
|
133
|
-
const
|
|
133
|
+
const aiModels = models.data.map(m => {
|
|
134
134
|
return {
|
|
135
135
|
id: m.id,
|
|
136
136
|
name: m.id,
|
|
@@ -140,7 +140,7 @@ export class MistralAIDriver extends AbstractDriver<MistralAIDriverOptions, Open
|
|
|
140
140
|
}
|
|
141
141
|
});
|
|
142
142
|
|
|
143
|
-
return
|
|
143
|
+
return aiModels;
|
|
144
144
|
}
|
|
145
145
|
|
|
146
146
|
validateConnection(): Promise<boolean> {
|
|
@@ -158,7 +158,7 @@ export class MistralAIDriver extends AbstractDriver<MistralAIDriverOptions, Open
|
|
|
158
158
|
return {
|
|
159
159
|
values: r.data[0].embedding,
|
|
160
160
|
model,
|
|
161
|
-
token_count: r.usage.total_tokens
|
|
161
|
+
token_count: r.usage.total_tokens || r.usage.prompt_tokens + r.usage.completion_tokens,
|
|
162
162
|
}
|
|
163
163
|
}
|
|
164
164
|
|
package/src/openai/azure.ts
CHANGED
|
@@ -8,7 +8,7 @@ export interface AzureOpenAIDriverOptions extends DriverOptions {
|
|
|
8
8
|
/**
|
|
9
9
|
* The credentials to use to access Azure OpenAI
|
|
10
10
|
*/
|
|
11
|
-
azureADTokenProvider?: any; //type with azure
|
|
11
|
+
azureADTokenProvider?: any; //type with azure credentials
|
|
12
12
|
|
|
13
13
|
apiKey?: string;
|
|
14
14
|
|
|
@@ -37,7 +37,7 @@ export class AzureOpenAIDriver extends BaseOpenAIDriver {
|
|
|
37
37
|
apiKey: opts.apiKey,
|
|
38
38
|
azureADTokenProvider: opts.azureADTokenProvider,
|
|
39
39
|
endpoint: opts.endpoint,
|
|
40
|
-
apiVersion: opts.apiVersion ?? "2024-
|
|
40
|
+
apiVersion: opts.apiVersion ?? "2024-10-21",
|
|
41
41
|
deployment: opts.deployment
|
|
42
42
|
});
|
|
43
43
|
this.provider = "azure_openai";
|