@llumiverse/drivers 1.1.1-dev.20260505.151157Z → 1.3.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.
Files changed (49) hide show
  1. package/lib/cjs/anthropic/index.js +64 -0
  2. package/lib/cjs/anthropic/index.js.map +1 -0
  3. package/lib/cjs/index.js +1 -0
  4. package/lib/cjs/index.js.map +1 -1
  5. package/lib/cjs/openai/index.js +12 -6
  6. package/lib/cjs/openai/index.js.map +1 -1
  7. package/lib/cjs/shared/claude-messages.js +737 -0
  8. package/lib/cjs/shared/claude-messages.js.map +1 -0
  9. package/lib/cjs/vertexai/index.js.map +1 -1
  10. package/lib/cjs/vertexai/models/claude.js +27 -872
  11. package/lib/cjs/vertexai/models/claude.js.map +1 -1
  12. package/lib/cjs/vertexai/models/gemini.js +18 -12
  13. package/lib/cjs/vertexai/models/gemini.js.map +1 -1
  14. package/lib/esm/anthropic/index.js +57 -0
  15. package/lib/esm/anthropic/index.js.map +1 -0
  16. package/lib/esm/index.js +1 -0
  17. package/lib/esm/index.js.map +1 -1
  18. package/lib/esm/openai/index.js +12 -7
  19. package/lib/esm/openai/index.js.map +1 -1
  20. package/lib/esm/shared/claude-messages.js +716 -0
  21. package/lib/esm/shared/claude-messages.js.map +1 -0
  22. package/lib/esm/vertexai/index.js.map +1 -1
  23. package/lib/esm/vertexai/models/claude.js +27 -865
  24. package/lib/esm/vertexai/models/claude.js.map +1 -1
  25. package/lib/esm/vertexai/models/gemini.js +18 -12
  26. package/lib/esm/vertexai/models/gemini.js.map +1 -1
  27. package/lib/types/anthropic/index.d.ts +21 -0
  28. package/lib/types/anthropic/index.d.ts.map +1 -0
  29. package/lib/types/index.d.ts +1 -0
  30. package/lib/types/index.d.ts.map +1 -1
  31. package/lib/types/openai/index.d.ts +1 -0
  32. package/lib/types/openai/index.d.ts.map +1 -1
  33. package/lib/types/shared/claude-messages.d.ts +75 -0
  34. package/lib/types/shared/claude-messages.d.ts.map +1 -0
  35. package/lib/types/vertexai/index.d.ts +4 -4
  36. package/lib/types/vertexai/index.d.ts.map +1 -1
  37. package/lib/types/vertexai/models/claude.d.ts +3 -106
  38. package/lib/types/vertexai/models/claude.d.ts.map +1 -1
  39. package/lib/types/vertexai/models/gemini.d.ts +1 -1
  40. package/lib/types/vertexai/models/gemini.d.ts.map +1 -1
  41. package/package.json +7 -6
  42. package/src/anthropic/index.ts +104 -0
  43. package/src/index.ts +1 -0
  44. package/src/openai/index.ts +13 -8
  45. package/src/shared/claude-messages.ts +879 -0
  46. package/src/vertexai/index.ts +18 -19
  47. package/src/vertexai/models/claude-error-handling.test.ts +3 -3
  48. package/src/vertexai/models/claude.ts +44 -1016
  49. package/src/vertexai/models/gemini.ts +27 -14
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@llumiverse/drivers",
3
- "version": "1.1.1-dev.20260505.151157Z",
3
+ "version": "1.3.0",
4
4
  "type": "module",
5
5
  "description": "LLM driver implementations. Currently supported are: openai, huggingface, bedrock, replicate.",
6
6
  "files": [
@@ -48,7 +48,7 @@
48
48
  "vitest": "^4.0.18"
49
49
  },
50
50
  "dependencies": {
51
- "@anthropic-ai/sdk": "^0.91.1",
51
+ "@anthropic-ai/sdk": "^0.96.0",
52
52
  "@anthropic-ai/vertex-sdk": "^0.16.0",
53
53
  "@aws-sdk/client-bedrock": "^3.1033.0",
54
54
  "@aws-sdk/client-bedrock-runtime": "^3.1033.0",
@@ -63,9 +63,9 @@
63
63
  "@azure/identity": "^4.13.0",
64
64
  "@azure/openai": "2.0.0",
65
65
  "@google-cloud/aiplatform": "^6.5.0",
66
- "@google/genai": "^1.49.0",
66
+ "@google/genai": "2.1.0",
67
67
  "@huggingface/inference": "4.13.11",
68
- "@vertesia/api-fetch-client": "^0.82.4",
68
+ "@vertesia/api-fetch-client": "^1.2.0",
69
69
  "eventsource": "^4.1.0",
70
70
  "google-auth-library": "^10.6.2",
71
71
  "groq-sdk": "^0.37.0",
@@ -73,13 +73,14 @@
73
73
  "node-web-stream-adapters": "^0.2.1",
74
74
  "openai": "^6.33.0",
75
75
  "replicate": "^1.4.0",
76
- "@llumiverse/common": "1.1.1-dev.20260505.151157Z",
77
- "@llumiverse/core": "1.1.1-dev.20260505.151157Z"
76
+ "@llumiverse/common": "1.3.0",
77
+ "@llumiverse/core": "1.3.0"
78
78
  },
