@llumiverse/drivers 0.22.0-dev.1 → 0.22.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (140) hide show
  1. package/lib/cjs/adobe/firefly.js +2 -2
  2. package/lib/cjs/adobe/firefly.js.map +1 -1
  3. package/lib/cjs/azure/azure_foundry.js +11 -11
  4. package/lib/cjs/azure/azure_foundry.js.map +1 -1
  5. package/lib/cjs/bedrock/index.js +154 -11
  6. package/lib/cjs/bedrock/index.js.map +1 -1
  7. package/lib/cjs/bedrock/twelvelabs.js +87 -0
  8. package/lib/cjs/bedrock/twelvelabs.js.map +1 -0
  9. package/lib/cjs/groq/index.js +3 -3
  10. package/lib/cjs/groq/index.js.map +1 -1
  11. package/lib/cjs/huggingface_ie.js +2 -2
  12. package/lib/cjs/huggingface_ie.js.map +1 -1
  13. package/lib/cjs/mistral/index.js +2 -2
  14. package/lib/cjs/mistral/index.js.map +1 -1
  15. package/lib/cjs/openai/azure_openai.js +1 -1
  16. package/lib/cjs/openai/azure_openai.js.map +1 -1
  17. package/lib/cjs/openai/index.js +9 -5
  18. package/lib/cjs/openai/index.js.map +1 -1
  19. package/lib/cjs/replicate.js +3 -3
  20. package/lib/cjs/replicate.js.map +1 -1
  21. package/lib/cjs/togetherai/index.js +2 -2
  22. package/lib/cjs/togetherai/index.js.map +1 -1
  23. package/lib/cjs/vertexai/index.js +81 -30
  24. package/lib/cjs/vertexai/index.js.map +1 -1
  25. package/lib/cjs/vertexai/models/claude.js +29 -7
  26. package/lib/cjs/vertexai/models/claude.js.map +1 -1
  27. package/lib/cjs/vertexai/models/gemini.js +13 -2
  28. package/lib/cjs/vertexai/models/gemini.js.map +1 -1
  29. package/lib/cjs/vertexai/models/imagen.js +2 -2
  30. package/lib/cjs/vertexai/models/imagen.js.map +1 -1
  31. package/lib/cjs/vertexai/models.js +13 -2
  32. package/lib/cjs/vertexai/models.js.map +1 -1
  33. package/lib/cjs/watsonx/index.js +3 -3
  34. package/lib/cjs/watsonx/index.js.map +1 -1
  35. package/lib/esm/adobe/firefly.js +2 -2
  36. package/lib/esm/adobe/firefly.js.map +1 -1
  37. package/lib/esm/azure/azure_foundry.js +11 -11
  38. package/lib/esm/azure/azure_foundry.js.map +1 -1
  39. package/lib/esm/bedrock/index.js +154 -11
  40. package/lib/esm/bedrock/index.js.map +1 -1
  41. package/lib/esm/bedrock/twelvelabs.js +84 -0
  42. package/lib/esm/bedrock/twelvelabs.js.map +1 -0
  43. package/lib/esm/groq/index.js +3 -3
  44. package/lib/esm/groq/index.js.map +1 -1
  45. package/lib/esm/huggingface_ie.js +2 -2
  46. package/lib/esm/huggingface_ie.js.map +1 -1
  47. package/lib/esm/mistral/index.js +2 -2
  48. package/lib/esm/mistral/index.js.map +1 -1
  49. package/lib/esm/openai/azure_openai.js +1 -1
  50. package/lib/esm/openai/azure_openai.js.map +1 -1
  51. package/lib/esm/openai/index.js +9 -5
  52. package/lib/esm/openai/index.js.map +1 -1
  53. package/lib/esm/replicate.js +3 -3
  54. package/lib/esm/replicate.js.map +1 -1
  55. package/lib/esm/src/bedrock/index.js +150 -7
  56. package/lib/esm/src/bedrock/index.js.map +1 -1
  57. package/lib/esm/src/bedrock/twelvelabs.js +84 -0
  58. package/lib/esm/src/bedrock/twelvelabs.js.map +1 -0
  59. package/lib/esm/src/groq/index.js +1 -1
  60. package/lib/esm/src/groq/index.js.map +1 -1
  61. package/lib/esm/src/huggingface_ie.js +3 -2
  62. package/lib/esm/src/huggingface_ie.js.map +1 -1
  63. package/lib/esm/src/index.js +2 -2
  64. package/lib/esm/src/index.js.map +1 -1
  65. package/lib/esm/src/openai/index.js +6 -2
  66. package/lib/esm/src/openai/index.js.map +1 -1
  67. package/lib/esm/src/replicate.js +1 -1
  68. package/lib/esm/src/replicate.js.map +1 -1
  69. package/lib/esm/src/test-driver/TestErrorCompletionStream.js +16 -0
  70. package/lib/esm/src/test-driver/TestErrorCompletionStream.js.map +1 -0
  71. package/lib/esm/src/test-driver/TestValidationErrorCompletionStream.js +20 -0
  72. package/lib/esm/src/test-driver/TestValidationErrorCompletionStream.js.map +1 -0
  73. package/lib/esm/src/test-driver/index.js +91 -0
  74. package/lib/esm/src/test-driver/index.js.map +1 -0
  75. package/lib/esm/src/test-driver/utils.js +25 -0
  76. package/lib/esm/src/test-driver/utils.js.map +1 -0
  77. package/lib/esm/src/vertexai/index.js +81 -30
  78. package/lib/esm/src/vertexai/index.js.map +1 -1
  79. package/lib/esm/src/vertexai/models/claude.js +26 -4
  80. package/lib/esm/src/vertexai/models/claude.js.map +1 -1
  81. package/lib/esm/src/vertexai/models/gemini.js +14 -3
  82. package/lib/esm/src/vertexai/models/gemini.js.map +1 -1
  83. package/lib/esm/src/vertexai/models/imagen.js +1 -1
  84. package/lib/esm/src/vertexai/models/imagen.js.map +1 -1
  85. package/lib/esm/src/vertexai/models.js +13 -2
  86. package/lib/esm/src/vertexai/models.js.map +1 -1
  87. package/lib/esm/togetherai/index.js +2 -2
  88. package/lib/esm/togetherai/index.js.map +1 -1
  89. package/lib/esm/tsconfig.tsbuildinfo +1 -1
  90. package/lib/esm/vertexai/index.js +81 -30
  91. package/lib/esm/vertexai/index.js.map +1 -1
  92. package/lib/esm/vertexai/models/claude.js +28 -6
  93. package/lib/esm/vertexai/models/claude.js.map +1 -1
  94. package/lib/esm/vertexai/models/gemini.js +14 -3
  95. package/lib/esm/vertexai/models/gemini.js.map +1 -1
  96. package/lib/esm/vertexai/models/imagen.js +2 -2
  97. package/lib/esm/vertexai/models/imagen.js.map +1 -1
  98. package/lib/esm/vertexai/models.js +13 -2
  99. package/lib/esm/vertexai/models.js.map +1 -1
  100. package/lib/esm/watsonx/index.js +3 -3
  101. package/lib/esm/watsonx/index.js.map +1 -1
  102. package/lib/types/bedrock/index.d.ts +7 -3
  103. package/lib/types/bedrock/index.d.ts.map +1 -1
  104. package/lib/types/bedrock/twelvelabs.d.ts +50 -0
  105. package/lib/types/bedrock/twelvelabs.d.ts.map +1 -0
  106. package/lib/types/groq/index.d.ts.map +1 -1
  107. package/lib/types/openai/index.d.ts.map +1 -1
  108. package/lib/types/replicate.d.ts.map +1 -1
  109. package/lib/types/src/bedrock/index.d.ts +7 -3
  110. package/lib/types/src/bedrock/twelvelabs.d.ts +49 -0
  111. package/lib/types/src/huggingface_ie.d.ts +6 -6
  112. package/lib/types/src/index.d.ts +2 -2
  113. package/lib/types/src/test-driver/TestErrorCompletionStream.d.ts +8 -0
  114. package/lib/types/src/test-driver/TestValidationErrorCompletionStream.d.ts +8 -0
  115. package/lib/types/src/test-driver/index.d.ts +23 -0
  116. package/lib/types/src/test-driver/utils.d.ts +4 -0
  117. package/lib/types/src/vertexai/index.d.ts +11 -11
  118. package/lib/types/src/vertexai/models/claude.d.ts +2 -0
  119. package/lib/types/vertexai/index.d.ts +11 -11
  120. package/lib/types/vertexai/index.d.ts.map +1 -1
  121. package/lib/types/vertexai/models/claude.d.ts +2 -0
  122. package/lib/types/vertexai/models/claude.d.ts.map +1 -1
  123. package/lib/types/vertexai/models/gemini.d.ts.map +1 -1
  124. package/lib/types/vertexai/models.d.ts.map +1 -1
  125. package/package.json +85 -85
  126. package/src/bedrock/index.ts +183 -10
  127. package/src/bedrock/twelvelabs.ts +150 -0
  128. package/src/groq/index.ts +4 -3
  129. package/src/huggingface_ie.ts +8 -7
  130. package/src/index.ts +2 -2
  131. package/src/openai/index.ts +6 -2
  132. package/src/replicate.ts +1 -1
  133. package/src/vertexai/index.ts +56 -3
  134. package/src/vertexai/models/claude.ts +30 -4
  135. package/src/vertexai/models/gemini.ts +16 -5
  136. package/src/vertexai/models.ts +14 -2
  137. /package/src/{test-driver → test}/TestErrorCompletionStream.ts +0 -0
  138. /package/src/{test-driver → test}/TestValidationErrorCompletionStream.ts +0 -0
  139. /package/src/{test-driver → test}/index.ts +0 -0
  140. /package/src/{test-driver → test}/utils.ts +0 -0
