@imenam/unified-llm-client 1.2.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/LICENSE +21 -0
- package/README.md +233 -0
- package/dist/adapters/anthropic/AnthropicLogAdapter.d.ts +6 -0
- package/dist/adapters/anthropic/AnthropicLogAdapter.d.ts.map +1 -0
- package/dist/adapters/anthropic/AnthropicLogAdapter.js +41 -0
- package/dist/adapters/anthropic/AnthropicOutputAdapter.d.ts +6 -0
- package/dist/adapters/anthropic/AnthropicOutputAdapter.d.ts.map +1 -0
- package/dist/adapters/anthropic/AnthropicOutputAdapter.js +41 -0
- package/dist/adapters/anthropic/AnthropicPromptAdapter.d.ts +12 -0
- package/dist/adapters/anthropic/AnthropicPromptAdapter.d.ts.map +1 -0
- package/dist/adapters/anthropic/AnthropicPromptAdapter.js +249 -0
- package/dist/adapters/anthropic/AnthropicToolAdapter.d.ts +6 -0
- package/dist/adapters/anthropic/AnthropicToolAdapter.d.ts.map +1 -0
- package/dist/adapters/anthropic/AnthropicToolAdapter.js +20 -0
- package/dist/adapters/gemini/GeminiAudioAdapter.d.ts +40 -0
- package/dist/adapters/gemini/GeminiAudioAdapter.d.ts.map +1 -0
- package/dist/adapters/gemini/GeminiAudioAdapter.js +273 -0
- package/dist/adapters/gemini/GeminiLogAdapter.d.ts +6 -0
- package/dist/adapters/gemini/GeminiLogAdapter.d.ts.map +1 -0
- package/dist/adapters/gemini/GeminiLogAdapter.js +43 -0
- package/dist/adapters/gemini/GeminiOutputAdapter.d.ts +6 -0
- package/dist/adapters/gemini/GeminiOutputAdapter.d.ts.map +1 -0
- package/dist/adapters/gemini/GeminiOutputAdapter.js +38 -0
- package/dist/adapters/gemini/GeminiPromptAdapter.d.ts +26 -0
- package/dist/adapters/gemini/GeminiPromptAdapter.d.ts.map +1 -0
- package/dist/adapters/gemini/GeminiPromptAdapter.js +334 -0
- package/dist/adapters/gemini/GeminiToolAdapter.d.ts +8 -0
- package/dist/adapters/gemini/GeminiToolAdapter.d.ts.map +1 -0
- package/dist/adapters/gemini/GeminiToolAdapter.js +42 -0
- package/dist/adapters/gemini/types.d.ts +14 -0
- package/dist/adapters/gemini/types.d.ts.map +1 -0
- package/dist/adapters/gemini/types.js +2 -0
- package/dist/adapters/openai/OpenAIOutputAdapter.d.ts +6 -0
- package/dist/adapters/openai/OpenAIOutputAdapter.d.ts.map +1 -0
- package/dist/adapters/openai/OpenAIOutputAdapter.js +18 -0
- package/dist/adapters/openai/OpenAIPromptAdapter.d.ts +13 -0
- package/dist/adapters/openai/OpenAIPromptAdapter.d.ts.map +1 -0
- package/dist/adapters/openai/OpenAIPromptAdapter.js +215 -0
- package/dist/adapters/openai/OpenAiLogAdapter.d.ts +6 -0
- package/dist/adapters/openai/OpenAiLogAdapter.d.ts.map +1 -0
- package/dist/adapters/openai/OpenAiLogAdapter.js +37 -0
- package/dist/adapters/openai/OpenAiToolAdapter.d.ts +6 -0
- package/dist/adapters/openai/OpenAiToolAdapter.d.ts.map +1 -0
- package/dist/adapters/openai/OpenAiToolAdapter.js +20 -0
- package/dist/adapters/qwen/QwenLogAdapter.d.ts +7 -0
- package/dist/adapters/qwen/QwenLogAdapter.d.ts.map +1 -0
- package/dist/adapters/qwen/QwenLogAdapter.js +49 -0
- package/dist/adapters/qwen/QwenOutputAdapter.d.ts +6 -0
- package/dist/adapters/qwen/QwenOutputAdapter.d.ts.map +1 -0
- package/dist/adapters/qwen/QwenOutputAdapter.js +9 -0
- package/dist/adapters/qwen/QwenPromptAdapter.d.ts +13 -0
- package/dist/adapters/qwen/QwenPromptAdapter.d.ts.map +1 -0
- package/dist/adapters/qwen/QwenPromptAdapter.js +313 -0
- package/dist/adapters/qwen/QwenToolAdapter.d.ts +6 -0
- package/dist/adapters/qwen/QwenToolAdapter.d.ts.map +1 -0
- package/dist/adapters/qwen/QwenToolAdapter.js +20 -0
- package/dist/common/types.d.ts +106 -0
- package/dist/common/types.d.ts.map +1 -0
- package/dist/common/types.js +2 -0
- package/dist/core/LLMAdapter.d.ts +74 -0
- package/dist/core/LLMAdapter.d.ts.map +1 -0
- package/dist/core/LLMAdapter.js +70 -0
- package/dist/core/Models.d.ts +16 -0
- package/dist/core/Models.d.ts.map +1 -0
- package/dist/core/Models.js +118 -0
- package/dist/core/UnifiedLLMClient.d.ts +68 -0
- package/dist/core/UnifiedLLMClient.d.ts.map +1 -0
- package/dist/core/UnifiedLLMClient.js +185 -0
- package/dist/examples/anthropic-example.d.ts +2 -0
- package/dist/examples/anthropic-example.d.ts.map +1 -0
- package/dist/examples/anthropic-example.js +243 -0
- package/dist/examples/audio-example.d.ts +14 -0
- package/dist/examples/audio-example.d.ts.map +1 -0
- package/dist/examples/audio-example.js +204 -0
- package/dist/examples/example-logging.d.ts +2 -0
- package/dist/examples/example-logging.d.ts.map +1 -0
- package/dist/examples/example-logging.js +53 -0
- package/dist/examples/example.d.ts +2 -0
- package/dist/examples/example.d.ts.map +1 -0
- package/dist/examples/example.js +373 -0
- package/dist/examples/qwen-vl-example.d.ts +26 -0
- package/dist/examples/qwen-vl-example.d.ts.map +1 -0
- package/dist/examples/qwen-vl-example.js +314 -0
- package/dist/examples/test-multiturn-tools.d.ts +2 -0
- package/dist/examples/test-multiturn-tools.d.ts.map +1 -0
- package/dist/examples/test-multiturn-tools.js +139 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/utils/audioUtils.d.ts +41 -0
- package/dist/utils/audioUtils.d.ts.map +1 -0
- package/dist/utils/audioUtils.js +185 -0
- package/package.json +64 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 imenam
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
# @imenam/unified-llm-client
|
|
2
|
+
|
|
3
|
+
A unified interface for multiple LLM providers — OpenAI, Gemini, Anthropic, and Qwen — with built-in support for tool-calling, streaming, multimodal inputs, and audio generation.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Unified API** — one interface, four providers
|
|
8
|
+
- **Tool-calling** — automatic execution loop with structured results
|
|
9
|
+
- **Streaming** — chunk-by-chunk responses via callbacks
|
|
10
|
+
- **Multimodal** — image and audio file inputs
|
|
11
|
+
- **Audio generation** — Text-to-Speech (Gemini)
|
|
12
|
+
- **Usage tracking** — token counts and estimated costs
|
|
13
|
+
- **Full TypeScript support** — exported types and `.d.ts` declarations
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install @imenam/unified-llm-client
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Supported Providers
|
|
22
|
+
|
|
23
|
+
| Provider | Chat | Streaming | Tool-calling | Multimodal | Audio TTS |
|
|
24
|
+
|-----------|:----:|:---------:|:------------:|:----------:|:---------:|
|
|
25
|
+
| OpenAI | ✅ | ✅ | ✅ | ✅ | ❌ |
|
|
26
|
+
| Gemini | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
27
|
+
| Anthropic | ✅ | ✅ | ✅ | ✅ | ❌ |
|
|
28
|
+
| Qwen | ✅ | ✅ | ✅ | ✅ | ❌ |
|
|
29
|
+
|
|
30
|
+
## Quick Start
|
|
31
|
+
|
|
32
|
+
Set your API keys in a `.env` file:
|
|
33
|
+
|
|
34
|
+
```env
|
|
35
|
+
OPENAI_API_KEY=sk-...
|
|
36
|
+
GOOGLE_API_KEY=...
|
|
37
|
+
ANTHROPIC_API_KEY=sk-ant-...
|
|
38
|
+
DASHSCOPE_API_KEY=... # for Qwen
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
import { UnifiedLLMClient, MODELS } from "@imenam/unified-llm-client";
|
|
43
|
+
|
|
44
|
+
const client = new UnifiedLLMClient(MODELS.GPT_4O_MINI);
|
|
45
|
+
|
|
46
|
+
const response = await client.chat({
|
|
47
|
+
message: "What is the capital of France?",
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
console.log(response.content); // "The capital of France is Paris."
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Available Models
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
import { MODELS } from "@imenam/unified-llm-client";
|
|
57
|
+
|
|
58
|
+
// OpenAI
|
|
59
|
+
MODELS.GPT_4O_MINI
|
|
60
|
+
MODELS.GPT_5
|
|
61
|
+
|
|
62
|
+
// Gemini
|
|
63
|
+
MODELS.GEMINI_FLASH_2_5
|
|
64
|
+
MODELS.GEMINI_2_5_PRO
|
|
65
|
+
MODELS.GEMINI_3_FLASH
|
|
66
|
+
MODELS.GEMINI_3_PRO
|
|
67
|
+
MODELS.GEMINI_3_1_PRO
|
|
68
|
+
|
|
69
|
+
// Anthropic
|
|
70
|
+
MODELS.CLAUDE_SONNET_4_6
|
|
71
|
+
MODELS.CLAUDE_OPUS_4_6
|
|
72
|
+
|
|
73
|
+
// Qwen
|
|
74
|
+
MODELS.QWEN_VL_3
|
|
75
|
+
MODELS.QWEN_VL_FLASH
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
You can also pass a custom model:
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
const client = new UnifiedLLMClient({
|
|
82
|
+
provider: "openai",
|
|
83
|
+
modelName: "gpt-4o",
|
|
84
|
+
});
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Tool-calling
|
|
88
|
+
|
|
89
|
+
Define tools with an `executor` function — the client will call them automatically and loop until the LLM produces a final text response.
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
import { UnifiedLLMClient, MODELS } from "@imenam/unified-llm-client";
|
|
93
|
+
import type { ToolDefinition } from "@imenam/unified-llm-client";
|
|
94
|
+
|
|
95
|
+
const tools: ToolDefinition[] = [
|
|
96
|
+
{
|
|
97
|
+
name: "get_weather",
|
|
98
|
+
description: "Get the current weather for a city",
|
|
99
|
+
parameters: {
|
|
100
|
+
type: "object",
|
|
101
|
+
properties: {
|
|
102
|
+
city: { type: "string", description: "City name" },
|
|
103
|
+
},
|
|
104
|
+
required: ["city"],
|
|
105
|
+
},
|
|
106
|
+
executor: async ({ city }) => {
|
|
107
|
+
return `The weather in ${city} is sunny and 22°C.`;
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
];
|
|
111
|
+
|
|
112
|
+
const client = new UnifiedLLMClient(MODELS.GEMINI_FLASH_2_5);
|
|
113
|
+
|
|
114
|
+
const response = await client.chat({
|
|
115
|
+
message: "What's the weather like in Paris?",
|
|
116
|
+
tools,
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
console.log(response.content);
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Streaming
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
const client = new UnifiedLLMClient(MODELS.GPT_4O_MINI);
|
|
126
|
+
|
|
127
|
+
const response = await client.chat({
|
|
128
|
+
message: "Tell me a short story.",
|
|
129
|
+
stream: true,
|
|
130
|
+
onChunk: (chunk) => {
|
|
131
|
+
process.stdout.write(chunk.content ?? "");
|
|
132
|
+
},
|
|
133
|
+
onFinalResponse: (final) => {
|
|
134
|
+
console.log("\n\nTotal tokens:", final.usage?.totalTokens);
|
|
135
|
+
},
|
|
136
|
+
});
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Conversation History
|
|
140
|
+
|
|
141
|
+
The client maintains conversation history internally. Use `getHistory()` and `setHistory()` to persist or restore it:
|
|
142
|
+
|
|
143
|
+
```typescript
|
|
144
|
+
const client = new UnifiedLLMClient(MODELS.CLAUDE_SONNET_4_6);
|
|
145
|
+
|
|
146
|
+
await client.chat({ message: "My name is Alice." });
|
|
147
|
+
await client.chat({ message: "What's my name?" });
|
|
148
|
+
// → "Your name is Alice."
|
|
149
|
+
|
|
150
|
+
const history = client.getHistory();
|
|
151
|
+
// Save and restore later:
|
|
152
|
+
const newClient = new UnifiedLLMClient(MODELS.CLAUDE_SONNET_4_6);
|
|
153
|
+
newClient.setHistory(history);
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## Multimodal Inputs
|
|
157
|
+
|
|
158
|
+
Attach images or audio files directly to a message:
|
|
159
|
+
|
|
160
|
+
```typescript
|
|
161
|
+
const response = await client.chat({
|
|
162
|
+
message: {
|
|
163
|
+
role: "user",
|
|
164
|
+
content: "What do you see in this image?",
|
|
165
|
+
attachedFile: "./photo.jpg",
|
|
166
|
+
},
|
|
167
|
+
});
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## Audio Generation (Gemini)
|
|
171
|
+
|
|
172
|
+
```typescript
|
|
173
|
+
import { UnifiedLLMClient, MODELS } from "@imenam/unified-llm-client";
|
|
174
|
+
|
|
175
|
+
const client = new UnifiedLLMClient(MODELS.GEMINI_FLASH_2_5);
|
|
176
|
+
|
|
177
|
+
const audio = await client.generateAudio({
|
|
178
|
+
text: "Hello, this is a test of text-to-speech.",
|
|
179
|
+
outputPath: "./output.wav",
|
|
180
|
+
voiceConfig: { voiceName: "Kore" },
|
|
181
|
+
});
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
## Logging
|
|
185
|
+
|
|
186
|
+
Pass a `logger` callback to capture structured logs for every request:
|
|
187
|
+
|
|
188
|
+
```typescript
|
|
189
|
+
const client = new UnifiedLLMClient(MODELS.GPT_4O_MINI, {
|
|
190
|
+
logger: (log) => {
|
|
191
|
+
console.log(`[${log.provider}] ${log.model} — ${log.totalTokens} tokens`);
|
|
192
|
+
},
|
|
193
|
+
});
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
## API Reference
|
|
197
|
+
|
|
198
|
+
### `new UnifiedLLMClient(model, options?)`
|
|
199
|
+
|
|
200
|
+
| Parameter | Type | Description |
|
|
201
|
+
|-----------|------|-------------|
|
|
202
|
+
| `model` | `Model` | Model object from `MODELS` or a custom `{ provider, modelName }` |
|
|
203
|
+
| `options.logger` | `(log: UnifiedLog) => void` | Optional logging callback |
|
|
204
|
+
|
|
205
|
+
### `client.chat(options)`
|
|
206
|
+
|
|
207
|
+
| Option | Type | Default | Description |
|
|
208
|
+
|--------|------|---------|-------------|
|
|
209
|
+
| `message` | `string \| ChatMessage \| ChatMessage[]` | — | User message or history |
|
|
210
|
+
| `tools` | `ToolDefinition[]` | `[]` | Tools available to the LLM |
|
|
211
|
+
| `toolChoice` | `"auto" \| "none" \| string` | `"auto"` | Tool selection strategy |
|
|
212
|
+
| `stream` | `boolean` | `false` | Enable streaming |
|
|
213
|
+
| `onChunk` | `(chunk: StreamedChatChunk) => void` | — | Streaming chunk callback |
|
|
214
|
+
| `onFinalResponse` | `(res: ChatResponse) => void` | — | Final response callback |
|
|
215
|
+
|
|
216
|
+
### `ChatResponse`
|
|
217
|
+
|
|
218
|
+
```typescript
|
|
219
|
+
interface ChatResponse {
|
|
220
|
+
content: string | null;
|
|
221
|
+
toolCalls?: ToolCall[];
|
|
222
|
+
usage?: {
|
|
223
|
+
promptTokens: number;
|
|
224
|
+
completionTokens: number;
|
|
225
|
+
totalTokens: number;
|
|
226
|
+
};
|
|
227
|
+
raw: unknown;
|
|
228
|
+
}
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
## License
|
|
232
|
+
|
|
233
|
+
MIT
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { UnifiedLog } from "../../common/types";
|
|
2
|
+
import { LogAdapter, LogData } from "../../core/LLMAdapter";
|
|
3
|
+
export declare class AnthropicLogAdapter implements LogAdapter {
|
|
4
|
+
toUnifiedLog(data: LogData): UnifiedLog;
|
|
5
|
+
}
|
|
6
|
+
//# sourceMappingURL=AnthropicLogAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AnthropicLogAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/anthropic/AnthropicLogAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAY,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAE5D,qBAAa,mBAAoB,YAAW,UAAU;IACpD,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,UAAU;CAoCxC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AnthropicLogAdapter = void 0;
|
|
4
|
+
class AnthropicLogAdapter {
|
|
5
|
+
toUnifiedLog(data) {
|
|
6
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
7
|
+
const { model, provider, messages, response, latencyMs, metadata } = data;
|
|
8
|
+
const usage = response.usage;
|
|
9
|
+
const raw = response.raw;
|
|
10
|
+
const inputTokens = (_c = (_b = (_a = raw === null || raw === void 0 ? void 0 : raw.usage) === null || _a === void 0 ? void 0 : _a.input_tokens) !== null && _b !== void 0 ? _b : usage === null || usage === void 0 ? void 0 : usage.promptTokens) !== null && _c !== void 0 ? _c : 0;
|
|
11
|
+
const outputTokens = (_f = (_e = (_d = raw === null || raw === void 0 ? void 0 : raw.usage) === null || _d === void 0 ? void 0 : _d.output_tokens) !== null && _e !== void 0 ? _e : usage === null || usage === void 0 ? void 0 : usage.completionTokens) !== null && _f !== void 0 ? _f : 0;
|
|
12
|
+
const cacheCreationTokens = (_h = (_g = raw === null || raw === void 0 ? void 0 : raw.usage) === null || _g === void 0 ? void 0 : _g.cache_creation_input_tokens) !== null && _h !== void 0 ? _h : 0;
|
|
13
|
+
const cacheReadTokens = (_k = (_j = raw === null || raw === void 0 ? void 0 : raw.usage) === null || _j === void 0 ? void 0 : _j.cache_read_input_tokens) !== null && _k !== void 0 ? _k : 0;
|
|
14
|
+
return {
|
|
15
|
+
requestId: (_l = raw === null || raw === void 0 ? void 0 : raw.id) !== null && _l !== void 0 ? _l : `anthropic-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
|
|
16
|
+
timestamp: new Date(),
|
|
17
|
+
provider: provider,
|
|
18
|
+
model,
|
|
19
|
+
prompt: messages,
|
|
20
|
+
output: {
|
|
21
|
+
content: response.content,
|
|
22
|
+
toolCalls: response.toolCalls,
|
|
23
|
+
finishReason: response.finishReason,
|
|
24
|
+
},
|
|
25
|
+
usage: {
|
|
26
|
+
promptTokens: inputTokens,
|
|
27
|
+
completionTokens: outputTokens,
|
|
28
|
+
totalTokens: inputTokens + outputTokens,
|
|
29
|
+
promptDetails: {
|
|
30
|
+
cachedTokens: cacheCreationTokens + cacheReadTokens,
|
|
31
|
+
},
|
|
32
|
+
completionDetails: {
|
|
33
|
+
textTokens: outputTokens,
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
latencyMs,
|
|
37
|
+
metadata,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
exports.AnthropicLogAdapter = AnthropicLogAdapter;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { ChatResponse } from "../../common/types";
|
|
2
|
+
import { OutputAdapter } from "../../core/LLMAdapter";
|
|
3
|
+
export declare class AnthropicOutputAdapter implements OutputAdapter {
|
|
4
|
+
parse(providerResponse: any): ChatResponse;
|
|
5
|
+
}
|
|
6
|
+
//# sourceMappingURL=AnthropicOutputAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AnthropicOutputAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/anthropic/AnthropicOutputAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAY,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEtD,qBAAa,sBAAuB,YAAW,aAAa;IAC1D,KAAK,CAAC,gBAAgB,EAAE,GAAG,GAAG,YAAY;CAqC3C"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AnthropicOutputAdapter = void 0;
|
|
4
|
+
class AnthropicOutputAdapter {
|
|
5
|
+
parse(providerResponse) {
|
|
6
|
+
var _a, _b, _c, _d;
|
|
7
|
+
const raw = (_a = providerResponse.raw) !== null && _a !== void 0 ? _a : providerResponse;
|
|
8
|
+
let textContent = null;
|
|
9
|
+
const toolCalls = [];
|
|
10
|
+
for (const block of (_b = raw.content) !== null && _b !== void 0 ? _b : []) {
|
|
11
|
+
if (block.type === "text") {
|
|
12
|
+
textContent = (textContent !== null && textContent !== void 0 ? textContent : "") + block.text;
|
|
13
|
+
}
|
|
14
|
+
else if (block.type === "tool_use") {
|
|
15
|
+
toolCalls.push({
|
|
16
|
+
id: block.id,
|
|
17
|
+
name: block.name,
|
|
18
|
+
arguments: block.input,
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
const usage = raw.usage;
|
|
23
|
+
return {
|
|
24
|
+
content: textContent,
|
|
25
|
+
toolCalls: toolCalls.length > 0 ? toolCalls : undefined,
|
|
26
|
+
lastToolArguments: (_c = toolCalls[0]) === null || _c === void 0 ? void 0 : _c.arguments,
|
|
27
|
+
raw,
|
|
28
|
+
usage: usage
|
|
29
|
+
? {
|
|
30
|
+
promptTokens: usage.input_tokens,
|
|
31
|
+
completionTokens: usage.output_tokens,
|
|
32
|
+
totalTokens: usage.input_tokens + usage.output_tokens,
|
|
33
|
+
promptTokensDetails: null,
|
|
34
|
+
thoughtsToken: 0,
|
|
35
|
+
}
|
|
36
|
+
: undefined,
|
|
37
|
+
finishReason: (_d = raw.stop_reason) !== null && _d !== void 0 ? _d : undefined,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
exports.AnthropicOutputAdapter = AnthropicOutputAdapter;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ChatMessage, ChatResponse, ToolDefinition } from "../../common/types";
|
|
2
|
+
import { ChatOptionalConfig, ChatStreamOptions, PromptAdapter, PromptAdapterOptions } from "../../core/LLMAdapter";
|
|
3
|
+
export declare class AnthropicPromptAdapter implements PromptAdapter {
|
|
4
|
+
private client;
|
|
5
|
+
private opts;
|
|
6
|
+
constructor(opts: PromptAdapterOptions);
|
|
7
|
+
formatMessage(message: ChatMessage): Promise<any>;
|
|
8
|
+
private buildRequestParams;
|
|
9
|
+
sendToProvider(messages: any[], tools?: ToolDefinition[], toolChoice?: "auto" | "none" | string, _attachedFile?: string | string[], model?: string, _config?: ChatOptionalConfig): Promise<ChatResponse>;
|
|
10
|
+
streamFromProvider({ messages, tools, toolChoice, model, onChunk, onFinalResponse, }: ChatStreamOptions): Promise<ChatResponse>;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=AnthropicPromptAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AnthropicPromptAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/anthropic/AnthropicPromptAdapter.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAY,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzF,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,aAAa,EAAE,oBAAoB,EAAqB,MAAM,uBAAuB,CAAC;AA4BtI,qBAAa,sBAAuB,YAAW,aAAa;IAC1D,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,IAAI,CAAuB;gBAEvB,IAAI,EAAE,oBAAoB;IAKhC,aAAa,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC;IAsEvD,OAAO,CAAC,kBAAkB;IAmCpB,cAAc,CAClB,QAAQ,EAAE,GAAG,EAAE,EACf,KAAK,GAAE,cAAc,EAAO,EAC5B,UAAU,GAAE,MAAM,GAAG,MAAM,GAAG,MAAe,EAC7C,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,EACjC,KAAK,CAAC,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC,YAAY,CAAC;IAgDlB,kBAAkB,CAAC,EACvB,QAAQ,EACR,KAAK,EACL,UAAU,EACV,KAAK,EACL,OAAO,EACP,eAAe,GAChB,EAAE,iBAAiB,GAAG,OAAO,CAAC,YAAY,CAAC;CA8D7C"}
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
36
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
37
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
38
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
39
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
40
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
41
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
45
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
46
|
+
};
|
|
47
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
48
|
+
exports.AnthropicPromptAdapter = void 0;
|
|
49
|
+
const sdk_1 = __importDefault(require("@anthropic-ai/sdk"));
|
|
50
|
+
const fs_1 = __importDefault(require("fs"));
|
|
51
|
+
const mime = __importStar(require("mime-types"));
|
|
52
|
+
const sharp_1 = __importDefault(require("sharp"));
|
|
53
|
+
const IMAGE_MIME_TYPES = ["image/jpeg", "image/png", "image/gif", "image/webp"];
|
|
54
|
+
const ANTHROPIC_MAX_IMAGE_BYTES = 5 * 1024 * 1024; // 5 MB
|
|
55
|
+
function compressImageIfNeeded(filePath, mimeType) {
|
|
56
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
57
|
+
const raw = fs_1.default.readFileSync(filePath);
|
|
58
|
+
if (raw.byteLength <= ANTHROPIC_MAX_IMAGE_BYTES) {
|
|
59
|
+
return { data: raw.toString("base64"), media_type: mimeType };
|
|
60
|
+
}
|
|
61
|
+
// Compression progressive jusqu'à passer sous la limite
|
|
62
|
+
let quality = 85;
|
|
63
|
+
let compressed;
|
|
64
|
+
do {
|
|
65
|
+
compressed = yield (0, sharp_1.default)(raw).jpeg({ quality }).toBuffer();
|
|
66
|
+
quality -= 10;
|
|
67
|
+
} while (compressed.byteLength > ANTHROPIC_MAX_IMAGE_BYTES && quality > 10);
|
|
68
|
+
return { data: compressed.toString("base64"), media_type: "image/jpeg" };
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
class AnthropicPromptAdapter {
|
|
72
|
+
constructor(opts) {
|
|
73
|
+
this.opts = opts;
|
|
74
|
+
this.client = new sdk_1.default({ apiKey: opts.apiKey });
|
|
75
|
+
}
|
|
76
|
+
formatMessage(message) {
|
|
77
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
78
|
+
var _a, _b;
|
|
79
|
+
if (message.role === "system") {
|
|
80
|
+
return { role: "system", content: message.content };
|
|
81
|
+
}
|
|
82
|
+
// Tool result message → user turn with tool_result content block
|
|
83
|
+
if (message.role === "tool") {
|
|
84
|
+
return {
|
|
85
|
+
role: "user",
|
|
86
|
+
content: [{
|
|
87
|
+
type: "tool_result",
|
|
88
|
+
tool_use_id: (_a = message.tool_call_id) !== null && _a !== void 0 ? _a : "",
|
|
89
|
+
content: typeof message.content === "string" ? message.content : JSON.stringify(message.content),
|
|
90
|
+
}],
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
// Assistant message with tool calls → assistant turn with tool_use content blocks
|
|
94
|
+
if (message.role === "assistant" && message.tool_calls && message.tool_calls.length > 0) {
|
|
95
|
+
const contentBlocks = [];
|
|
96
|
+
if (message.content) {
|
|
97
|
+
contentBlocks.push({ type: "text", text: message.content });
|
|
98
|
+
}
|
|
99
|
+
for (const tc of message.tool_calls) {
|
|
100
|
+
contentBlocks.push({
|
|
101
|
+
type: "tool_use",
|
|
102
|
+
id: (_b = tc.id) !== null && _b !== void 0 ? _b : tc.name,
|
|
103
|
+
name: tc.name,
|
|
104
|
+
input: tc.arguments,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
return { role: "assistant", content: contentBlocks };
|
|
108
|
+
}
|
|
109
|
+
if (message.attachedFile) {
|
|
110
|
+
const files = Array.isArray(message.attachedFile) ? message.attachedFile : [message.attachedFile];
|
|
111
|
+
const contentBlocks = [];
|
|
112
|
+
for (const filePath of files) {
|
|
113
|
+
const mimeType = mime.lookup(filePath) || "application/octet-stream";
|
|
114
|
+
if (IMAGE_MIME_TYPES.includes(mimeType)) {
|
|
115
|
+
const { data, media_type } = yield compressImageIfNeeded(filePath, mimeType);
|
|
116
|
+
contentBlocks.push({
|
|
117
|
+
type: "image",
|
|
118
|
+
source: { type: "base64", media_type, data },
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
else if (mimeType === "application/pdf") {
|
|
122
|
+
const base64Data = fs_1.default.readFileSync(filePath).toString("base64");
|
|
123
|
+
contentBlocks.push({
|
|
124
|
+
type: "document",
|
|
125
|
+
source: { type: "base64", media_type: "application/pdf", data: base64Data },
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
contentBlocks.push({ type: "text", text: message.content });
|
|
130
|
+
return {
|
|
131
|
+
role: message.role === "assistant" ? "assistant" : "user",
|
|
132
|
+
content: contentBlocks,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
return {
|
|
136
|
+
role: message.role === "assistant" ? "assistant" : "user",
|
|
137
|
+
content: message.content,
|
|
138
|
+
};
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
buildRequestParams(messages, tools = [], toolChoice = "auto", model) {
|
|
142
|
+
const systemMessages = messages.filter((m) => m.role === "system");
|
|
143
|
+
const nonSystemMessages = messages.filter((m) => m.role !== "system");
|
|
144
|
+
const systemPrompt = systemMessages.map((m) => m.content).join("\n") || undefined;
|
|
145
|
+
let sdkTools = undefined;
|
|
146
|
+
let sdkToolChoice = undefined;
|
|
147
|
+
if (toolChoice !== "none" && tools.length > 0) {
|
|
148
|
+
sdkTools = tools.map((t) => {
|
|
149
|
+
var _a, _b;
|
|
150
|
+
return ({
|
|
151
|
+
name: t.name,
|
|
152
|
+
description: t.description,
|
|
153
|
+
input_schema: {
|
|
154
|
+
type: "object",
|
|
155
|
+
properties: ((_a = t.parameters) === null || _a === void 0 ? void 0 : _a.properties) || {},
|
|
156
|
+
required: ((_b = t.parameters) === null || _b === void 0 ? void 0 : _b.required) || [],
|
|
157
|
+
},
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
if (toolChoice === "auto") {
|
|
161
|
+
sdkToolChoice = { type: "auto" };
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
sdkToolChoice = { type: "tool", name: toolChoice };
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return { systemPrompt, nonSystemMessages, sdkTools, sdkToolChoice, model: model || this.opts.model };
|
|
168
|
+
}
|
|
169
|
+
sendToProvider(messages_1) {
|
|
170
|
+
return __awaiter(this, arguments, void 0, function* (messages, tools = [], toolChoice = "auto", _attachedFile, model, _config) {
|
|
171
|
+
var _a, _b;
|
|
172
|
+
const { systemPrompt, nonSystemMessages, sdkTools, sdkToolChoice, model: resolvedModel } = this.buildRequestParams(messages, tools, toolChoice, model);
|
|
173
|
+
const response = yield this.client.messages.create(Object.assign(Object.assign(Object.assign({ model: resolvedModel, max_tokens: 8096, messages: nonSystemMessages }, (systemPrompt ? { system: systemPrompt } : {})), (sdkTools ? { tools: sdkTools } : {})), (sdkToolChoice ? { tool_choice: sdkToolChoice } : {})));
|
|
174
|
+
let textContent = null;
|
|
175
|
+
const toolCalls = [];
|
|
176
|
+
for (const block of response.content) {
|
|
177
|
+
if (block.type === "text") {
|
|
178
|
+
textContent = (textContent !== null && textContent !== void 0 ? textContent : "") + block.text;
|
|
179
|
+
}
|
|
180
|
+
else if (block.type === "tool_use") {
|
|
181
|
+
toolCalls.push({
|
|
182
|
+
id: block.id,
|
|
183
|
+
name: block.name,
|
|
184
|
+
arguments: block.input,
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return {
|
|
189
|
+
content: textContent,
|
|
190
|
+
toolCalls: toolCalls.length > 0 ? toolCalls : undefined,
|
|
191
|
+
lastToolArguments: (_a = toolCalls[0]) === null || _a === void 0 ? void 0 : _a.arguments,
|
|
192
|
+
raw: response,
|
|
193
|
+
usage: {
|
|
194
|
+
promptTokens: response.usage.input_tokens,
|
|
195
|
+
completionTokens: response.usage.output_tokens,
|
|
196
|
+
totalTokens: response.usage.input_tokens + response.usage.output_tokens,
|
|
197
|
+
promptTokensDetails: null,
|
|
198
|
+
thoughtsToken: 0,
|
|
199
|
+
},
|
|
200
|
+
finishReason: (_b = response.stop_reason) !== null && _b !== void 0 ? _b : undefined,
|
|
201
|
+
};
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
streamFromProvider(_a) {
|
|
205
|
+
return __awaiter(this, arguments, void 0, function* ({ messages, tools, toolChoice, model, onChunk, onFinalResponse, }) {
|
|
206
|
+
var _b, _c;
|
|
207
|
+
const { systemPrompt, nonSystemMessages, sdkTools, sdkToolChoice, model: resolvedModel } = this.buildRequestParams(messages, tools !== null && tools !== void 0 ? tools : [], toolChoice !== null && toolChoice !== void 0 ? toolChoice : "auto", model);
|
|
208
|
+
const stream = this.client.messages.stream(Object.assign(Object.assign(Object.assign({ model: resolvedModel, max_tokens: 8096, messages: nonSystemMessages }, (systemPrompt ? { system: systemPrompt } : {})), (sdkTools ? { tools: sdkTools } : {})), (sdkToolChoice ? { tool_choice: sdkToolChoice } : {})));
|
|
209
|
+
const toolCalls = [];
|
|
210
|
+
stream.on("text", (text) => {
|
|
211
|
+
onChunk === null || onChunk === void 0 ? void 0 : onChunk({ contentChunk: text });
|
|
212
|
+
});
|
|
213
|
+
stream.on("contentBlock", (block) => {
|
|
214
|
+
if (block.type === "tool_use") {
|
|
215
|
+
toolCalls.push({
|
|
216
|
+
id: block.id,
|
|
217
|
+
name: block.name,
|
|
218
|
+
arguments: block.input,
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
const finalMessage = yield stream.finalMessage();
|
|
223
|
+
let textContent = null;
|
|
224
|
+
for (const block of finalMessage.content) {
|
|
225
|
+
if (block.type === "text") {
|
|
226
|
+
textContent = (textContent !== null && textContent !== void 0 ? textContent : "") + block.text;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
const finalResponse = {
|
|
230
|
+
content: textContent,
|
|
231
|
+
toolCalls: toolCalls.length > 0 ? toolCalls : undefined,
|
|
232
|
+
lastToolArguments: (_b = toolCalls[0]) === null || _b === void 0 ? void 0 : _b.arguments,
|
|
233
|
+
raw: finalMessage,
|
|
234
|
+
usage: {
|
|
235
|
+
promptTokens: finalMessage.usage.input_tokens,
|
|
236
|
+
completionTokens: finalMessage.usage.output_tokens,
|
|
237
|
+
totalTokens: finalMessage.usage.input_tokens + finalMessage.usage.output_tokens,
|
|
238
|
+
promptTokensDetails: null,
|
|
239
|
+
thoughtsToken: 0,
|
|
240
|
+
},
|
|
241
|
+
finishReason: (_c = finalMessage.stop_reason) !== null && _c !== void 0 ? _c : undefined,
|
|
242
|
+
};
|
|
243
|
+
onChunk === null || onChunk === void 0 ? void 0 : onChunk({ isFinal: true, contentChunk: "" });
|
|
244
|
+
onFinalResponse === null || onFinalResponse === void 0 ? void 0 : onFinalResponse(finalResponse);
|
|
245
|
+
return finalResponse;
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
exports.AnthropicPromptAdapter = AnthropicPromptAdapter;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { ToolCall } from "../../common/types";
|
|
2
|
+
import { ToolAdapter } from "../../core/LLMAdapter";
|
|
3
|
+
export declare class AnthropicToolAdapter implements ToolAdapter {
|
|
4
|
+
formatToolCallResult(toolCall: ToolCall): any;
|
|
5
|
+
}
|
|
6
|
+
//# sourceMappingURL=AnthropicToolAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AnthropicToolAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/anthropic/AnthropicToolAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEpD,qBAAa,oBAAqB,YAAW,WAAW;IACtD,oBAAoB,CAAC,QAAQ,EAAE,QAAQ,GAAG,GAAG;CAe9C"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AnthropicToolAdapter = void 0;
|
|
4
|
+
class AnthropicToolAdapter {
|
|
5
|
+
formatToolCallResult(toolCall) {
|
|
6
|
+
return {
|
|
7
|
+
role: "user",
|
|
8
|
+
content: [
|
|
9
|
+
{
|
|
10
|
+
type: "tool_result",
|
|
11
|
+
tool_use_id: toolCall.id,
|
|
12
|
+
content: typeof toolCall.result === "string"
|
|
13
|
+
? toolCall.result
|
|
14
|
+
: JSON.stringify(toolCall.result),
|
|
15
|
+
},
|
|
16
|
+
],
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
exports.AnthropicToolAdapter = AnthropicToolAdapter;
|