@ziro-agent/anthropic 0.1.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/dist/index.cjs +370 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +21 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.js +367 -0
- package/dist/index.js.map +1 -0
- package/package.json +67 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var core = require('@ziro-agent/core');
|
|
4
|
+
|
|
5
|
+
// src/anthropic-messages-model.ts
|
|
6
|
+
|
|
7
|
+
// src/util/sse.ts
|
|
8
|
+
async function* parseSSEWithEvent(body) {
|
|
9
|
+
const reader = body.getReader();
|
|
10
|
+
const decoder = new TextDecoder("utf-8");
|
|
11
|
+
let buffer = "";
|
|
12
|
+
try {
|
|
13
|
+
while (true) {
|
|
14
|
+
const { done, value } = await reader.read();
|
|
15
|
+
if (done) {
|
|
16
|
+
if (buffer.trim().length > 0) {
|
|
17
|
+
const evt = parseBlock(buffer);
|
|
18
|
+
if (evt) yield evt;
|
|
19
|
+
}
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
buffer += decoder.decode(value, { stream: true });
|
|
23
|
+
while (true) {
|
|
24
|
+
const idx = findEventBoundary(buffer);
|
|
25
|
+
if (idx === -1) break;
|
|
26
|
+
const block = buffer.slice(0, idx);
|
|
27
|
+
buffer = buffer.slice(idx).replace(/^(\r?\n){2}/, "");
|
|
28
|
+
const evt = parseBlock(block);
|
|
29
|
+
if (evt) yield evt;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
} finally {
|
|
33
|
+
reader.releaseLock();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function findEventBoundary(s) {
|
|
37
|
+
const i1 = s.indexOf("\n\n");
|
|
38
|
+
const i2 = s.indexOf("\r\n\r\n");
|
|
39
|
+
if (i1 === -1) return i2;
|
|
40
|
+
if (i2 === -1) return i1;
|
|
41
|
+
return Math.min(i1, i2);
|
|
42
|
+
}
|
|
43
|
+
function parseBlock(block) {
|
|
44
|
+
const lines = block.split(/\r?\n/);
|
|
45
|
+
let event;
|
|
46
|
+
const data = [];
|
|
47
|
+
for (const line of lines) {
|
|
48
|
+
if (line.startsWith("event:")) event = line.slice(6).trim();
|
|
49
|
+
else if (line.startsWith("data:")) data.push(line.slice(5).replace(/^ /, ""));
|
|
50
|
+
}
|
|
51
|
+
if (data.length === 0 && !event) return null;
|
|
52
|
+
return { ...event !== void 0 ? { event } : {}, data: data.join("\n") };
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// src/anthropic-messages-model.ts
|
|
56
|
+
var AnthropicMessagesModel = class {
|
|
57
|
+
provider = "anthropic";
|
|
58
|
+
modelId;
|
|
59
|
+
config;
|
|
60
|
+
constructor(config) {
|
|
61
|
+
this.modelId = config.modelId;
|
|
62
|
+
this.config = config;
|
|
63
|
+
}
|
|
64
|
+
async generate(options) {
|
|
65
|
+
const body = this.buildBody(options, false);
|
|
66
|
+
const res = await this.fetch("/messages", body, options);
|
|
67
|
+
const json = await res.json();
|
|
68
|
+
const text = (json.content ?? []).filter((b) => b.type === "text").map((b) => b.text).join("");
|
|
69
|
+
const toolCalls = (json.content ?? []).filter((b) => b.type === "tool_use").map((b) => {
|
|
70
|
+
const tu = b;
|
|
71
|
+
return { type: "tool-call", toolCallId: tu.id, toolName: tu.name, args: tu.input };
|
|
72
|
+
});
|
|
73
|
+
return {
|
|
74
|
+
text,
|
|
75
|
+
content: [
|
|
76
|
+
...text.length > 0 ? [{ type: "text", text }] : [],
|
|
77
|
+
...toolCalls
|
|
78
|
+
],
|
|
79
|
+
toolCalls,
|
|
80
|
+
finishReason: mapFinishReason(json.stop_reason),
|
|
81
|
+
usage: mapUsage(json.usage),
|
|
82
|
+
rawResponse: json
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
async stream(options) {
|
|
86
|
+
const body = this.buildBody(options, true);
|
|
87
|
+
const res = await this.fetch("/messages", body, options);
|
|
88
|
+
if (!res.body) {
|
|
89
|
+
throw new core.APICallError({
|
|
90
|
+
message: "Anthropic streaming response has no body.",
|
|
91
|
+
statusCode: res.status
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
const events = parseSSEWithEvent(res.body);
|
|
95
|
+
return new ReadableStream({
|
|
96
|
+
async start(controller) {
|
|
97
|
+
const toolBlocks = /* @__PURE__ */ new Map();
|
|
98
|
+
let finish = "unknown";
|
|
99
|
+
let usage = {};
|
|
100
|
+
try {
|
|
101
|
+
for await (const evt of events) {
|
|
102
|
+
const data = parseEvent(evt);
|
|
103
|
+
if (!data) continue;
|
|
104
|
+
switch (data.type) {
|
|
105
|
+
case "message_start": {
|
|
106
|
+
const msg = data.message;
|
|
107
|
+
if (msg?.usage) usage = mergeUsage(usage, mapUsage(msg.usage));
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
case "content_block_start": {
|
|
111
|
+
const block = data.content_block;
|
|
112
|
+
if (block?.type === "tool_use" && typeof data.index === "number") {
|
|
113
|
+
toolBlocks.set(data.index, {
|
|
114
|
+
id: block.id ?? `tu_${data.index}`,
|
|
115
|
+
name: block.name ?? "",
|
|
116
|
+
argsBuffer: ""
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
break;
|
|
120
|
+
}
|
|
121
|
+
case "content_block_delta": {
|
|
122
|
+
const delta = data.delta;
|
|
123
|
+
if (delta?.type === "text_delta" && delta.text) {
|
|
124
|
+
controller.enqueue({ type: "text-delta", textDelta: delta.text });
|
|
125
|
+
} else if (delta?.type === "input_json_delta" && typeof data.index === "number" && delta.partial_json) {
|
|
126
|
+
const tb = toolBlocks.get(data.index);
|
|
127
|
+
if (tb) {
|
|
128
|
+
tb.argsBuffer += delta.partial_json;
|
|
129
|
+
controller.enqueue({
|
|
130
|
+
type: "tool-call-delta",
|
|
131
|
+
toolCallId: tb.id,
|
|
132
|
+
toolName: tb.name,
|
|
133
|
+
argsDelta: delta.partial_json
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
break;
|
|
138
|
+
}
|
|
139
|
+
case "message_delta": {
|
|
140
|
+
const delta = data.delta;
|
|
141
|
+
if (delta?.stop_reason) finish = mapFinishReason(delta.stop_reason);
|
|
142
|
+
if (data.usage) usage = mergeUsage(usage, mapUsage(data.usage));
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
145
|
+
case "message_stop": {
|
|
146
|
+
break;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
for (const tb of toolBlocks.values()) {
|
|
151
|
+
controller.enqueue({
|
|
152
|
+
type: "tool-call",
|
|
153
|
+
toolCallId: tb.id,
|
|
154
|
+
toolName: tb.name,
|
|
155
|
+
args: safeParseJSON(tb.argsBuffer)
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
controller.enqueue({ type: "finish", finishReason: finish, usage });
|
|
159
|
+
controller.close();
|
|
160
|
+
} catch (err) {
|
|
161
|
+
controller.enqueue({ type: "error", error: err });
|
|
162
|
+
controller.close();
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
buildBody(options, stream) {
|
|
168
|
+
const { system, messages } = splitSystem(options.messages);
|
|
169
|
+
const body = {
|
|
170
|
+
model: this.modelId,
|
|
171
|
+
messages: messages.map(toAnthropicMessage),
|
|
172
|
+
max_tokens: options.maxTokens ?? 4096
|
|
173
|
+
};
|
|
174
|
+
if (system) body["system"] = system;
|
|
175
|
+
if (stream) body["stream"] = true;
|
|
176
|
+
if (options.tools?.length) {
|
|
177
|
+
body["tools"] = options.tools.map((t) => ({
|
|
178
|
+
name: t.name,
|
|
179
|
+
...t.description !== void 0 ? { description: t.description } : {},
|
|
180
|
+
input_schema: t.parameters
|
|
181
|
+
}));
|
|
182
|
+
}
|
|
183
|
+
if (options.toolChoice !== void 0) {
|
|
184
|
+
if (options.toolChoice === "required") body["tool_choice"] = { type: "any" };
|
|
185
|
+
else if (options.toolChoice === "auto") body["tool_choice"] = { type: "auto" };
|
|
186
|
+
else if (options.toolChoice === "none") ; else if (typeof options.toolChoice === "object") {
|
|
187
|
+
body["tool_choice"] = { type: "tool", name: options.toolChoice.toolName };
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
if (options.temperature !== void 0) body["temperature"] = options.temperature;
|
|
191
|
+
if (options.topP !== void 0) body["top_p"] = options.topP;
|
|
192
|
+
if (options.topK !== void 0) body["top_k"] = options.topK;
|
|
193
|
+
if (options.stopSequences !== void 0) body["stop_sequences"] = options.stopSequences;
|
|
194
|
+
if (options.providerOptions) Object.assign(body, options.providerOptions);
|
|
195
|
+
return body;
|
|
196
|
+
}
|
|
197
|
+
async fetch(path, body, options) {
|
|
198
|
+
const url = `${this.config.baseURL}${path}`;
|
|
199
|
+
const headers = { ...this.config.headers, ...options.headers };
|
|
200
|
+
const init = {
|
|
201
|
+
method: "POST",
|
|
202
|
+
headers,
|
|
203
|
+
body: JSON.stringify(body)
|
|
204
|
+
};
|
|
205
|
+
if (options.abortSignal) init.signal = options.abortSignal;
|
|
206
|
+
const res = await this.config.fetcher(url, init);
|
|
207
|
+
if (!res.ok) {
|
|
208
|
+
const text = await res.text().catch(() => "");
|
|
209
|
+
throw new core.APICallError({
|
|
210
|
+
message: `Anthropic API error: ${res.status} ${res.statusText}`,
|
|
211
|
+
url,
|
|
212
|
+
statusCode: res.status,
|
|
213
|
+
responseBody: text
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
return res;
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
function splitSystem(messages) {
|
|
220
|
+
const sys = messages.filter((m) => m.role === "system");
|
|
221
|
+
const rest = messages.filter((m) => m.role !== "system");
|
|
222
|
+
if (sys.length === 0) return { messages: rest };
|
|
223
|
+
const text = sys.flatMap((m) => m.content).filter((p) => p.type === "text").map((p) => p.text).join("\n");
|
|
224
|
+
return { system: text, messages: rest };
|
|
225
|
+
}
|
|
226
|
+
function toAnthropicMessage(m) {
|
|
227
|
+
switch (m.role) {
|
|
228
|
+
case "user": {
|
|
229
|
+
const blocks = m.content.map((p) => {
|
|
230
|
+
if (p.type === "text") return { type: "text", text: p.text };
|
|
231
|
+
if (p.type === "image") {
|
|
232
|
+
if (typeof p.image === "string" && p.image.startsWith("http")) {
|
|
233
|
+
return { type: "image", source: { type: "url", url: p.image } };
|
|
234
|
+
}
|
|
235
|
+
if (typeof p.image === "string") {
|
|
236
|
+
return { type: "image", source: { type: "url", url: p.image } };
|
|
237
|
+
}
|
|
238
|
+
return {
|
|
239
|
+
type: "image",
|
|
240
|
+
source: {
|
|
241
|
+
type: "base64",
|
|
242
|
+
media_type: p.mimeType ?? "image/png",
|
|
243
|
+
data: uint8ToBase64(p.image)
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
return p;
|
|
248
|
+
});
|
|
249
|
+
return { role: "user", content: blocks };
|
|
250
|
+
}
|
|
251
|
+
case "assistant": {
|
|
252
|
+
const blocks = m.content.map((p) => {
|
|
253
|
+
if (p.type === "text") return { type: "text", text: p.text };
|
|
254
|
+
if (p.type === "tool-call") {
|
|
255
|
+
return { type: "tool_use", id: p.toolCallId, name: p.toolName, input: p.args };
|
|
256
|
+
}
|
|
257
|
+
return p;
|
|
258
|
+
});
|
|
259
|
+
return { role: "assistant", content: blocks };
|
|
260
|
+
}
|
|
261
|
+
case "tool": {
|
|
262
|
+
return {
|
|
263
|
+
role: "user",
|
|
264
|
+
content: m.content.filter((r) => r.type === "tool-result").map((r) => ({
|
|
265
|
+
type: "tool_result",
|
|
266
|
+
tool_use_id: r.toolCallId,
|
|
267
|
+
content: typeof r.result === "string" ? r.result : JSON.stringify(r.result),
|
|
268
|
+
...r.isError ? { is_error: true } : {}
|
|
269
|
+
}))
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
case "system":
|
|
273
|
+
return { role: "user", content: "" };
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
function parseEvent(evt) {
|
|
277
|
+
if (!evt.data) return null;
|
|
278
|
+
try {
|
|
279
|
+
return JSON.parse(evt.data);
|
|
280
|
+
} catch {
|
|
281
|
+
return null;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
function safeParseJSON(text) {
|
|
285
|
+
if (!text) return {};
|
|
286
|
+
try {
|
|
287
|
+
return JSON.parse(text);
|
|
288
|
+
} catch {
|
|
289
|
+
return text;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
function mapFinishReason(reason) {
|
|
293
|
+
switch (reason) {
|
|
294
|
+
case "end_turn":
|
|
295
|
+
return "stop";
|
|
296
|
+
case "max_tokens":
|
|
297
|
+
return "length";
|
|
298
|
+
case "tool_use":
|
|
299
|
+
return "tool-calls";
|
|
300
|
+
case "stop_sequence":
|
|
301
|
+
return "stop";
|
|
302
|
+
case null:
|
|
303
|
+
case void 0:
|
|
304
|
+
return "unknown";
|
|
305
|
+
default:
|
|
306
|
+
return "other";
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
function mapUsage(u) {
|
|
310
|
+
if (!u) return {};
|
|
311
|
+
const promptTokens = (u.input_tokens ?? 0) + (u.cache_read_input_tokens ?? 0) + (u.cache_creation_input_tokens ?? 0);
|
|
312
|
+
const out = {
|
|
313
|
+
promptTokens: u.input_tokens !== void 0 ? promptTokens : void 0,
|
|
314
|
+
completionTokens: u.output_tokens
|
|
315
|
+
};
|
|
316
|
+
if (out.promptTokens !== void 0 && out.completionTokens !== void 0) {
|
|
317
|
+
out.totalTokens = out.promptTokens + out.completionTokens;
|
|
318
|
+
}
|
|
319
|
+
if (u.cache_read_input_tokens !== void 0) out.cachedPromptTokens = u.cache_read_input_tokens;
|
|
320
|
+
return out;
|
|
321
|
+
}
|
|
322
|
+
function mergeUsage(a, b) {
|
|
323
|
+
const sum = (x, y) => x === void 0 && y === void 0 ? void 0 : (x ?? 0) + (y ?? 0);
|
|
324
|
+
return {
|
|
325
|
+
promptTokens: sum(a.promptTokens, b.promptTokens),
|
|
326
|
+
completionTokens: sum(a.completionTokens, b.completionTokens),
|
|
327
|
+
totalTokens: sum(a.totalTokens, b.totalTokens),
|
|
328
|
+
cachedPromptTokens: sum(a.cachedPromptTokens, b.cachedPromptTokens)
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
function uint8ToBase64(arr) {
|
|
332
|
+
let s = "";
|
|
333
|
+
for (let i = 0; i < arr.byteLength; i++) s += String.fromCharCode(arr[i]);
|
|
334
|
+
return typeof btoa !== "undefined" ? btoa(s) : Buffer.from(s, "binary").toString("base64");
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
// src/anthropic-provider.ts
|
|
338
|
+
function createAnthropic(options = {}) {
|
|
339
|
+
const apiKey = options.apiKey ?? loadEnv("ANTHROPIC_API_KEY");
|
|
340
|
+
const baseURL = options.baseURL ?? "https://api.anthropic.com/v1";
|
|
341
|
+
const version = options.version ?? "2023-06-01";
|
|
342
|
+
const fetcher = options.fetch ?? globalThis.fetch;
|
|
343
|
+
const headers = {
|
|
344
|
+
"Content-Type": "application/json",
|
|
345
|
+
"anthropic-version": version,
|
|
346
|
+
...options.headers
|
|
347
|
+
};
|
|
348
|
+
if (apiKey) headers["x-api-key"] = apiKey;
|
|
349
|
+
const make = (modelId) => new AnthropicMessagesModel({
|
|
350
|
+
modelId,
|
|
351
|
+
baseURL,
|
|
352
|
+
headers,
|
|
353
|
+
fetcher
|
|
354
|
+
});
|
|
355
|
+
const provider = ((modelId) => make(modelId));
|
|
356
|
+
provider.messages = make;
|
|
357
|
+
return provider;
|
|
358
|
+
}
|
|
359
|
+
var anthropic = createAnthropic();
|
|
360
|
+
function loadEnv(name) {
|
|
361
|
+
if (typeof process !== "undefined" && process.env) {
|
|
362
|
+
return process.env[name];
|
|
363
|
+
}
|
|
364
|
+
return void 0;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
exports.anthropic = anthropic;
|
|
368
|
+
exports.createAnthropic = createAnthropic;
|
|
369
|
+
//# sourceMappingURL=index.cjs.map
|
|
370
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/util/sse.ts","../src/anthropic-messages-model.ts","../src/anthropic-provider.ts"],"names":["APICallError"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Anthropic streams SSE with explicit `event:` lines (e.g. `content_block_delta`).\n * We surface both the event name and the data payload — the model logic decides\n * how to interpret them.\n */\nexport interface SSEEvent {\n event?: string;\n data: string;\n}\n\nexport async function* parseSSEWithEvent(\n body: ReadableStream<Uint8Array>,\n): AsyncIterable<SSEEvent> {\n const reader = body.getReader();\n const decoder = new TextDecoder('utf-8');\n let buffer = '';\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) {\n if (buffer.trim().length > 0) {\n const evt = parseBlock(buffer);\n if (evt) yield evt;\n }\n return;\n }\n buffer += decoder.decode(value, { stream: true });\n\n while (true) {\n const idx = findEventBoundary(buffer);\n if (idx === -1) break;\n const block = buffer.slice(0, idx);\n buffer = buffer.slice(idx).replace(/^(\\r?\\n){2}/, '');\n const evt = parseBlock(block);\n if (evt) yield evt;\n }\n }\n } finally {\n reader.releaseLock();\n }\n}\n\nfunction findEventBoundary(s: string): number {\n const i1 = s.indexOf('\\n\\n');\n const i2 = s.indexOf('\\r\\n\\r\\n');\n if (i1 === -1) return i2;\n if (i2 === -1) return i1;\n return Math.min(i1, i2);\n}\n\nfunction parseBlock(block: string): SSEEvent | null {\n const lines = block.split(/\\r?\\n/);\n let event: string | undefined;\n const data: string[] = [];\n for (const line of lines) {\n if (line.startsWith('event:')) event = line.slice(6).trim();\n else if (line.startsWith('data:')) data.push(line.slice(5).replace(/^ /, ''));\n }\n if (data.length === 0 && !event) return null;\n return { ...(event !== undefined ? { event } : {}), data: data.join('\\n') };\n}\n","import {\n APICallError,\n type FinishReason,\n type LanguageModel,\n type ModelCallOptions,\n type ModelGenerateResult,\n type ModelStreamPart,\n type NormalizedMessage,\n type TokenUsage,\n type ToolCallPart,\n} from '@ziro-agent/core';\nimport { parseSSEWithEvent, type SSEEvent } from './util/sse.js';\n\nexport type AnthropicMessagesModelId =\n | 'claude-opus-4-1'\n | 'claude-opus-4'\n | 'claude-sonnet-4-5'\n | 'claude-sonnet-4'\n | 'claude-3-7-sonnet-latest'\n | 'claude-3-5-sonnet-latest'\n | 'claude-3-5-haiku-latest'\n | 'claude-3-haiku-20240307'\n | (string & {});\n\ninterface AnthropicMessagesModelConfig {\n modelId: AnthropicMessagesModelId;\n baseURL: string;\n headers: Record<string, string>;\n fetcher: typeof fetch;\n}\n\nexport class AnthropicMessagesModel implements LanguageModel {\n readonly provider = 'anthropic';\n readonly modelId: string;\n private readonly config: AnthropicMessagesModelConfig;\n\n constructor(config: AnthropicMessagesModelConfig) {\n this.modelId = config.modelId;\n this.config = config;\n }\n\n async generate(options: ModelCallOptions): Promise<ModelGenerateResult> {\n const body = this.buildBody(options, false);\n const res = await this.fetch('/messages', body, options);\n const json = (await res.json()) as AnthropicMessageResponse;\n\n const text = (json.content ?? [])\n .filter((b) => b.type === 'text')\n .map((b) => (b as { text: string }).text)\n .join('');\n\n const toolCalls: ToolCallPart[] = (json.content ?? [])\n .filter((b) => b.type === 'tool_use')\n .map((b) => {\n const tu = b as { id: string; name: string; input: unknown };\n return { type: 'tool-call', toolCallId: tu.id, toolName: tu.name, args: tu.input };\n });\n\n return {\n text,\n content: [\n ...(text.length > 0 ? [{ type: 'text' as const, text }] : []),\n ...toolCalls,\n ],\n toolCalls,\n finishReason: mapFinishReason(json.stop_reason),\n usage: mapUsage(json.usage),\n rawResponse: json,\n };\n }\n\n async stream(options: ModelCallOptions): Promise<ReadableStream<ModelStreamPart>> {\n const body = this.buildBody(options, true);\n const res = await this.fetch('/messages', body, options);\n if (!res.body) {\n throw new APICallError({\n message: 'Anthropic streaming response has no body.',\n statusCode: res.status,\n });\n }\n\n const events = parseSSEWithEvent(res.body);\n\n return new ReadableStream<ModelStreamPart>({\n async start(controller) {\n const toolBlocks = new Map<number, { id: string; name: string; argsBuffer: string }>();\n let finish: FinishReason = 'unknown';\n let usage: TokenUsage = {};\n\n try {\n for await (const evt of events) {\n const data = parseEvent(evt);\n if (!data) continue;\n\n switch (data.type) {\n case 'message_start': {\n const msg = data.message as { usage?: AnthropicUsage } | undefined;\n if (msg?.usage) usage = mergeUsage(usage, mapUsage(msg.usage));\n break;\n }\n case 'content_block_start': {\n const block = data.content_block as\n | { type: string; id?: string; name?: string }\n | undefined;\n if (block?.type === 'tool_use' && typeof data.index === 'number') {\n toolBlocks.set(data.index, {\n id: block.id ?? `tu_${data.index}`,\n name: block.name ?? '',\n argsBuffer: '',\n });\n }\n break;\n }\n case 'content_block_delta': {\n const delta = data.delta as\n | { type: string; text?: string; partial_json?: string }\n | undefined;\n if (delta?.type === 'text_delta' && delta.text) {\n controller.enqueue({ type: 'text-delta', textDelta: delta.text });\n } else if (\n delta?.type === 'input_json_delta' &&\n typeof data.index === 'number' &&\n delta.partial_json\n ) {\n const tb = toolBlocks.get(data.index);\n if (tb) {\n tb.argsBuffer += delta.partial_json;\n controller.enqueue({\n type: 'tool-call-delta',\n toolCallId: tb.id,\n toolName: tb.name,\n argsDelta: delta.partial_json,\n });\n }\n }\n break;\n }\n case 'message_delta': {\n const delta = data.delta as { stop_reason?: string } | undefined;\n if (delta?.stop_reason) finish = mapFinishReason(delta.stop_reason);\n if (data.usage) usage = mergeUsage(usage, mapUsage(data.usage as AnthropicUsage));\n break;\n }\n case 'message_stop': {\n break;\n }\n }\n }\n\n for (const tb of toolBlocks.values()) {\n controller.enqueue({\n type: 'tool-call',\n toolCallId: tb.id,\n toolName: tb.name,\n args: safeParseJSON(tb.argsBuffer),\n });\n }\n\n controller.enqueue({ type: 'finish', finishReason: finish, usage });\n controller.close();\n } catch (err) {\n controller.enqueue({ type: 'error', error: err });\n controller.close();\n }\n },\n });\n }\n\n private buildBody(options: ModelCallOptions, stream: boolean): Record<string, unknown> {\n const { system, messages } = splitSystem(options.messages);\n\n const body: Record<string, unknown> = {\n model: this.modelId,\n messages: messages.map(toAnthropicMessage),\n max_tokens: options.maxTokens ?? 4096,\n };\n if (system) body['system'] = system;\n if (stream) body['stream'] = true;\n if (options.tools?.length) {\n body['tools'] = options.tools.map((t) => ({\n name: t.name,\n ...(t.description !== undefined ? { description: t.description } : {}),\n input_schema: t.parameters,\n }));\n }\n if (options.toolChoice !== undefined) {\n if (options.toolChoice === 'required') body['tool_choice'] = { type: 'any' };\n else if (options.toolChoice === 'auto') body['tool_choice'] = { type: 'auto' };\n else if (options.toolChoice === 'none') {\n // Anthropic has no explicit \"none\" — skip.\n } else if (typeof options.toolChoice === 'object') {\n body['tool_choice'] = { type: 'tool', name: options.toolChoice.toolName };\n }\n }\n if (options.temperature !== undefined) body['temperature'] = options.temperature;\n if (options.topP !== undefined) body['top_p'] = options.topP;\n if (options.topK !== undefined) body['top_k'] = options.topK;\n if (options.stopSequences !== undefined) body['stop_sequences'] = options.stopSequences;\n if (options.providerOptions) Object.assign(body, options.providerOptions);\n return body;\n }\n\n private async fetch(\n path: string,\n body: unknown,\n options: ModelCallOptions,\n ): Promise<Response> {\n const url = `${this.config.baseURL}${path}`;\n const headers = { ...this.config.headers, ...options.headers };\n const init: RequestInit = {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n };\n if (options.abortSignal) init.signal = options.abortSignal;\n\n const res = await this.config.fetcher(url, init);\n if (!res.ok) {\n const text = await res.text().catch(() => '');\n throw new APICallError({\n message: `Anthropic API error: ${res.status} ${res.statusText}`,\n url,\n statusCode: res.status,\n responseBody: text,\n });\n }\n return res;\n }\n}\n\nfunction splitSystem(messages: NormalizedMessage[]): {\n system?: string;\n messages: NormalizedMessage[];\n} {\n const sys = messages.filter((m) => m.role === 'system');\n const rest = messages.filter((m) => m.role !== 'system');\n if (sys.length === 0) return { messages: rest };\n const text = sys\n .flatMap((m) => m.content)\n .filter((p) => p.type === 'text')\n .map((p) => (p as { text: string }).text)\n .join('\\n');\n return { system: text, messages: rest };\n}\n\nfunction toAnthropicMessage(m: NormalizedMessage): unknown {\n switch (m.role) {\n case 'user': {\n const blocks = m.content.map((p) => {\n if (p.type === 'text') return { type: 'text', text: p.text };\n if (p.type === 'image') {\n if (typeof p.image === 'string' && p.image.startsWith('http')) {\n return { type: 'image', source: { type: 'url', url: p.image } };\n }\n if (typeof p.image === 'string') {\n return { type: 'image', source: { type: 'url', url: p.image } };\n }\n return {\n type: 'image',\n source: {\n type: 'base64',\n media_type: p.mimeType ?? 'image/png',\n data: uint8ToBase64(p.image as Uint8Array),\n },\n };\n }\n return p;\n });\n return { role: 'user', content: blocks };\n }\n case 'assistant': {\n const blocks = m.content.map((p) => {\n if (p.type === 'text') return { type: 'text', text: p.text };\n if (p.type === 'tool-call') {\n return { type: 'tool_use', id: p.toolCallId, name: p.toolName, input: p.args };\n }\n return p;\n });\n return { role: 'assistant', content: blocks };\n }\n case 'tool': {\n return {\n role: 'user',\n content: m.content\n .filter((r): r is Extract<typeof r, { type: 'tool-result' }> => r.type === 'tool-result')\n .map((r) => ({\n type: 'tool_result',\n tool_use_id: r.toolCallId,\n content: typeof r.result === 'string' ? r.result : JSON.stringify(r.result),\n ...(r.isError ? { is_error: true } : {}),\n })),\n };\n }\n case 'system':\n return { role: 'user', content: '' };\n }\n}\n\nfunction parseEvent(evt: SSEEvent): { type: string; [k: string]: unknown } | null {\n if (!evt.data) return null;\n try {\n return JSON.parse(evt.data) as { type: string };\n } catch {\n return null;\n }\n}\n\nfunction safeParseJSON(text: string): unknown {\n if (!text) return {};\n try {\n return JSON.parse(text);\n } catch {\n return text;\n }\n}\n\nfunction mapFinishReason(reason: string | null | undefined): FinishReason {\n switch (reason) {\n case 'end_turn':\n return 'stop';\n case 'max_tokens':\n return 'length';\n case 'tool_use':\n return 'tool-calls';\n case 'stop_sequence':\n return 'stop';\n case null:\n case undefined:\n return 'unknown';\n default:\n return 'other';\n }\n}\n\ninterface AnthropicUsage {\n input_tokens?: number;\n output_tokens?: number;\n cache_read_input_tokens?: number;\n cache_creation_input_tokens?: number;\n}\n\nfunction mapUsage(u: AnthropicUsage | undefined): TokenUsage {\n if (!u) return {};\n const promptTokens =\n (u.input_tokens ?? 0) +\n (u.cache_read_input_tokens ?? 0) +\n (u.cache_creation_input_tokens ?? 0);\n const out: TokenUsage = {\n promptTokens: u.input_tokens !== undefined ? promptTokens : undefined,\n completionTokens: u.output_tokens,\n };\n if (out.promptTokens !== undefined && out.completionTokens !== undefined) {\n out.totalTokens = out.promptTokens + out.completionTokens;\n }\n if (u.cache_read_input_tokens !== undefined) out.cachedPromptTokens = u.cache_read_input_tokens;\n return out;\n}\n\nfunction mergeUsage(a: TokenUsage, b: TokenUsage): TokenUsage {\n const sum = (x?: number, y?: number) =>\n x === undefined && y === undefined ? undefined : (x ?? 0) + (y ?? 0);\n return {\n promptTokens: sum(a.promptTokens, b.promptTokens),\n completionTokens: sum(a.completionTokens, b.completionTokens),\n totalTokens: sum(a.totalTokens, b.totalTokens),\n cachedPromptTokens: sum(a.cachedPromptTokens, b.cachedPromptTokens),\n };\n}\n\nfunction uint8ToBase64(arr: Uint8Array): string {\n let s = '';\n for (let i = 0; i < arr.byteLength; i++) s += String.fromCharCode(arr[i] as number);\n return typeof btoa !== 'undefined'\n ? btoa(s)\n : Buffer.from(s, 'binary').toString('base64');\n}\n\ninterface AnthropicMessageResponse {\n content?: Array<\n | { type: 'text'; text: string }\n | { type: 'tool_use'; id: string; name: string; input: unknown }\n >;\n stop_reason?: string;\n usage?: AnthropicUsage;\n}\n","import type { LanguageModel } from '@ziro-agent/core';\nimport {\n AnthropicMessagesModel,\n type AnthropicMessagesModelId,\n} from './anthropic-messages-model.js';\n\nexport interface AnthropicProviderOptions {\n /** Defaults to `process.env.ANTHROPIC_API_KEY`. */\n apiKey?: string;\n baseURL?: string;\n /** API version sent in `anthropic-version`. Defaults to `2023-06-01`. */\n version?: string;\n headers?: Record<string, string>;\n fetch?: typeof fetch;\n}\n\nexport interface AnthropicProvider {\n (modelId: AnthropicMessagesModelId): LanguageModel;\n messages(modelId: AnthropicMessagesModelId): LanguageModel;\n}\n\nexport function createAnthropic(options: AnthropicProviderOptions = {}): AnthropicProvider {\n const apiKey = options.apiKey ?? loadEnv('ANTHROPIC_API_KEY');\n const baseURL = options.baseURL ?? 'https://api.anthropic.com/v1';\n const version = options.version ?? '2023-06-01';\n const fetcher = options.fetch ?? globalThis.fetch;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'anthropic-version': version,\n ...options.headers,\n };\n if (apiKey) headers['x-api-key'] = apiKey;\n\n const make = (modelId: AnthropicMessagesModelId): LanguageModel =>\n new AnthropicMessagesModel({\n modelId,\n baseURL,\n headers,\n fetcher,\n });\n\n const provider = ((modelId: AnthropicMessagesModelId) => make(modelId)) as AnthropicProvider;\n provider.messages = make;\n return provider;\n}\n\nexport const anthropic: AnthropicProvider = createAnthropic();\n\nfunction loadEnv(name: string): string | undefined {\n if (typeof process !== 'undefined' && process.env) {\n return process.env[name];\n }\n return undefined;\n}\n"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { LanguageModel } from '@ziro-agent/core';
|
|
2
|
+
|
|
3
|
+
type AnthropicMessagesModelId = 'claude-opus-4-1' | 'claude-opus-4' | 'claude-sonnet-4-5' | 'claude-sonnet-4' | 'claude-3-7-sonnet-latest' | 'claude-3-5-sonnet-latest' | 'claude-3-5-haiku-latest' | 'claude-3-haiku-20240307' | (string & {});
|
|
4
|
+
|
|
5
|
+
interface AnthropicProviderOptions {
|
|
6
|
+
/** Defaults to `process.env.ANTHROPIC_API_KEY`. */
|
|
7
|
+
apiKey?: string;
|
|
8
|
+
baseURL?: string;
|
|
9
|
+
/** API version sent in `anthropic-version`. Defaults to `2023-06-01`. */
|
|
10
|
+
version?: string;
|
|
11
|
+
headers?: Record<string, string>;
|
|
12
|
+
fetch?: typeof fetch;
|
|
13
|
+
}
|
|
14
|
+
interface AnthropicProvider {
|
|
15
|
+
(modelId: AnthropicMessagesModelId): LanguageModel;
|
|
16
|
+
messages(modelId: AnthropicMessagesModelId): LanguageModel;
|
|
17
|
+
}
|
|
18
|
+
declare function createAnthropic(options?: AnthropicProviderOptions): AnthropicProvider;
|
|
19
|
+
declare const anthropic: AnthropicProvider;
|
|
20
|
+
|
|
21
|
+
export { type AnthropicMessagesModelId, type AnthropicProviderOptions, anthropic, createAnthropic };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { LanguageModel } from '@ziro-agent/core';
|
|
2
|
+
|
|
3
|
+
type AnthropicMessagesModelId = 'claude-opus-4-1' | 'claude-opus-4' | 'claude-sonnet-4-5' | 'claude-sonnet-4' | 'claude-3-7-sonnet-latest' | 'claude-3-5-sonnet-latest' | 'claude-3-5-haiku-latest' | 'claude-3-haiku-20240307' | (string & {});
|
|
4
|
+
|
|
5
|
+
interface AnthropicProviderOptions {
|
|
6
|
+
/** Defaults to `process.env.ANTHROPIC_API_KEY`. */
|
|
7
|
+
apiKey?: string;
|
|
8
|
+
baseURL?: string;
|
|
9
|
+
/** API version sent in `anthropic-version`. Defaults to `2023-06-01`. */
|
|
10
|
+
version?: string;
|
|
11
|
+
headers?: Record<string, string>;
|
|
12
|
+
fetch?: typeof fetch;
|
|
13
|
+
}
|
|
14
|
+
interface AnthropicProvider {
|
|
15
|
+
(modelId: AnthropicMessagesModelId): LanguageModel;
|
|
16
|
+
messages(modelId: AnthropicMessagesModelId): LanguageModel;
|
|
17
|
+
}
|
|
18
|
+
declare function createAnthropic(options?: AnthropicProviderOptions): AnthropicProvider;
|
|
19
|
+
declare const anthropic: AnthropicProvider;
|
|
20
|
+
|
|
21
|
+
export { type AnthropicMessagesModelId, type AnthropicProviderOptions, anthropic, createAnthropic };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
import { APICallError } from '@ziro-agent/core';
|
|
2
|
+
|
|
3
|
+
// src/anthropic-messages-model.ts
|
|
4
|
+
|
|
5
|
+
// src/util/sse.ts
|
|
6
|
+
async function* parseSSEWithEvent(body) {
|
|
7
|
+
const reader = body.getReader();
|
|
8
|
+
const decoder = new TextDecoder("utf-8");
|
|
9
|
+
let buffer = "";
|
|
10
|
+
try {
|
|
11
|
+
while (true) {
|
|
12
|
+
const { done, value } = await reader.read();
|
|
13
|
+
if (done) {
|
|
14
|
+
if (buffer.trim().length > 0) {
|
|
15
|
+
const evt = parseBlock(buffer);
|
|
16
|
+
if (evt) yield evt;
|
|
17
|
+
}
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
buffer += decoder.decode(value, { stream: true });
|
|
21
|
+
while (true) {
|
|
22
|
+
const idx = findEventBoundary(buffer);
|
|
23
|
+
if (idx === -1) break;
|
|
24
|
+
const block = buffer.slice(0, idx);
|
|
25
|
+
buffer = buffer.slice(idx).replace(/^(\r?\n){2}/, "");
|
|
26
|
+
const evt = parseBlock(block);
|
|
27
|
+
if (evt) yield evt;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
} finally {
|
|
31
|
+
reader.releaseLock();
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function findEventBoundary(s) {
|
|
35
|
+
const i1 = s.indexOf("\n\n");
|
|
36
|
+
const i2 = s.indexOf("\r\n\r\n");
|
|
37
|
+
if (i1 === -1) return i2;
|
|
38
|
+
if (i2 === -1) return i1;
|
|
39
|
+
return Math.min(i1, i2);
|
|
40
|
+
}
|
|
41
|
+
function parseBlock(block) {
|
|
42
|
+
const lines = block.split(/\r?\n/);
|
|
43
|
+
let event;
|
|
44
|
+
const data = [];
|
|
45
|
+
for (const line of lines) {
|
|
46
|
+
if (line.startsWith("event:")) event = line.slice(6).trim();
|
|
47
|
+
else if (line.startsWith("data:")) data.push(line.slice(5).replace(/^ /, ""));
|
|
48
|
+
}
|
|
49
|
+
if (data.length === 0 && !event) return null;
|
|
50
|
+
return { ...event !== void 0 ? { event } : {}, data: data.join("\n") };
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// src/anthropic-messages-model.ts
|
|
54
|
+
var AnthropicMessagesModel = class {
|
|
55
|
+
provider = "anthropic";
|
|
56
|
+
modelId;
|
|
57
|
+
config;
|
|
58
|
+
constructor(config) {
|
|
59
|
+
this.modelId = config.modelId;
|
|
60
|
+
this.config = config;
|
|
61
|
+
}
|
|
62
|
+
async generate(options) {
|
|
63
|
+
const body = this.buildBody(options, false);
|
|
64
|
+
const res = await this.fetch("/messages", body, options);
|
|
65
|
+
const json = await res.json();
|
|
66
|
+
const text = (json.content ?? []).filter((b) => b.type === "text").map((b) => b.text).join("");
|
|
67
|
+
const toolCalls = (json.content ?? []).filter((b) => b.type === "tool_use").map((b) => {
|
|
68
|
+
const tu = b;
|
|
69
|
+
return { type: "tool-call", toolCallId: tu.id, toolName: tu.name, args: tu.input };
|
|
70
|
+
});
|
|
71
|
+
return {
|
|
72
|
+
text,
|
|
73
|
+
content: [
|
|
74
|
+
...text.length > 0 ? [{ type: "text", text }] : [],
|
|
75
|
+
...toolCalls
|
|
76
|
+
],
|
|
77
|
+
toolCalls,
|
|
78
|
+
finishReason: mapFinishReason(json.stop_reason),
|
|
79
|
+
usage: mapUsage(json.usage),
|
|
80
|
+
rawResponse: json
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
async stream(options) {
|
|
84
|
+
const body = this.buildBody(options, true);
|
|
85
|
+
const res = await this.fetch("/messages", body, options);
|
|
86
|
+
if (!res.body) {
|
|
87
|
+
throw new APICallError({
|
|
88
|
+
message: "Anthropic streaming response has no body.",
|
|
89
|
+
statusCode: res.status
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
const events = parseSSEWithEvent(res.body);
|
|
93
|
+
return new ReadableStream({
|
|
94
|
+
async start(controller) {
|
|
95
|
+
const toolBlocks = /* @__PURE__ */ new Map();
|
|
96
|
+
let finish = "unknown";
|
|
97
|
+
let usage = {};
|
|
98
|
+
try {
|
|
99
|
+
for await (const evt of events) {
|
|
100
|
+
const data = parseEvent(evt);
|
|
101
|
+
if (!data) continue;
|
|
102
|
+
switch (data.type) {
|
|
103
|
+
case "message_start": {
|
|
104
|
+
const msg = data.message;
|
|
105
|
+
if (msg?.usage) usage = mergeUsage(usage, mapUsage(msg.usage));
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
case "content_block_start": {
|
|
109
|
+
const block = data.content_block;
|
|
110
|
+
if (block?.type === "tool_use" && typeof data.index === "number") {
|
|
111
|
+
toolBlocks.set(data.index, {
|
|
112
|
+
id: block.id ?? `tu_${data.index}`,
|
|
113
|
+
name: block.name ?? "",
|
|
114
|
+
argsBuffer: ""
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
break;
|
|
118
|
+
}
|
|
119
|
+
case "content_block_delta": {
|
|
120
|
+
const delta = data.delta;
|
|
121
|
+
if (delta?.type === "text_delta" && delta.text) {
|
|
122
|
+
controller.enqueue({ type: "text-delta", textDelta: delta.text });
|
|
123
|
+
} else if (delta?.type === "input_json_delta" && typeof data.index === "number" && delta.partial_json) {
|
|
124
|
+
const tb = toolBlocks.get(data.index);
|
|
125
|
+
if (tb) {
|
|
126
|
+
tb.argsBuffer += delta.partial_json;
|
|
127
|
+
controller.enqueue({
|
|
128
|
+
type: "tool-call-delta",
|
|
129
|
+
toolCallId: tb.id,
|
|
130
|
+
toolName: tb.name,
|
|
131
|
+
argsDelta: delta.partial_json
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
break;
|
|
136
|
+
}
|
|
137
|
+
case "message_delta": {
|
|
138
|
+
const delta = data.delta;
|
|
139
|
+
if (delta?.stop_reason) finish = mapFinishReason(delta.stop_reason);
|
|
140
|
+
if (data.usage) usage = mergeUsage(usage, mapUsage(data.usage));
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
case "message_stop": {
|
|
144
|
+
break;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
for (const tb of toolBlocks.values()) {
|
|
149
|
+
controller.enqueue({
|
|
150
|
+
type: "tool-call",
|
|
151
|
+
toolCallId: tb.id,
|
|
152
|
+
toolName: tb.name,
|
|
153
|
+
args: safeParseJSON(tb.argsBuffer)
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
controller.enqueue({ type: "finish", finishReason: finish, usage });
|
|
157
|
+
controller.close();
|
|
158
|
+
} catch (err) {
|
|
159
|
+
controller.enqueue({ type: "error", error: err });
|
|
160
|
+
controller.close();
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
buildBody(options, stream) {
|
|
166
|
+
const { system, messages } = splitSystem(options.messages);
|
|
167
|
+
const body = {
|
|
168
|
+
model: this.modelId,
|
|
169
|
+
messages: messages.map(toAnthropicMessage),
|
|
170
|
+
max_tokens: options.maxTokens ?? 4096
|
|
171
|
+
};
|
|
172
|
+
if (system) body["system"] = system;
|
|
173
|
+
if (stream) body["stream"] = true;
|
|
174
|
+
if (options.tools?.length) {
|
|
175
|
+
body["tools"] = options.tools.map((t) => ({
|
|
176
|
+
name: t.name,
|
|
177
|
+
...t.description !== void 0 ? { description: t.description } : {},
|
|
178
|
+
input_schema: t.parameters
|
|
179
|
+
}));
|
|
180
|
+
}
|
|
181
|
+
if (options.toolChoice !== void 0) {
|
|
182
|
+
if (options.toolChoice === "required") body["tool_choice"] = { type: "any" };
|
|
183
|
+
else if (options.toolChoice === "auto") body["tool_choice"] = { type: "auto" };
|
|
184
|
+
else if (options.toolChoice === "none") ; else if (typeof options.toolChoice === "object") {
|
|
185
|
+
body["tool_choice"] = { type: "tool", name: options.toolChoice.toolName };
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
if (options.temperature !== void 0) body["temperature"] = options.temperature;
|
|
189
|
+
if (options.topP !== void 0) body["top_p"] = options.topP;
|
|
190
|
+
if (options.topK !== void 0) body["top_k"] = options.topK;
|
|
191
|
+
if (options.stopSequences !== void 0) body["stop_sequences"] = options.stopSequences;
|
|
192
|
+
if (options.providerOptions) Object.assign(body, options.providerOptions);
|
|
193
|
+
return body;
|
|
194
|
+
}
|
|
195
|
+
async fetch(path, body, options) {
|
|
196
|
+
const url = `${this.config.baseURL}${path}`;
|
|
197
|
+
const headers = { ...this.config.headers, ...options.headers };
|
|
198
|
+
const init = {
|
|
199
|
+
method: "POST",
|
|
200
|
+
headers,
|
|
201
|
+
body: JSON.stringify(body)
|
|
202
|
+
};
|
|
203
|
+
if (options.abortSignal) init.signal = options.abortSignal;
|
|
204
|
+
const res = await this.config.fetcher(url, init);
|
|
205
|
+
if (!res.ok) {
|
|
206
|
+
const text = await res.text().catch(() => "");
|
|
207
|
+
throw new APICallError({
|
|
208
|
+
message: `Anthropic API error: ${res.status} ${res.statusText}`,
|
|
209
|
+
url,
|
|
210
|
+
statusCode: res.status,
|
|
211
|
+
responseBody: text
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
return res;
|
|
215
|
+
}
|
|
216
|
+
};
|
|
217
|
+
function splitSystem(messages) {
|
|
218
|
+
const sys = messages.filter((m) => m.role === "system");
|
|
219
|
+
const rest = messages.filter((m) => m.role !== "system");
|
|
220
|
+
if (sys.length === 0) return { messages: rest };
|
|
221
|
+
const text = sys.flatMap((m) => m.content).filter((p) => p.type === "text").map((p) => p.text).join("\n");
|
|
222
|
+
return { system: text, messages: rest };
|
|
223
|
+
}
|
|
224
|
+
function toAnthropicMessage(m) {
|
|
225
|
+
switch (m.role) {
|
|
226
|
+
case "user": {
|
|
227
|
+
const blocks = m.content.map((p) => {
|
|
228
|
+
if (p.type === "text") return { type: "text", text: p.text };
|
|
229
|
+
if (p.type === "image") {
|
|
230
|
+
if (typeof p.image === "string" && p.image.startsWith("http")) {
|
|
231
|
+
return { type: "image", source: { type: "url", url: p.image } };
|
|
232
|
+
}
|
|
233
|
+
if (typeof p.image === "string") {
|
|
234
|
+
return { type: "image", source: { type: "url", url: p.image } };
|
|
235
|
+
}
|
|
236
|
+
return {
|
|
237
|
+
type: "image",
|
|
238
|
+
source: {
|
|
239
|
+
type: "base64",
|
|
240
|
+
media_type: p.mimeType ?? "image/png",
|
|
241
|
+
data: uint8ToBase64(p.image)
|
|
242
|
+
}
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
return p;
|
|
246
|
+
});
|
|
247
|
+
return { role: "user", content: blocks };
|
|
248
|
+
}
|
|
249
|
+
case "assistant": {
|
|
250
|
+
const blocks = m.content.map((p) => {
|
|
251
|
+
if (p.type === "text") return { type: "text", text: p.text };
|
|
252
|
+
if (p.type === "tool-call") {
|
|
253
|
+
return { type: "tool_use", id: p.toolCallId, name: p.toolName, input: p.args };
|
|
254
|
+
}
|
|
255
|
+
return p;
|
|
256
|
+
});
|
|
257
|
+
return { role: "assistant", content: blocks };
|
|
258
|
+
}
|
|
259
|
+
case "tool": {
|
|
260
|
+
return {
|
|
261
|
+
role: "user",
|
|
262
|
+
content: m.content.filter((r) => r.type === "tool-result").map((r) => ({
|
|
263
|
+
type: "tool_result",
|
|
264
|
+
tool_use_id: r.toolCallId,
|
|
265
|
+
content: typeof r.result === "string" ? r.result : JSON.stringify(r.result),
|
|
266
|
+
...r.isError ? { is_error: true } : {}
|
|
267
|
+
}))
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
case "system":
|
|
271
|
+
return { role: "user", content: "" };
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
function parseEvent(evt) {
|
|
275
|
+
if (!evt.data) return null;
|
|
276
|
+
try {
|
|
277
|
+
return JSON.parse(evt.data);
|
|
278
|
+
} catch {
|
|
279
|
+
return null;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
function safeParseJSON(text) {
|
|
283
|
+
if (!text) return {};
|
|
284
|
+
try {
|
|
285
|
+
return JSON.parse(text);
|
|
286
|
+
} catch {
|
|
287
|
+
return text;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
function mapFinishReason(reason) {
|
|
291
|
+
switch (reason) {
|
|
292
|
+
case "end_turn":
|
|
293
|
+
return "stop";
|
|
294
|
+
case "max_tokens":
|
|
295
|
+
return "length";
|
|
296
|
+
case "tool_use":
|
|
297
|
+
return "tool-calls";
|
|
298
|
+
case "stop_sequence":
|
|
299
|
+
return "stop";
|
|
300
|
+
case null:
|
|
301
|
+
case void 0:
|
|
302
|
+
return "unknown";
|
|
303
|
+
default:
|
|
304
|
+
return "other";
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
function mapUsage(u) {
|
|
308
|
+
if (!u) return {};
|
|
309
|
+
const promptTokens = (u.input_tokens ?? 0) + (u.cache_read_input_tokens ?? 0) + (u.cache_creation_input_tokens ?? 0);
|
|
310
|
+
const out = {
|
|
311
|
+
promptTokens: u.input_tokens !== void 0 ? promptTokens : void 0,
|
|
312
|
+
completionTokens: u.output_tokens
|
|
313
|
+
};
|
|
314
|
+
if (out.promptTokens !== void 0 && out.completionTokens !== void 0) {
|
|
315
|
+
out.totalTokens = out.promptTokens + out.completionTokens;
|
|
316
|
+
}
|
|
317
|
+
if (u.cache_read_input_tokens !== void 0) out.cachedPromptTokens = u.cache_read_input_tokens;
|
|
318
|
+
return out;
|
|
319
|
+
}
|
|
320
|
+
function mergeUsage(a, b) {
|
|
321
|
+
const sum = (x, y) => x === void 0 && y === void 0 ? void 0 : (x ?? 0) + (y ?? 0);
|
|
322
|
+
return {
|
|
323
|
+
promptTokens: sum(a.promptTokens, b.promptTokens),
|
|
324
|
+
completionTokens: sum(a.completionTokens, b.completionTokens),
|
|
325
|
+
totalTokens: sum(a.totalTokens, b.totalTokens),
|
|
326
|
+
cachedPromptTokens: sum(a.cachedPromptTokens, b.cachedPromptTokens)
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
function uint8ToBase64(arr) {
|
|
330
|
+
let s = "";
|
|
331
|
+
for (let i = 0; i < arr.byteLength; i++) s += String.fromCharCode(arr[i]);
|
|
332
|
+
return typeof btoa !== "undefined" ? btoa(s) : Buffer.from(s, "binary").toString("base64");
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
// src/anthropic-provider.ts
|
|
336
|
+
function createAnthropic(options = {}) {
|
|
337
|
+
const apiKey = options.apiKey ?? loadEnv("ANTHROPIC_API_KEY");
|
|
338
|
+
const baseURL = options.baseURL ?? "https://api.anthropic.com/v1";
|
|
339
|
+
const version = options.version ?? "2023-06-01";
|
|
340
|
+
const fetcher = options.fetch ?? globalThis.fetch;
|
|
341
|
+
const headers = {
|
|
342
|
+
"Content-Type": "application/json",
|
|
343
|
+
"anthropic-version": version,
|
|
344
|
+
...options.headers
|
|
345
|
+
};
|
|
346
|
+
if (apiKey) headers["x-api-key"] = apiKey;
|
|
347
|
+
const make = (modelId) => new AnthropicMessagesModel({
|
|
348
|
+
modelId,
|
|
349
|
+
baseURL,
|
|
350
|
+
headers,
|
|
351
|
+
fetcher
|
|
352
|
+
});
|
|
353
|
+
const provider = ((modelId) => make(modelId));
|
|
354
|
+
provider.messages = make;
|
|
355
|
+
return provider;
|
|
356
|
+
}
|
|
357
|
+
var anthropic = createAnthropic();
|
|
358
|
+
function loadEnv(name) {
|
|
359
|
+
if (typeof process !== "undefined" && process.env) {
|
|
360
|
+
return process.env[name];
|
|
361
|
+
}
|
|
362
|
+
return void 0;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
export { anthropic, createAnthropic };
|
|
366
|
+
//# sourceMappingURL=index.js.map
|
|
367
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/util/sse.ts","../src/anthropic-messages-model.ts","../src/anthropic-provider.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Anthropic streams SSE with explicit `event:` lines (e.g. `content_block_delta`).\n * We surface both the event name and the data payload — the model logic decides\n * how to interpret them.\n */\nexport interface SSEEvent {\n event?: string;\n data: string;\n}\n\nexport async function* parseSSEWithEvent(\n body: ReadableStream<Uint8Array>,\n): AsyncIterable<SSEEvent> {\n const reader = body.getReader();\n const decoder = new TextDecoder('utf-8');\n let buffer = '';\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) {\n if (buffer.trim().length > 0) {\n const evt = parseBlock(buffer);\n if (evt) yield evt;\n }\n return;\n }\n buffer += decoder.decode(value, { stream: true });\n\n while (true) {\n const idx = findEventBoundary(buffer);\n if (idx === -1) break;\n const block = buffer.slice(0, idx);\n buffer = buffer.slice(idx).replace(/^(\\r?\\n){2}/, '');\n const evt = parseBlock(block);\n if (evt) yield evt;\n }\n }\n } finally {\n reader.releaseLock();\n }\n}\n\nfunction findEventBoundary(s: string): number {\n const i1 = s.indexOf('\\n\\n');\n const i2 = s.indexOf('\\r\\n\\r\\n');\n if (i1 === -1) return i2;\n if (i2 === -1) return i1;\n return Math.min(i1, i2);\n}\n\nfunction parseBlock(block: string): SSEEvent | null {\n const lines = block.split(/\\r?\\n/);\n let event: string | undefined;\n const data: string[] = [];\n for (const line of lines) {\n if (line.startsWith('event:')) event = line.slice(6).trim();\n else if (line.startsWith('data:')) data.push(line.slice(5).replace(/^ /, ''));\n }\n if (data.length === 0 && !event) return null;\n return { ...(event !== undefined ? { event } : {}), data: data.join('\\n') };\n}\n","import {\n APICallError,\n type FinishReason,\n type LanguageModel,\n type ModelCallOptions,\n type ModelGenerateResult,\n type ModelStreamPart,\n type NormalizedMessage,\n type TokenUsage,\n type ToolCallPart,\n} from '@ziro-agent/core';\nimport { parseSSEWithEvent, type SSEEvent } from './util/sse.js';\n\nexport type AnthropicMessagesModelId =\n | 'claude-opus-4-1'\n | 'claude-opus-4'\n | 'claude-sonnet-4-5'\n | 'claude-sonnet-4'\n | 'claude-3-7-sonnet-latest'\n | 'claude-3-5-sonnet-latest'\n | 'claude-3-5-haiku-latest'\n | 'claude-3-haiku-20240307'\n | (string & {});\n\ninterface AnthropicMessagesModelConfig {\n modelId: AnthropicMessagesModelId;\n baseURL: string;\n headers: Record<string, string>;\n fetcher: typeof fetch;\n}\n\nexport class AnthropicMessagesModel implements LanguageModel {\n readonly provider = 'anthropic';\n readonly modelId: string;\n private readonly config: AnthropicMessagesModelConfig;\n\n constructor(config: AnthropicMessagesModelConfig) {\n this.modelId = config.modelId;\n this.config = config;\n }\n\n async generate(options: ModelCallOptions): Promise<ModelGenerateResult> {\n const body = this.buildBody(options, false);\n const res = await this.fetch('/messages', body, options);\n const json = (await res.json()) as AnthropicMessageResponse;\n\n const text = (json.content ?? [])\n .filter((b) => b.type === 'text')\n .map((b) => (b as { text: string }).text)\n .join('');\n\n const toolCalls: ToolCallPart[] = (json.content ?? [])\n .filter((b) => b.type === 'tool_use')\n .map((b) => {\n const tu = b as { id: string; name: string; input: unknown };\n return { type: 'tool-call', toolCallId: tu.id, toolName: tu.name, args: tu.input };\n });\n\n return {\n text,\n content: [\n ...(text.length > 0 ? [{ type: 'text' as const, text }] : []),\n ...toolCalls,\n ],\n toolCalls,\n finishReason: mapFinishReason(json.stop_reason),\n usage: mapUsage(json.usage),\n rawResponse: json,\n };\n }\n\n async stream(options: ModelCallOptions): Promise<ReadableStream<ModelStreamPart>> {\n const body = this.buildBody(options, true);\n const res = await this.fetch('/messages', body, options);\n if (!res.body) {\n throw new APICallError({\n message: 'Anthropic streaming response has no body.',\n statusCode: res.status,\n });\n }\n\n const events = parseSSEWithEvent(res.body);\n\n return new ReadableStream<ModelStreamPart>({\n async start(controller) {\n const toolBlocks = new Map<number, { id: string; name: string; argsBuffer: string }>();\n let finish: FinishReason = 'unknown';\n let usage: TokenUsage = {};\n\n try {\n for await (const evt of events) {\n const data = parseEvent(evt);\n if (!data) continue;\n\n switch (data.type) {\n case 'message_start': {\n const msg = data.message as { usage?: AnthropicUsage } | undefined;\n if (msg?.usage) usage = mergeUsage(usage, mapUsage(msg.usage));\n break;\n }\n case 'content_block_start': {\n const block = data.content_block as\n | { type: string; id?: string; name?: string }\n | undefined;\n if (block?.type === 'tool_use' && typeof data.index === 'number') {\n toolBlocks.set(data.index, {\n id: block.id ?? `tu_${data.index}`,\n name: block.name ?? '',\n argsBuffer: '',\n });\n }\n break;\n }\n case 'content_block_delta': {\n const delta = data.delta as\n | { type: string; text?: string; partial_json?: string }\n | undefined;\n if (delta?.type === 'text_delta' && delta.text) {\n controller.enqueue({ type: 'text-delta', textDelta: delta.text });\n } else if (\n delta?.type === 'input_json_delta' &&\n typeof data.index === 'number' &&\n delta.partial_json\n ) {\n const tb = toolBlocks.get(data.index);\n if (tb) {\n tb.argsBuffer += delta.partial_json;\n controller.enqueue({\n type: 'tool-call-delta',\n toolCallId: tb.id,\n toolName: tb.name,\n argsDelta: delta.partial_json,\n });\n }\n }\n break;\n }\n case 'message_delta': {\n const delta = data.delta as { stop_reason?: string } | undefined;\n if (delta?.stop_reason) finish = mapFinishReason(delta.stop_reason);\n if (data.usage) usage = mergeUsage(usage, mapUsage(data.usage as AnthropicUsage));\n break;\n }\n case 'message_stop': {\n break;\n }\n }\n }\n\n for (const tb of toolBlocks.values()) {\n controller.enqueue({\n type: 'tool-call',\n toolCallId: tb.id,\n toolName: tb.name,\n args: safeParseJSON(tb.argsBuffer),\n });\n }\n\n controller.enqueue({ type: 'finish', finishReason: finish, usage });\n controller.close();\n } catch (err) {\n controller.enqueue({ type: 'error', error: err });\n controller.close();\n }\n },\n });\n }\n\n private buildBody(options: ModelCallOptions, stream: boolean): Record<string, unknown> {\n const { system, messages } = splitSystem(options.messages);\n\n const body: Record<string, unknown> = {\n model: this.modelId,\n messages: messages.map(toAnthropicMessage),\n max_tokens: options.maxTokens ?? 4096,\n };\n if (system) body['system'] = system;\n if (stream) body['stream'] = true;\n if (options.tools?.length) {\n body['tools'] = options.tools.map((t) => ({\n name: t.name,\n ...(t.description !== undefined ? { description: t.description } : {}),\n input_schema: t.parameters,\n }));\n }\n if (options.toolChoice !== undefined) {\n if (options.toolChoice === 'required') body['tool_choice'] = { type: 'any' };\n else if (options.toolChoice === 'auto') body['tool_choice'] = { type: 'auto' };\n else if (options.toolChoice === 'none') {\n // Anthropic has no explicit \"none\" — skip.\n } else if (typeof options.toolChoice === 'object') {\n body['tool_choice'] = { type: 'tool', name: options.toolChoice.toolName };\n }\n }\n if (options.temperature !== undefined) body['temperature'] = options.temperature;\n if (options.topP !== undefined) body['top_p'] = options.topP;\n if (options.topK !== undefined) body['top_k'] = options.topK;\n if (options.stopSequences !== undefined) body['stop_sequences'] = options.stopSequences;\n if (options.providerOptions) Object.assign(body, options.providerOptions);\n return body;\n }\n\n private async fetch(\n path: string,\n body: unknown,\n options: ModelCallOptions,\n ): Promise<Response> {\n const url = `${this.config.baseURL}${path}`;\n const headers = { ...this.config.headers, ...options.headers };\n const init: RequestInit = {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n };\n if (options.abortSignal) init.signal = options.abortSignal;\n\n const res = await this.config.fetcher(url, init);\n if (!res.ok) {\n const text = await res.text().catch(() => '');\n throw new APICallError({\n message: `Anthropic API error: ${res.status} ${res.statusText}`,\n url,\n statusCode: res.status,\n responseBody: text,\n });\n }\n return res;\n }\n}\n\nfunction splitSystem(messages: NormalizedMessage[]): {\n system?: string;\n messages: NormalizedMessage[];\n} {\n const sys = messages.filter((m) => m.role === 'system');\n const rest = messages.filter((m) => m.role !== 'system');\n if (sys.length === 0) return { messages: rest };\n const text = sys\n .flatMap((m) => m.content)\n .filter((p) => p.type === 'text')\n .map((p) => (p as { text: string }).text)\n .join('\\n');\n return { system: text, messages: rest };\n}\n\nfunction toAnthropicMessage(m: NormalizedMessage): unknown {\n switch (m.role) {\n case 'user': {\n const blocks = m.content.map((p) => {\n if (p.type === 'text') return { type: 'text', text: p.text };\n if (p.type === 'image') {\n if (typeof p.image === 'string' && p.image.startsWith('http')) {\n return { type: 'image', source: { type: 'url', url: p.image } };\n }\n if (typeof p.image === 'string') {\n return { type: 'image', source: { type: 'url', url: p.image } };\n }\n return {\n type: 'image',\n source: {\n type: 'base64',\n media_type: p.mimeType ?? 'image/png',\n data: uint8ToBase64(p.image as Uint8Array),\n },\n };\n }\n return p;\n });\n return { role: 'user', content: blocks };\n }\n case 'assistant': {\n const blocks = m.content.map((p) => {\n if (p.type === 'text') return { type: 'text', text: p.text };\n if (p.type === 'tool-call') {\n return { type: 'tool_use', id: p.toolCallId, name: p.toolName, input: p.args };\n }\n return p;\n });\n return { role: 'assistant', content: blocks };\n }\n case 'tool': {\n return {\n role: 'user',\n content: m.content\n .filter((r): r is Extract<typeof r, { type: 'tool-result' }> => r.type === 'tool-result')\n .map((r) => ({\n type: 'tool_result',\n tool_use_id: r.toolCallId,\n content: typeof r.result === 'string' ? r.result : JSON.stringify(r.result),\n ...(r.isError ? { is_error: true } : {}),\n })),\n };\n }\n case 'system':\n return { role: 'user', content: '' };\n }\n}\n\nfunction parseEvent(evt: SSEEvent): { type: string; [k: string]: unknown } | null {\n if (!evt.data) return null;\n try {\n return JSON.parse(evt.data) as { type: string };\n } catch {\n return null;\n }\n}\n\nfunction safeParseJSON(text: string): unknown {\n if (!text) return {};\n try {\n return JSON.parse(text);\n } catch {\n return text;\n }\n}\n\nfunction mapFinishReason(reason: string | null | undefined): FinishReason {\n switch (reason) {\n case 'end_turn':\n return 'stop';\n case 'max_tokens':\n return 'length';\n case 'tool_use':\n return 'tool-calls';\n case 'stop_sequence':\n return 'stop';\n case null:\n case undefined:\n return 'unknown';\n default:\n return 'other';\n }\n}\n\ninterface AnthropicUsage {\n input_tokens?: number;\n output_tokens?: number;\n cache_read_input_tokens?: number;\n cache_creation_input_tokens?: number;\n}\n\nfunction mapUsage(u: AnthropicUsage | undefined): TokenUsage {\n if (!u) return {};\n const promptTokens =\n (u.input_tokens ?? 0) +\n (u.cache_read_input_tokens ?? 0) +\n (u.cache_creation_input_tokens ?? 0);\n const out: TokenUsage = {\n promptTokens: u.input_tokens !== undefined ? promptTokens : undefined,\n completionTokens: u.output_tokens,\n };\n if (out.promptTokens !== undefined && out.completionTokens !== undefined) {\n out.totalTokens = out.promptTokens + out.completionTokens;\n }\n if (u.cache_read_input_tokens !== undefined) out.cachedPromptTokens = u.cache_read_input_tokens;\n return out;\n}\n\nfunction mergeUsage(a: TokenUsage, b: TokenUsage): TokenUsage {\n const sum = (x?: number, y?: number) =>\n x === undefined && y === undefined ? undefined : (x ?? 0) + (y ?? 0);\n return {\n promptTokens: sum(a.promptTokens, b.promptTokens),\n completionTokens: sum(a.completionTokens, b.completionTokens),\n totalTokens: sum(a.totalTokens, b.totalTokens),\n cachedPromptTokens: sum(a.cachedPromptTokens, b.cachedPromptTokens),\n };\n}\n\nfunction uint8ToBase64(arr: Uint8Array): string {\n let s = '';\n for (let i = 0; i < arr.byteLength; i++) s += String.fromCharCode(arr[i] as number);\n return typeof btoa !== 'undefined'\n ? btoa(s)\n : Buffer.from(s, 'binary').toString('base64');\n}\n\ninterface AnthropicMessageResponse {\n content?: Array<\n | { type: 'text'; text: string }\n | { type: 'tool_use'; id: string; name: string; input: unknown }\n >;\n stop_reason?: string;\n usage?: AnthropicUsage;\n}\n","import type { LanguageModel } from '@ziro-agent/core';\nimport {\n AnthropicMessagesModel,\n type AnthropicMessagesModelId,\n} from './anthropic-messages-model.js';\n\nexport interface AnthropicProviderOptions {\n /** Defaults to `process.env.ANTHROPIC_API_KEY`. */\n apiKey?: string;\n baseURL?: string;\n /** API version sent in `anthropic-version`. Defaults to `2023-06-01`. */\n version?: string;\n headers?: Record<string, string>;\n fetch?: typeof fetch;\n}\n\nexport interface AnthropicProvider {\n (modelId: AnthropicMessagesModelId): LanguageModel;\n messages(modelId: AnthropicMessagesModelId): LanguageModel;\n}\n\nexport function createAnthropic(options: AnthropicProviderOptions = {}): AnthropicProvider {\n const apiKey = options.apiKey ?? loadEnv('ANTHROPIC_API_KEY');\n const baseURL = options.baseURL ?? 'https://api.anthropic.com/v1';\n const version = options.version ?? '2023-06-01';\n const fetcher = options.fetch ?? globalThis.fetch;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'anthropic-version': version,\n ...options.headers,\n };\n if (apiKey) headers['x-api-key'] = apiKey;\n\n const make = (modelId: AnthropicMessagesModelId): LanguageModel =>\n new AnthropicMessagesModel({\n modelId,\n baseURL,\n headers,\n fetcher,\n });\n\n const provider = ((modelId: AnthropicMessagesModelId) => make(modelId)) as AnthropicProvider;\n provider.messages = make;\n return provider;\n}\n\nexport const anthropic: AnthropicProvider = createAnthropic();\n\nfunction loadEnv(name: string): string | undefined {\n if (typeof process !== 'undefined' && process.env) {\n return process.env[name];\n }\n return undefined;\n}\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ziro-agent/anthropic",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Anthropic (Claude) provider for ZiroAgent SDK.",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"homepage": "https://github.com/ziroagent/sdk-typescript/tree/main/packages/providers-anthropic",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/ziroagent/sdk-typescript.git",
|
|
10
|
+
"directory": "packages/providers-anthropic"
|
|
11
|
+
},
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/ziroagent/sdk-typescript/issues"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"ai",
|
|
17
|
+
"llm",
|
|
18
|
+
"anthropic",
|
|
19
|
+
"claude",
|
|
20
|
+
"ziroagent"
|
|
21
|
+
],
|
|
22
|
+
"type": "module",
|
|
23
|
+
"sideEffects": false,
|
|
24
|
+
"main": "./dist/index.cjs",
|
|
25
|
+
"module": "./dist/index.js",
|
|
26
|
+
"types": "./dist/index.d.ts",
|
|
27
|
+
"exports": {
|
|
28
|
+
".": {
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
30
|
+
"import": "./dist/index.js",
|
|
31
|
+
"require": "./dist/index.cjs"
|
|
32
|
+
},
|
|
33
|
+
"./package.json": "./package.json"
|
|
34
|
+
},
|
|
35
|
+
"files": [
|
|
36
|
+
"dist",
|
|
37
|
+
"README.md",
|
|
38
|
+
"LICENSE"
|
|
39
|
+
],
|
|
40
|
+
"scripts": {
|
|
41
|
+
"build": "tsup",
|
|
42
|
+
"dev": "tsup --watch",
|
|
43
|
+
"test": "vitest run",
|
|
44
|
+
"test:watch": "vitest",
|
|
45
|
+
"typecheck": "tsc --noEmit",
|
|
46
|
+
"clean": "rm -rf dist .turbo *.tsbuildinfo",
|
|
47
|
+
"publint": "publint",
|
|
48
|
+
"attw": "attw --pack ."
|
|
49
|
+
},
|
|
50
|
+
"dependencies": {
|
|
51
|
+
"@ziro-agent/core": "workspace:*"
|
|
52
|
+
},
|
|
53
|
+
"devDependencies": {
|
|
54
|
+
"@arethetypeswrong/cli": "^0.18.2",
|
|
55
|
+
"msw": "^2.11.7",
|
|
56
|
+
"publint": "^0.3.18",
|
|
57
|
+
"tsup": "^8.5.1",
|
|
58
|
+
"typescript": "^5.9.3",
|
|
59
|
+
"vitest": "^4.1.4"
|
|
60
|
+
},
|
|
61
|
+
"engines": {
|
|
62
|
+
"node": ">=20.10.0"
|
|
63
|
+
},
|
|
64
|
+
"publishConfig": {
|
|
65
|
+
"access": "public"
|
|
66
|
+
}
|
|
67
|
+
}
|