79
79
  "ts_dual_module": {
80
80
  "outDir": "lib"
81
81
  },
82
82
  "scripts": {
83
+ "lint": "biome lint src",
83
84
  "test": "vitest run --retry 3",
84
85
  "build": "pnpm exec tsmod build",
85
86
  "clean": "rimraf ./lib tsconfig.tsbuildinfo"
@@ -0,0 +1,104 @@
1
+ import Anthropic from '@anthropic-ai/sdk';
2
+ import type { AnthropicClaudeOptions } from "@llumiverse/common";
3
+ import {
4
+ AbstractDriver,
5
+ type AIModel,
6
+ type Completion,
7
+ type CompletionChunkObject,
8
+ type DriverOptions,
9
+ type EmbeddingsOptions,
10
+ type EmbeddingsResult,
11
+ type ExecutionOptions,
12
+ LlumiverseError,
13
+ type LlumiverseErrorContext,
14
+ type ModelSearchPayload,
15
+ ModelType,
16
+ type PromptSegment,
17
+ Providers,
18
+ } from "@llumiverse/core";
19
+ import {
20
+ buildClaudeStreamingConversation,
21
+ type ClaudePrompt,
22
+ executeClaudeCompletion,
23
+ formatAnthropicLlumiverseError,
24
+ formatClaudePrompt,
25
+ streamClaudeCompletion,
26
+ } from "../shared/claude-messages.js";
27
+
28
+ export interface AnthropicDriverOptions extends DriverOptions {
29
+ apiKey?: string;
30
+ baseURL?: string;
31
+ }
32
+
33
+ export class AnthropicDriver extends AbstractDriver<AnthropicDriverOptions, ClaudePrompt> {
34
+
35
+ provider = Providers.anthropic;
36
+ client: Anthropic;
37
+
38
+ constructor(opts: AnthropicDriverOptions) {
39
+ super(opts);
40
+ this.client = new Anthropic({ apiKey: opts.apiKey, ...(opts.baseURL ? { baseURL: opts.baseURL } : {}) });
41
+ }
42
+
43
+ protected formatPrompt(segments: PromptSegment[], opts: ExecutionOptions): Promise<ClaudePrompt> {
44
+ return formatClaudePrompt(segments, opts);
45
+ }
46
+
47
+ async requestTextCompletion(prompt: ClaudePrompt, options: ExecutionOptions): Promise<Completion> {
48
+ const model_options = options.model_options as AnthropicClaudeOptions | undefined;
49
+ if (model_options?._option_id !== undefined && model_options?._option_id !== "anthropic-claude") {
50
+ this.logger.debug({ options: options.model_options }, "Unexpected option id");
51
+ }
52
+ return executeClaudeCompletion(this.client, prompt, options);
53
+ }
54
+
55
+ async requestTextCompletionStream(prompt: ClaudePrompt, options: ExecutionOptions): Promise<AsyncIterable<CompletionChunkObject>> {
56
+ const model_options = options.model_options as AnthropicClaudeOptions | undefined;
57
+ if (model_options?._option_id !== undefined && model_options?._option_id !== "anthropic-claude") {
58
+ this.logger.debug({ options: options.model_options }, "Unexpected option id");
59
+ }
60
+ return streamClaudeCompletion(this.client, prompt, options);
61
+ }
62
+
63
+ async listModels(_params?: ModelSearchPayload): Promise<AIModel[]> {
64
+ const page = await this.client.models.list({ limit: 1000 });
65
+ return page.data.map((m) => ({
66
+ id: m.id,
67
+ name: m.display_name ?? m.id,
68
+ provider: Providers.anthropic,
69
+ type: ModelType.Text,
70
+ can_stream: true,
71
+ } satisfies AIModel));
72
+ }
73
+
74
+ async validateConnection(): Promise<boolean> {
75
+ try {
76
+ await this.client.models.list({ limit: 1 });
77
+ return true;
78
+ } catch {
79
+ return false;
80
+ }
81
+ }
82
+
83
+ async generateEmbeddings(_opts: EmbeddingsOptions): Promise<EmbeddingsResult> {
84
+ throw new LlumiverseError(
85
+ '[anthropic] Anthropic does not support embeddings',
86
+ false,
87
+ { provider: Providers.anthropic, model: _opts.model ?? 'unknown', operation: 'execute' },
88
+ undefined,
89
+ );
90
+ }
91
+
92
+ buildStreamingConversation(
93
+ prompt: ClaudePrompt,
94
+ result: unknown[],
95
+ toolUse: unknown[] | undefined,
96
+ options: ExecutionOptions
97
+ ): ClaudePrompt {
98
+ return buildClaudeStreamingConversation(prompt, result, toolUse, options);
99
+ }
100
+
101
+ formatLlumiverseError(error: unknown, context: LlumiverseErrorContext): LlumiverseError {
102
+ return formatAnthropicLlumiverseError(error, context);
103
+ }
104
+ }
package/src/index.ts CHANGED
@@ -1,3 +1,4 @@
1
+ export * from "./anthropic/index.js";
1
2
  export * from "./azure/azure_foundry.js";
2
3
  export * from "./bedrock/index.js";
3
4
  export * from "./groq/index.js";
@@ -880,21 +880,25 @@ function createAssistantMessageFromCompletion(completion: Completion): ResponseI
880
880
  return result;
881
881
  }