package/package.json CHANGED
@@ -1,87 +1,87 @@
1
1
  {
2
- "name": "@llumiverse/drivers",
3
- "version": "0.22.0-dev.1",
4
- "type": "module",
5
- "description": "LLM driver implementations. Currently supported are: openai, huggingface, bedrock, replicate.",
6
- "files": [
7
- "lib",
8
- "src"
9
- ],
10
- "types": "./lib/types/index.d.ts",
11
- "exports": {
2
+ "name": "@llumiverse/drivers",
3
+ "version": "0.22.1",
4
+ "type": "module",
5
+ "description": "LLM driver implementations. Currently supported are: openai, huggingface, bedrock, replicate.",
6
+ "files": [
7
+ "lib",
8
+ "src"
9
+ ],
12
10
  "types": "./lib/types/index.d.ts",
13
- "import": "./lib/esm/index.js",
14
- "require": "./lib/cjs/index.js"
15
- },
16
- "author": "Llumiverse",
17
- "license": "Apache-2.0",
18
- "homepage": "https://github.com/vertesia/llumiverse",
19
- "repository": {
20
- "type": "git",
21
- "url": "git+ssh://git@github.com/vertesia/llumiverse.git"
22
- },
23
- "keywords": [
24
- "llm",
25
- "ai",
26
- "prompt",
27
- "prompt engineering",
28
- "ml",
29
- "machine learning",
30
- "embeddings",
31
- "training",
32
- "model",
33
- "universal",
34
- "api",
35
- "chatgpt",
36
- "openai",
37
- "vertexai",
38
- "bedrock",
39
- "replicate",
40
- "huggingface",
41
- "togetherai"
42
- ],
43
- "devDependencies": {
44
- "dotenv": "^16.6.1",
45
- "rimraf": "^6.0.1",
46
- "ts-dual-module": "^0.6.3",
47
- "typescript": "^5.9.2",
48
- "vitest": "^3.2.4"
49
- },
50
- "dependencies": {
51
- "@anthropic-ai/sdk": "^0.63.0",
52
- "@anthropic-ai/vertex-sdk": "^0.14.0",
53
- "@aws-sdk/client-bedrock": "^3.894.0",
54
- "@aws-sdk/client-bedrock-runtime": "^3.894.0",
55
- "@aws-sdk/client-s3": "^3.894.0",
56
- "@aws-sdk/credential-providers": "^3.894.0",
57
- "@aws-sdk/lib-storage": "^3.894.0",
58
- "@aws-sdk/types": "^3.893.0",
59
- "@azure-rest/ai-inference": "1.0.0-beta.6",
60
- "@azure/ai-projects": "1.0.0-beta.10",
61
- "@azure/core-auth": "^1.10.1",
62
- "@azure/core-sse": "^2.3.0",
63
- "@azure/identity": "^4.12.0",
64
- "@azure/openai": "2.0.0",
65
- "@google-cloud/aiplatform": "^3.35.0",
66
- "@google/genai": "^1.20.0",
67
- "@huggingface/inference": "^4.8.0",
68
- "@vertesia/api-fetch-client": "^0.78.0",
69
- "eventsource": "^4.0.0",
70
- "google-auth-library": "^9.15.1",
71
- "groq-sdk": "^0.32.0",
72
- "mnemonist": "^0.40.3",
73
- "node-web-stream-adapters": "^0.2.1",
74
- "openai": "^4.104.0",
75
- "replicate": "^1.2.0",
76
- "@llumiverse/common": "0.22.0-dev.1",
77
- "@llumiverse/core": "0.22.0-dev.1"
78
- },
79
- "ts_dual_module": {
80
- "outDir": "lib"
81
- },
82
- "scripts": {
83
- "test": "vitest run --retry 3",
84
- "build": "pnpm exec tsmod build",
85
- "clean": "rimraf ./lib tsconfig.tsbuildinfo"
86
- }
87
- }
11
+ "exports": {
12
+ "types": "./lib/types/index.d.ts",
13
+ "import": "./lib/esm/index.js",
14
+ "require": "./lib/cjs/index.js"
15
+ },
16
+ "scripts": {
17
+ "test": "vitest run --retry 3",
18
+ "build": "pnpm exec tsmod build",
19
+ "clean": "rimraf ./lib tsconfig.tsbuildinfo"
20
+ },
21
+ "author": "Llumiverse",
22
+ "license": "Apache-2.0",
23
+ "homepage": "https://github.com/vertesia/llumiverse",
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "git+ssh://git@github.com/vertesia/llumiverse.git"
27
+ },
28
+ "keywords": [
29
+ "llm",
30
+ "ai",
31
+ "prompt",
32
+ "prompt engineering",
33
+ "ml",
34
+ "machine learning",
35
+ "embeddings",
36
+ "training",
37
+ "model",
38
+ "universal",
39
+ "api",
40
+ "chatgpt",
41
+ "openai",
42
+ "vertexai",
43
+ "bedrock",
44
+ "replicate",
45
+ "huggingface",
46
+ "togetherai"
47
+ ],
48
+ "devDependencies": {
49
+ "dotenv": "^16.6.1",
50
+ "rimraf": "^6.0.1",
51
+ "ts-dual-module": "^0.6.3",
52
+ "typescript": "^5.9.2",
53
+ "vitest": "^3.2.4"
54
+ },
55
+ "dependencies": {
56
+ "@anthropic-ai/sdk": "^0.66.0",
57
+ "@anthropic-ai/vertex-sdk": "^0.14.0",
58
+ "@aws-sdk/client-bedrock": "^3.840.0",
59
+ "@aws-sdk/client-bedrock-runtime": "^3.840.0",
60
+ "@aws-sdk/client-s3": "^3.840.0",
61
+ "@aws-sdk/credential-providers": "^3.840.0",
62
+ "@aws-sdk/lib-storage": "^3.840.0",
63
+ "@aws-sdk/types": "^3.840.0",
64
+ "@azure-rest/ai-inference": "1.0.0-beta.6",
65
+ "@azure/ai-projects": "1.0.0-beta.10",
66
+ "@azure/core-auth": "^1.10.0",
67
+ "@azure/core-sse": "^2.3.0",
68
+ "@azure/identity": "^4.10.1",
69
+ "@azure/openai": "2.0.0",
70
+ "@google-cloud/aiplatform": "^3.35.0",
71
+ "@google/genai": "^1.25.0",
72
+ "@huggingface/inference": "2.6.7",
73
+ "@llumiverse/common": "workspace:*",
74
+ "@llumiverse/core": "workspace:*",
75
+ "@vertesia/api-fetch-client": "^0.74.0",
76
+ "eventsource": "^4.0.0",
77
+ "google-auth-library": "^9.15.1",
78
+ "groq-sdk": "^0.34.0",
79
+ "mnemonist": "^0.40.3",
80
+ "node-web-stream-adapters": "^0.2.1",
81
+ "openai": "^4.104.0",
82
+ "replicate": "^1.0.1"
83
+ },
84
+ "ts_dual_module": {
85
+ "outDir": "lib"
86
+ }
87
+ }
@@ -20,6 +20,12 @@ import { LRUCache } from "mnemonist";
20
20
  import { converseConcatMessages, converseJSONprefill, converseSystemToMessages, formatConversePrompt } from "./converse.js";
