@llumiverse/drivers 1.2.0 → 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.
- package/lib/cjs/anthropic/index.js +64 -0
- package/lib/cjs/anthropic/index.js.map +1 -0
- package/lib/cjs/index.js +1 -0
- package/lib/cjs/index.js.map +1 -1
- package/lib/cjs/openai/index.js +12 -6
- package/lib/cjs/openai/index.js.map +1 -1
- package/lib/cjs/shared/claude-messages.js +737 -0
- package/lib/cjs/shared/claude-messages.js.map +1 -0
- package/lib/cjs/vertexai/index.js.map +1 -1
- package/lib/cjs/vertexai/models/claude.js +27 -872
- package/lib/cjs/vertexai/models/claude.js.map +1 -1
- package/lib/cjs/vertexai/models/gemini.js +18 -12
- package/lib/cjs/vertexai/models/gemini.js.map +1 -1
- package/lib/esm/anthropic/index.js +57 -0
- package/lib/esm/anthropic/index.js.map +1 -0
- package/lib/esm/index.js +1 -0
- package/lib/esm/index.js.map +1 -1
- package/lib/esm/openai/index.js +12 -7
- package/lib/esm/openai/index.js.map +1 -1
- package/lib/esm/shared/claude-messages.js +716 -0
- package/lib/esm/shared/claude-messages.js.map +1 -0
- package/lib/esm/vertexai/index.js.map +1 -1
- package/lib/esm/vertexai/models/claude.js +27 -865
- package/lib/esm/vertexai/models/claude.js.map +1 -1
- package/lib/esm/vertexai/models/gemini.js +18 -12
- package/lib/esm/vertexai/models/gemini.js.map +1 -1
- package/lib/types/anthropic/index.d.ts +21 -0
- package/lib/types/anthropic/index.d.ts.map +1 -0
- package/lib/types/index.d.ts +1 -0
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/openai/index.d.ts +1 -0
- package/lib/types/openai/index.d.ts.map +1 -1
- package/lib/types/shared/claude-messages.d.ts +75 -0
- package/lib/types/shared/claude-messages.d.ts.map +1 -0
- package/lib/types/vertexai/index.d.ts +4 -4
- package/lib/types/vertexai/index.d.ts.map +1 -1
- package/lib/types/vertexai/models/claude.d.ts +3 -106
- package/lib/types/vertexai/models/claude.d.ts.map +1 -1
- package/lib/types/vertexai/models/gemini.d.ts +1 -1
- package/lib/types/vertexai/models/gemini.d.ts.map +1 -1
- package/package.json +7 -6
- package/src/anthropic/index.ts +104 -0
- package/src/index.ts +1 -0
- package/src/openai/index.ts +13 -8
- package/src/shared/claude-messages.ts +879 -0
- package/src/vertexai/index.ts +18 -19
- package/src/vertexai/models/claude-error-handling.test.ts +3 -3
- package/src/vertexai/models/claude.ts +44 -1016
- 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.
|
|
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.
|
|
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": "
|
|
66
|
+
"@google/genai": "2.1.0",
|
|
67
67
|
"@huggingface/inference": "4.13.11",
|
|
68
|
-
"@vertesia/api-fetch-client": "^
|
|
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/
|
|
77
|
-
"@llumiverse/
|
|
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
package/src/openai/index.ts
CHANGED
|
@@ -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
|
|
892
|
-
|
|
893
|
-
|
|
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:
|
|
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:
|
|
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 {
|