882
882
 
883
- function mapResponseStream(stream: AsyncIterable<OpenAI.Responses.ResponseStreamEvent>): AsyncIterable<CompletionChunkObject> {
884
- const toolCallMetadata = new Map<string, { syntheticId: string, name?: string }>();
883
+ export function mapResponseStream(stream: AsyncIterable<OpenAI.Responses.ResponseStreamEvent>): AsyncIterable<CompletionChunkObject> {
884
+ const toolCallMetadata = new Map<string, { syntheticId: string, callId?: string, name?: string }>();
885
885
 
886
886
  return {
887
887
  async *[Symbol.asyncIterator]() {
888
888
  for await (const event of stream) {
889
889
  if (event.type === 'response.output_item.added' && event.item.type === 'function_call') {
890
890
  const syntheticId = `tool_${event.output_index}`;
891
- const actualId = event.item.id ?? event.item.call_id;
892
- if (actualId) {
893
- toolCallMetadata.set(actualId, { syntheticId, name: event.item.name });
891
+ const callId = event.item.call_id ?? event.item.id;
892
+ const metadata = { syntheticId, callId, name: event.item.name };
893
+ if (event.item.id) {
894
+ toolCallMetadata.set(event.item.id, metadata);
895
+ }
896
+ if (event.item.call_id) {
897
+ toolCallMetadata.set(event.item.call_id, metadata);
894
898
  }
895
899
  const toolUse: ToolUse & { _actual_id?: string } = {
896
900
  id: syntheticId,
897
- _actual_id: actualId,
901
+ _actual_id: callId,
898
902
  tool_name: event.item.name,
899
903
  tool_input: '' as any,
900
904
  };
@@ -905,9 +909,10 @@ function mapResponseStream(stream: AsyncIterable<OpenAI.Responses.ResponseStream
905
909
  } else if (event.type === 'response.function_call_arguments.delta') {
906
910
  const metadata = toolCallMetadata.get(event.item_id);
907
911
  const syntheticId = metadata?.syntheticId ?? `tool_${event.output_index}`;
912
+ const callId = metadata?.callId ?? event.item_id;
908
913
  const toolUse: ToolUse & { _actual_id?: string } = {
909
914
  id: syntheticId,
910
- _actual_id: event.item_id,
915
+ _actual_id: callId,
911
916
  tool_name: metadata?.name ?? '',
912
917
  tool_input: event.delta as any,
913
918
  };
@@ -925,7 +930,7 @@ function mapResponseStream(stream: AsyncIterable<OpenAI.Responses.ResponseStream
925
930
  const syntheticId = metadata?.syntheticId ?? `tool_${event.output_index}`;
926
931
  const tool_name = metadata?.name ?? event.name ?? '';
927
932
  if (event.item_id) {
928
- toolCallMetadata.set(event.item_id, { syntheticId, name: tool_name });
933
+ toolCallMetadata.set(event.item_id, { syntheticId, callId: metadata?.callId, name: tool_name });
929
934
  }
930
935
  } else if (event.type === 'response.output_text.delta') {
931
936
  yield {