21
21
  import { formatNovaImageGenerationPayload, NovaImageGenerationTaskType } from "./nova-image-payload.js";
22
22
  import { forceUploadFile } from "./s3.js";
23
+ import {
24
+ formatTwelvelabsPegasusPrompt,
25
+ TwelvelabsPegasusRequest,
26
+ TwelvelabsMarengoRequest,
27
+ TwelvelabsMarengoResponse
28
+ } from "./twelvelabs.js";
23
29
 
24
30
  const supportStreamingCache = new LRUCache<string, boolean>(4096);
25
31
 
@@ -84,7 +90,7 @@ function maxTokenFallbackClaude(option: StatelessExecutionOptions): number {
84
90
  }
85
91
  }
86
92
 
87
- export type BedrockPrompt = NovaMessagesPrompt | ConverseRequest;
93
+ export type BedrockPrompt = NovaMessagesPrompt | ConverseRequest | TwelvelabsPegasusRequest;
88
94
 
89
95
  export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockPrompt> {
90
96
 
@@ -129,6 +135,9 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
129
135
  if (opts.model.includes("canvas")) {
130
136
  return await formatNovaPrompt(segments, opts.result_schema);
131
137
  }
138
+ if (opts.model.includes("twelvelabs.pegasus")) {
139
+ return await formatTwelvelabsPegasusPrompt(segments, opts);
140
+ }
132
141
  return await formatConversePrompt(segments, opts);
133
142
  }
134
143
 
@@ -320,6 +329,11 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
320
329
  }
321
330
 
322
331
  protected async canStream(options: ExecutionOptions): Promise<boolean> {
332
+ // // TwelveLabs Pegasus supports streaming according to the documentation
333
+ // if (options.model.includes("twelvelabs.pegasus")) {
334
+ // return true;
335
+ // }
336
+
323
337
  let canStream = supportStreamingCache.get(options.model);
324
338
  if (canStream == null) {
325
339
  let type = BedrockModelType.Unknown;
@@ -336,8 +350,15 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
336
350
  return canStream;
337
351
  }
338
352
 
339
- async requestTextCompletion(prompt: ConverseRequest, options: ExecutionOptions): Promise<Completion> {
340
- let conversation = updateConversation(options.conversation as ConverseRequest, prompt);
353
+ async requestTextCompletion(prompt: BedrockPrompt, options: ExecutionOptions): Promise<Completion> {
354
+ // Handle Twelvelabs Pegasus models
355
+ if (options.model.includes("twelvelabs.pegasus")) {
356
+ return this.requestTwelvelabsPegasusCompletion(prompt as TwelvelabsPegasusRequest, options);
357
+ }
358
+
359
+ // Handle other Bedrock models that use Converse API
360
+ const conversePrompt = prompt as ConverseRequest;
361
+ let conversation = updateConversation(options.conversation as ConverseRequest, conversePrompt);
341
362
 
342
363
  const payload = this.preparePayload(conversation, options);
343
364
  const executor = this.getExecutor();
@@ -348,7 +369,7 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
348
369
 
349
370
  conversation = updateConversation(conversation, {
350
371
  messages: [res.output?.message ?? { content: [{ text: "" }], role: "assistant" }],
351
- modelId: prompt.modelId,
372
+ modelId: conversePrompt.modelId,
352
373
  });
353
374
 
354
375
  let tool_use: ToolUse[] | undefined = undefined;
@@ -369,7 +390,7 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
369
390
  }
370
391
 
371
392
  const completion = {
372
- ...this.getExtractedExecution(res, prompt, options),
393
+ ...this.getExtractedExecution(res, conversePrompt, options),
373
394
  original_response: options.include_original_response ? res : undefined,
374
395
  conversation: conversation,
375
396
  tool_use: tool_use,
@@ -378,8 +399,104 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
378
399
  return completion;
379
400
  }
380
401
 
381
- async requestTextCompletionStream(prompt: ConverseRequest, options: ExecutionOptions): Promise<AsyncIterable<CompletionChunkObject>> {
382
- const payload = this.preparePayload(prompt, options);
402
+ private async requestTwelvelabsPegasusCompletion(prompt: TwelvelabsPegasusRequest, options: ExecutionOptions): Promise<Completion> {
403
+ const executor = this.getExecutor();
404
+
405
+ const res = await executor.invokeModel({
406
+ modelId: options.model,
407
+ contentType: "application/json",
408
+ accept: "application/json",
409
+ body: JSON.stringify(prompt),
410
+ });
411
+
412
+ const decoder = new TextDecoder();
413
+ const body = decoder.decode(res.body);
414
+ const result = JSON.parse(body);
415
+
416
+ // Extract the response according to TwelveLabs Pegasus format
417
+ let finishReason: string | undefined;
418
+ switch (result.finishReason) {
419
+ case "stop":
420
+ finishReason = "stop";
421
+ break;
422
+ case "length":
423
+ finishReason = "length";
424
+ break;
425
+ default:
426
+ finishReason = result.finishReason;
427
+ }
428
+
429
+ return {
430
+ result: result.message ? [{ type: "text" as const, value: result.message }] : [],
431
+ finish_reason: finishReason,
432
+ original_response: options.include_original_response ? result : undefined,
433
+ };
434
+ }
435
+
436
+ private async requestTwelvelabsPegasusCompletionStream(prompt: TwelvelabsPegasusRequest, options: ExecutionOptions): Promise<AsyncIterable<CompletionChunkObject>> {
437
+ const executor = this.getExecutor();
438
+
439
+ const res = await executor.invokeModelWithResponseStream({
440
+ modelId: options.model,
441
+ contentType: "application/json",
442
+ accept: "application/json",
443
+ body: JSON.stringify(prompt),
444
+ });
445
+
446
+ if (!res.body) {
447
+ throw new Error("[Bedrock] Stream not found in response");
448
+ }
449
+
450
+ return transformAsyncIterator(res.body, (chunk: any) => {
451
+ if (chunk.chunk?.bytes) {
452
+ const decoder = new TextDecoder();
453
+ const body = decoder.decode(chunk.chunk.bytes);
454
+
455
+ try {
456
+ const result = JSON.parse(body);
457
+
458
+ // Extract streaming response according to TwelveLabs Pegasus format
459
+ let finishReason: string | undefined;
460
+ if (result.finishReason) {
461
+ switch (result.finishReason) {
462
+ case "stop":
463
+ finishReason = "stop";
464
+ break;
465
+ case "length":
466
+ finishReason = "length";
467
+ break;
468
+ default:
469
+ finishReason = result.finishReason;
470
+ }
471
+ }
472
+
473
+ return {
474
+ result: result.delta || result.message ? [{ type: "text" as const, value: result.delta || result.message || "" }] : [],
475
+ finish_reason: finishReason,
476
+ } satisfies CompletionChunkObject;
477
+ } catch (error) {
478
+ // If JSON parsing fails, return empty chunk
479
+ return {
480
+ result: [],
481
+ } satisfies CompletionChunkObject;
482
+ }
483
+ }
484
+
485
+ return {
486
+ result: [],
487
+ } satisfies CompletionChunkObject;
488
+ });
489
+ }
490
+
491
+ async requestTextCompletionStream(prompt: BedrockPrompt, options: ExecutionOptions): Promise<AsyncIterable<CompletionChunkObject>> {
492
+ // Handle Twelvelabs Pegasus models
493
+ if (options.model.includes("twelvelabs.pegasus")) {
494
+ return this.requestTwelvelabsPegasusCompletionStream(prompt as TwelvelabsPegasusRequest, options);
495
+ }
496
+
497
+ // Handle other Bedrock models that use Converse API
498
+ const conversePrompt = prompt as ConverseRequest;
499
+ const payload = this.preparePayload(conversePrompt, options);
383
500
  const executor = this.getExecutor();
384
501
  return executor.converseStream({
385
502
  ...payload,
@@ -391,7 +508,7 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
391
508
  }
392
509
 
393
510
  return transformAsyncIterator(stream, (streamSegment: ConverseStreamOutput) => {
394
- return this.getExtractedStream(streamSegment, prompt, options);
511
+ return this.getExtractedStream(streamSegment, conversePrompt, options);
395
512
  });
396
513
 
397
514
  }).catch((err) => {
@@ -703,17 +820,21 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
703
820
  foundationModels = foundationModels.filter(foundationFilter);
704
821
  }
705
822
 
706
- const supportedPublishers = ["amazon", "anthropic", "cohere", "ai21", "mistral", "meta", "deepseek", "writer", "openai"];
823
+ const supportedPublishers = ["amazon", "anthropic", "cohere", "ai21",
824
+ "mistral", "meta", "deepseek", "writer",
825
+ "openai", "twelvelabs", "qwen"];
707
826
  const unsupportedModelsByPublisher = {
708
827
  amazon: ["titan-image-generator", "nova-reel", "nova-sonic", "rerank"],
709
828
  anthropic: [],
710
- cohere: ["rerank"],
829
+ cohere: ["rerank", "embed"],
711
830
  ai21: [],
712
831
  mistral: [],
713
832
  meta: [],
714
833
  deepseek: [],
715
834
  writer: [],
716
835
  openai: [],
836
+ twelvelabs: ["marengo"],
837
+ qwen: [],
717
838
  };
718
839
 
719
840
  // Helper function to check if model should be filtered out
@@ -839,6 +960,13 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
839
960
  async generateEmbeddings({ text, image, model }: EmbeddingsOptions): Promise<EmbeddingsResult> {
840
961
 
841
962
  this.logger.info("[Bedrock] Generating embeddings with model " + model);
963
+
964
+ // Handle TwelveLabs Marengo models
965
+ if (model?.includes("twelvelabs.marengo")) {
966
+ return this.generateTwelvelabsMarengoEmbeddings({ text, image, model });
967
+ }
968
+
969
+ // Handle other Bedrock embedding models
842
970
  const defaultModel = image ? "amazon.titan-embed-image-v1" : "amazon.titan-embed-text-v2:0";
843
971
  const modelID = model ?? defaultModel;
844
972
 
@@ -871,6 +999,51 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
871
999
  token_count: result.inputTextTokenCount
872
1000
  };
873
1001
  }
1002
+
1003
+ private async generateTwelvelabsMarengoEmbeddings({ text, image, model }: EmbeddingsOptions): Promise<EmbeddingsResult> {
1004
+ const executor = this.getExecutor();
1005
+
1006
+ // Prepare the request payload for TwelveLabs Marengo
1007
+ let invokeBody: TwelvelabsMarengoRequest = {
1008
+ inputType: "text"
1009
+ };
1010
+
1011
+ if (text) {
1012
+ invokeBody.inputText = text;
1013
+ invokeBody.inputType = "text";
1014
+ }
1015
+
1016
+ if (image) {
1017
+ // For the embeddings interface, image is expected to be base64
1018
+ invokeBody.mediaSource = {
1019
+ base64String: image
1020
+ };
1021
+ invokeBody.inputType = "image";
1022
+ }
1023
+
1024
+ const res = await executor.invokeModel({
1025
+ modelId: model!,
1026
+ contentType: "application/json",
1027
+ accept: "application/json",
1028
+ body: JSON.stringify(invokeBody),
1029
+ });
1030
+
1031
+ const decoder = new TextDecoder();
1032
+ const body = decoder.decode(res.body);
1033
+ const result: TwelvelabsMarengoResponse = JSON.parse(body);
1034
+
1035
+ // TwelveLabs Marengo returns embedding data
1036
+ if (!result.embedding) {
1037
+ throw new Error("Embeddings not found in TwelveLabs Marengo response");
1038
+ }
1039
+
1040
+ return {
1041
+ values: result.embedding,
1042
+ model: model!,
1043
+ // TwelveLabs Marengo doesn't return token count in the same way
1044
+ token_count: undefined
1045
+ };
1046
+ }
874
1047
  }
875
1048
 
876
1049
  function jobInfo(job: GetModelCustomizationJobCommandOutput, jobId: string): TrainingJob {
@@ -0,0 +1,150 @@
1
+ import { DataSource, ExecutionOptions, readStreamAsBase64 } from "@llumiverse/core";
2
+ import { PromptSegment, PromptRole } from "@llumiverse/core";
3
+
4
+ // TwelveLabs Pegasus Request/Response Types
5
+ export interface TwelvelabsPegasusRequest {
6
+ inputPrompt: string;
7
+ temperature?: number;
8
+ responseFormat?: {
9
+ type: "json_schema";
10
+ json_schema: {
11
+ name: string;
12
+ schema: any;
13
+ };
14
+ };
15
+ mediaSource: {
16
+ base64String?: string;
17
+ s3Location?: {
18
+ uri: string;
19
+ bucketOwner?: string;
20
+ };
21
+ };
22
+ maxOutputTokens?: number;
23
+ }
24
+
25
+ export interface TwelvelabsPegasusResponse {
26
+ message: string;
27
+ finishReason: "stop" | "length";
28
+ }
29
+
30
+ // TwelveLabs Marengo Request/Response Types
31
+ export interface TwelvelabsMarengoRequest {
32
+ inputType: "text" | "image" | "video" | "audio";
33
+ inputText?: string;
34
+ textTruncate?: "start" | "end";
35
+ mediaSource?: {
36
+ base64String?: string;
37
+ s3Location?: {
38
+ uri: string;
39
+ bucketOwner?: string;
40
+ };
41
+ };
42
+ embeddingOption?: "visual-text" | "visual-image" | "audio";
43
+ startSec?: number;
44
+ lengthSec?: number;
45
+ useFixedLengthSec?: boolean;
46
+ minClipSec?: number;
47
+ }
48
+
49
+ export interface TwelvelabsMarengoResponse {
50
+ embedding: number[];
51
+ embeddingOption: "visual-text" | "visual-image" | "audio";
52
+ startSec: number;
53
+ endSec: number;
54
+ }
55
+
56
+ // Convert prompt segments to TwelveLabs Pegasus request
57
+ export async function formatTwelvelabsPegasusPrompt(
58
+ segments: PromptSegment[],
59
+ options: ExecutionOptions
60
+ ): Promise<TwelvelabsPegasusRequest> {
61
+ let inputPrompt = "";
62
+ let videoFile: DataSource | undefined;
63
+
64
+ // Extract text content and video files from segments
65
+ for (const segment of segments) {
66
+ if (segment.role === PromptRole.system || segment.role === PromptRole.user) {
67
+ if (segment.content) {
68
+ inputPrompt += segment.content + "\n";
69
+ }
70
+
71
+ // Look for video files
72
+ for (const file of segment.files ?? []) {
73
+ if (file.mime_type && file.mime_type.startsWith("video/")) {
74
+ videoFile = file;
75
+ break; // Use the first video file found
76
+ }
77
+ }
78
+ }
79
+ }
80
+
81
+ if (!videoFile) {
82
+ throw new Error("TwelveLabs Pegasus requires a video file input");
83
+ }
84
+
85
+ // Prepare media source
86
+ let mediaSource: TwelvelabsPegasusRequest["mediaSource"];
87
+
88
+ try {
89
+ // Try to get S3 URL first
90
+ const url = await videoFile.getURL();
91
+ const parsedUrl = new URL(url);
92
+
93
+ if (parsedUrl.hostname.endsWith("amazonaws.com") &&
94
+ (parsedUrl.hostname.startsWith("s3.") || parsedUrl.hostname.includes(".s3."))) {
95
+ // Convert S3 URL to s3:// format
96
+ const bucketMatch = parsedUrl.hostname.match(/^(?:s3\.)?([^.]+)\.s3\./);
97
+ const bucket = bucketMatch ? bucketMatch[1] : parsedUrl.hostname.split('.')[0];
98
+ const key = parsedUrl.pathname.substring(1); // Remove leading slash
99
+
100
+ mediaSource = {
101
+ s3Location: {
102
+ uri: `s3://${bucket}/${key}`,
103
+ }
104
+ };
105
+ } else {
106
+ // Fall back to base64 encoding
107
+ const stream = await videoFile.getStream();
108
+ const base64String = await readStreamAsBase64(stream);
109
+
110
+ mediaSource = {
111
+ base64String
112
+ };
113
+ }
114
+ } catch (error) {
115
+ // If getting URL fails, use base64 encoding
116
+ const stream = await videoFile.getStream();
117
+ const base64String = await readStreamAsBase64(stream);
118
+
119
+ mediaSource = {
120
+ base64String
121
+ };
122
+ }
123
+
124
+ const request: TwelvelabsPegasusRequest = {
125
+ inputPrompt: inputPrompt.trim(),
126
+ mediaSource
127
+ };
128
+
129
+ // Add optional parameters from model options
130
+ const modelOptions = options.model_options as any;
131
+ if (modelOptions?.temperature !== undefined) {
132
+ request.temperature = modelOptions.temperature;
133
+ }
134
+ if (modelOptions?.max_tokens !== undefined) {
135
+ request.maxOutputTokens = modelOptions.max_tokens;
136
+ }
137
+
138
+ // Add response format if result schema is specified
139
+ if (options.result_schema) {
140
+ request.responseFormat = {
141
+ type: "json_schema",
142
+ json_schema: {
143
+ name: "response",
144
+ schema: options.result_schema
145
+ }
146
+ };
147
+ }
148
+
149
+ return request;
150
+ }
package/src/groq/index.ts CHANGED
@@ -4,6 +4,7 @@ import { formatOpenAILikeMultimodalPrompt } from "../openai/openai_format.js";
4
4
 
5
5
  import Groq from "groq-sdk";
6
6
  import type { ChatCompletionMessageParam, ChatCompletionTool } from "groq-sdk/resources/chat/completions";
7
+ import type { FunctionParameters } from "groq-sdk/resources/shared";
7
8
 
8
9
  interface GroqDriverOptions extends DriverOptions {
9
10
  apiKey: string;
@@ -158,7 +159,7 @@ export class GroqDriver extends AbstractDriver<GroqDriverOptions, ChatCompletion
158
159
  function: {
159
160
  name: tool.name,
160
161
  description: tool.description,
161
- parameters: tool.input_schema as any,
162
+ parameters: tool.input_schema satisfies FunctionParameters,
162
163
  }
163
164
  }));
164
165
  }
@@ -287,13 +288,13 @@ export class GroqDriver extends AbstractDriver<GroqDriverOptions, ChatCompletion
287
288
 
288
289
  return {
289
290
  result: choice.delta.content ? [{ type: "text", value: choice.delta.content }] : [],
290
- finish_reason: finish_reason,
291
+ finish_reason: finish_reason ?? undefined,
291
292
  token_usage: {
292
293
  prompt: chunk.x_groq?.usage?.prompt_tokens,
293
294
  result: chunk.x_groq?.usage?.completion_tokens,
294
295
  total: chunk.x_groq?.usage?.total_tokens,
295
296
  },
296
- } as CompletionChunkObject;
297
+ } satisfies CompletionChunkObject;
297
298
  });
298
299
  }
299
300