@aigne/anthropic 0.14.17-beta → 1.74.0-beta
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/README.md +11 -11
- package/dist/_virtual/rolldown_runtime.cjs +29 -0
- package/dist/anthropic-chat-model.cjs +364 -0
- package/dist/anthropic-chat-model.d.cts +151 -0
- package/dist/anthropic-chat-model.d.cts.map +1 -0
- package/dist/anthropic-chat-model.d.mts +151 -0
- package/dist/anthropic-chat-model.d.mts.map +1 -0
- package/dist/anthropic-chat-model.mjs +362 -0
- package/dist/anthropic-chat-model.mjs.map +1 -0
- package/dist/index.cjs +4 -0
- package/dist/index.d.cts +2 -0
- package/dist/index.d.mts +2 -0
- package/dist/index.mjs +3 -0
- package/package.json +29 -30
- package/CHANGELOG.md +0 -2377
- package/lib/cjs/anthropic-chat-model.d.ts +0 -145
- package/lib/cjs/anthropic-chat-model.js +0 -412
- package/lib/cjs/index.d.ts +0 -1
- package/lib/cjs/index.js +0 -17
- package/lib/cjs/package.json +0 -3
- package/lib/dts/anthropic-chat-model.d.ts +0 -145
- package/lib/dts/index.d.ts +0 -1
- package/lib/esm/anthropic-chat-model.d.ts +0 -145
- package/lib/esm/anthropic-chat-model.js +0 -405
- package/lib/esm/index.d.ts +0 -1
- package/lib/esm/index.js +0 -1
- package/lib/esm/package.json +0 -3
package/README.md
CHANGED
|
@@ -2,28 +2,28 @@
|
|
|
2
2
|
|
|
3
3
|
<p align="center">
|
|
4
4
|
<picture>
|
|
5
|
-
<source srcset="https://raw.githubusercontent.com/
|
|
6
|
-
<source srcset="https://raw.githubusercontent.com/
|
|
7
|
-
<img src="https://raw.githubusercontent.com/
|
|
5
|
+
<source srcset="https://raw.githubusercontent.com/ArcBlock/aigne-framework/main/logo-dark.svg" media="(prefers-color-scheme: dark)">
|
|
6
|
+
<source srcset="https://raw.githubusercontent.com/ArcBlock/aigne-framework/main/logo.svg" media="(prefers-color-scheme: light)">
|
|
7
|
+
<img src="https://raw.githubusercontent.com/ArcBlock/aigne-framework/main/logo.svg" alt="AIGNE Logo" width="400" />
|
|
8
8
|
</picture>
|
|
9
9
|
</p>
|
|
10
10
|
|
|
11
|
-
[](https://star-history.com/#ArcBlock/aigne-framework)
|
|
12
|
+
[](https://github.com/ArcBlock/aigne-framework/issues)
|
|
13
|
+
[](https://codecov.io/gh/ArcBlock/aigne-framework)
|
|
14
14
|
[](https://www.npmjs.com/package/@aigne/anthropic)
|
|
15
|
-
[](https://github.com/
|
|
15
|
+
[](https://github.com/ArcBlock/aigne-framework/blob/main/LICENSE.md)
|
|
16
16
|
|
|
17
|
-
AIGNE Anthropic SDK for integrating with Claude AI models within the [AIGNE Framework](https://github.com/
|
|
17
|
+
AIGNE Anthropic SDK for integrating with Claude AI models within the [AIGNE Framework](https://github.com/ArcBlock/aigne-framework).
|
|
18
18
|
|
|
19
19
|
## Introduction
|
|
20
20
|
|
|
21
21
|
`@aigne/anthropic` provides a seamless integration between the AIGNE Framework and Anthropic's Claude language models and API. This package enables developers to easily leverage Anthropic's Claude models in their AIGNE applications, providing a consistent interface across the framework while taking advantage of Claude's advanced AI capabilities.
|
|
22
22
|
|
|
23
23
|
<picture>
|
|
24
|
-
<source srcset="https://raw.githubusercontent.com/
|
|
25
|
-
<source srcset="https://raw.githubusercontent.com/
|
|
26
|
-
<img src="https://raw.githubusercontent.com/
|
|
24
|
+
<source srcset="https://raw.githubusercontent.com/ArcBlock/aigne-framework/main/assets/aigne-anthropic-dark.png" media="(prefers-color-scheme: dark)">
|
|
25
|
+
<source srcset="https://raw.githubusercontent.com/ArcBlock/aigne-framework/main/assets/aigne-anthropic.png" media="(prefers-color-scheme: light)">
|
|
26
|
+
<img src="https://raw.githubusercontent.com/ArcBlock/aigne-framework/main/aigne-anthropic.png" alt="AIGNE Arch" />
|
|
27
27
|
</picture>
|
|
28
28
|
|
|
29
29
|
## Features
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
//#region rolldown:runtime
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __copyProps = (to, from, except, desc) => {
|
|
9
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
10
|
+
for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
11
|
+
key = keys[i];
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except) {
|
|
13
|
+
__defProp(to, key, {
|
|
14
|
+
get: ((k) => from[k]).bind(null, key),
|
|
15
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return to;
|
|
21
|
+
};
|
|
22
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
23
|
+
value: mod,
|
|
24
|
+
enumerable: true
|
|
25
|
+
}) : target, mod));
|
|
26
|
+
|
|
27
|
+
//#endregion
|
|
28
|
+
|
|
29
|
+
exports.__toESM = __toESM;
|
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
const require_rolldown_runtime = require('./_virtual/rolldown_runtime.cjs');
|
|
2
|
+
let _aigne_core = require("@aigne/core");
|
|
3
|
+
let _aigne_core_utils_json_schema = require("@aigne/core/utils/json-schema");
|
|
4
|
+
let _aigne_core_utils_type_utils = require("@aigne/core/utils/type-utils");
|
|
5
|
+
let _anthropic_ai_sdk = require("@anthropic-ai/sdk");
|
|
6
|
+
_anthropic_ai_sdk = require_rolldown_runtime.__toESM(_anthropic_ai_sdk);
|
|
7
|
+
let zod = require("zod");
|
|
8
|
+
|
|
9
|
+
//#region src/anthropic-chat-model.ts
|
|
10
|
+
const CHAT_MODEL_CLAUDE_DEFAULT_MODEL = "claude-3-7-sonnet-latest";
|
|
11
|
+
const OUTPUT_FUNCTION_NAME = "generate_json";
|
|
12
|
+
/**
|
|
13
|
+
* @hidden
|
|
14
|
+
*/
|
|
15
|
+
const claudeChatModelOptionsSchema = zod.z.object({
|
|
16
|
+
apiKey: zod.z.string().optional(),
|
|
17
|
+
model: zod.z.string().optional(),
|
|
18
|
+
modelOptions: zod.z.object({
|
|
19
|
+
model: zod.z.string().optional(),
|
|
20
|
+
temperature: zod.z.number().optional(),
|
|
21
|
+
topP: zod.z.number().optional(),
|
|
22
|
+
frequencyPenalty: zod.z.number().optional(),
|
|
23
|
+
presencePenalty: zod.z.number().optional(),
|
|
24
|
+
parallelToolCalls: zod.z.boolean().optional().default(true)
|
|
25
|
+
}).optional()
|
|
26
|
+
});
|
|
27
|
+
/**
|
|
28
|
+
* Implementation of the ChatModel interface for Anthropic's Claude API
|
|
29
|
+
*
|
|
30
|
+
* This model provides access to Claude's capabilities including:
|
|
31
|
+
* - Text generation
|
|
32
|
+
* - Tool use
|
|
33
|
+
* - JSON structured output
|
|
34
|
+
*
|
|
35
|
+
* Default model: 'claude-3-7-sonnet-latest'
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* Here's how to create and use a Claude chat model:
|
|
39
|
+
* {@includeCode ../test/anthropic-chat-model.test.ts#example-anthropic-chat-model}
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* Here's an example with streaming response:
|
|
43
|
+
* {@includeCode ../test/anthropic-chat-model.test.ts#example-anthropic-chat-model-streaming-async-generator}
|
|
44
|
+
*/
|
|
45
|
+
var AnthropicChatModel = class extends _aigne_core.ChatModel {
|
|
46
|
+
constructor(options) {
|
|
47
|
+
if (options) (0, _aigne_core_utils_type_utils.checkArguments)("AnthropicChatModel", claudeChatModelOptionsSchema, options);
|
|
48
|
+
super();
|
|
49
|
+
this.options = options;
|
|
50
|
+
}
|
|
51
|
+
apiKeyEnvName = "ANTHROPIC_API_KEY";
|
|
52
|
+
/**
|
|
53
|
+
* @hidden
|
|
54
|
+
*/
|
|
55
|
+
_client;
|
|
56
|
+
get client() {
|
|
57
|
+
const { apiKey } = this.credential;
|
|
58
|
+
if (!apiKey) throw new Error("AnthropicChatModel requires an API key. Please provide it via `options.apiKey`, or set the `ANTHROPIC_API_KEY` or `CLAUDE_API_KEY` environment variable");
|
|
59
|
+
this._client ??= new _anthropic_ai_sdk.default({
|
|
60
|
+
apiKey,
|
|
61
|
+
...this.options?.clientOptions,
|
|
62
|
+
timeout: this.options?.clientOptions?.timeout ?? 6e5
|
|
63
|
+
});
|
|
64
|
+
return this._client;
|
|
65
|
+
}
|
|
66
|
+
get modelOptions() {
|
|
67
|
+
return this.options?.modelOptions;
|
|
68
|
+
}
|
|
69
|
+
get credential() {
|
|
70
|
+
return {
|
|
71
|
+
apiKey: this.options?.apiKey || process.env[this.apiKeyEnvName] || process.env.CLAUDE_API_KEY,
|
|
72
|
+
model: this.options?.model || CHAT_MODEL_CLAUDE_DEFAULT_MODEL
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
async countTokens(input) {
|
|
76
|
+
const request = await this.getMessageCreateParams(input);
|
|
77
|
+
return (await this.client.messages.countTokens((0, _aigne_core_utils_type_utils.omit)(request, "max_tokens"))).input_tokens;
|
|
78
|
+
}
|
|
79
|
+
async getMessageCreateParams(input) {
|
|
80
|
+
const { modelOptions = {} } = input;
|
|
81
|
+
const model = modelOptions.model || this.credential.model;
|
|
82
|
+
const disableParallelToolUse = modelOptions.parallelToolCalls === false;
|
|
83
|
+
return {
|
|
84
|
+
model,
|
|
85
|
+
temperature: modelOptions.temperature,
|
|
86
|
+
top_p: modelOptions.topP,
|
|
87
|
+
max_tokens: this.getMaxTokens(model),
|
|
88
|
+
...await convertMessages(input),
|
|
89
|
+
...convertTools({
|
|
90
|
+
...input,
|
|
91
|
+
disableParallelToolUse
|
|
92
|
+
})
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
getMaxTokens(model) {
|
|
96
|
+
for (const [regex, maxTokens] of [
|
|
97
|
+
[/claude-opus-4-/, 32e3],
|
|
98
|
+
[/claude-sonnet-4-/, 64e3],
|
|
99
|
+
[/claude-3-7-sonnet-/, 64e3],
|
|
100
|
+
[/claude-3-5-sonnet-/, 8192],
|
|
101
|
+
[/claude-3-5-haiku-/, 8192]
|
|
102
|
+
]) if (regex.test(model)) return maxTokens;
|
|
103
|
+
return 4096;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Process the input using Claude's chat model
|
|
107
|
+
* @param input - The input to process
|
|
108
|
+
* @returns The processed output from the model
|
|
109
|
+
*/
|
|
110
|
+
process(input, _options) {
|
|
111
|
+
return this.processInput(input);
|
|
112
|
+
}
|
|
113
|
+
async *processInput(input) {
|
|
114
|
+
const body = await this.getMessageCreateParams(input);
|
|
115
|
+
const stream = this.client.messages.stream({
|
|
116
|
+
...body,
|
|
117
|
+
stream: true
|
|
118
|
+
});
|
|
119
|
+
const blocks = [];
|
|
120
|
+
let usage;
|
|
121
|
+
let json;
|
|
122
|
+
for await (const chunk of stream) {
|
|
123
|
+
if (chunk.type === "message_start") {
|
|
124
|
+
yield { delta: { json: { model: chunk.message.model } } };
|
|
125
|
+
const { input_tokens, output_tokens, cache_creation_input_tokens, cache_read_input_tokens } = chunk.message.usage;
|
|
126
|
+
usage = {
|
|
127
|
+
inputTokens: input_tokens,
|
|
128
|
+
outputTokens: output_tokens,
|
|
129
|
+
cacheCreationInputTokens: cache_creation_input_tokens ?? void 0,
|
|
130
|
+
cacheReadInputTokens: cache_read_input_tokens ?? void 0
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
if (chunk.type === "message_delta" && usage) usage.outputTokens = chunk.usage.output_tokens;
|
|
134
|
+
if (chunk.type === "content_block_delta" && chunk.delta.type === "text_delta") yield { delta: { text: { text: chunk.delta.text } } };
|
|
135
|
+
if (chunk.type === "content_block_start" && chunk.content_block.type === "tool_use") blocks[chunk.index] = {
|
|
136
|
+
type: "function",
|
|
137
|
+
id: chunk.content_block.id,
|
|
138
|
+
function: {
|
|
139
|
+
name: chunk.content_block.name,
|
|
140
|
+
arguments: {}
|
|
141
|
+
},
|
|
142
|
+
args: ""
|
|
143
|
+
};
|
|
144
|
+
if (chunk.type === "content_block_delta" && chunk.delta.type === "input_json_delta") {
|
|
145
|
+
const call = blocks[chunk.index];
|
|
146
|
+
if (!call) throw new Error("Tool call not found");
|
|
147
|
+
call.args += chunk.delta.partial_json;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
const toolCalls = blocks.filter(_aigne_core_utils_type_utils.isNonNullable);
|
|
151
|
+
const outputToolCall = toolCalls.find((c) => c.function.name === OUTPUT_FUNCTION_NAME);
|
|
152
|
+
const businessToolCalls = toolCalls.filter((c) => c.function.name !== OUTPUT_FUNCTION_NAME).map(({ args, ...c }) => ({
|
|
153
|
+
...c,
|
|
154
|
+
function: {
|
|
155
|
+
...c.function,
|
|
156
|
+
arguments: args.trim() ? (0, _aigne_core_utils_json_schema.parseJSON)(args) : {}
|
|
157
|
+
}
|
|
158
|
+
})).filter(_aigne_core_utils_type_utils.isNonNullable);
|
|
159
|
+
if (outputToolCall) json = outputToolCall.args.trim() ? (0, _aigne_core_utils_json_schema.parseJSON)(outputToolCall.args) : {};
|
|
160
|
+
if (businessToolCalls.length) yield { delta: { json: { toolCalls: businessToolCalls } } };
|
|
161
|
+
if (json !== void 0) yield { delta: { json: { json } } };
|
|
162
|
+
yield { delta: { json: { usage } } };
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
/**
|
|
166
|
+
* Parse cache configuration from model options
|
|
167
|
+
*/
|
|
168
|
+
function parseCacheConfig(modelOptions) {
|
|
169
|
+
const cacheConfig = modelOptions?.cacheConfig || {};
|
|
170
|
+
return {
|
|
171
|
+
shouldCache: cacheConfig.enabled !== false,
|
|
172
|
+
ttl: cacheConfig.ttl === "1h" ? "1h" : "5m",
|
|
173
|
+
strategy: cacheConfig.strategy || "auto",
|
|
174
|
+
autoBreakpoints: {
|
|
175
|
+
tools: cacheConfig.autoBreakpoints?.tools !== false,
|
|
176
|
+
system: cacheConfig.autoBreakpoints?.system !== false,
|
|
177
|
+
lastMessage: cacheConfig.autoBreakpoints?.lastMessage === true
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
async function convertMessages({ messages, modelOptions }) {
|
|
182
|
+
const systemBlocks = [];
|
|
183
|
+
const msgs = [];
|
|
184
|
+
const { shouldCache, strategy, autoBreakpoints, ...cacheConfig } = parseCacheConfig(modelOptions);
|
|
185
|
+
const ttl = cacheConfig.ttl === "1h" ? "1h" : void 0;
|
|
186
|
+
for (const msg of messages) if (msg.role === "system") if (typeof msg.content === "string") {
|
|
187
|
+
const block = {
|
|
188
|
+
type: "text",
|
|
189
|
+
text: msg.content
|
|
190
|
+
};
|
|
191
|
+
systemBlocks.push(block);
|
|
192
|
+
} else if (Array.isArray(msg.content)) systemBlocks.push(...msg.content.map((item) => {
|
|
193
|
+
if (item.type !== "text") throw new Error("System message only supports text content blocks");
|
|
194
|
+
return {
|
|
195
|
+
type: "text",
|
|
196
|
+
text: item.text
|
|
197
|
+
};
|
|
198
|
+
}));
|
|
199
|
+
else throw new Error("System message must have string or array content");
|
|
200
|
+
else if (msg.role === "tool") {
|
|
201
|
+
if (!msg.toolCallId) throw new Error("Tool message must have toolCallId");
|
|
202
|
+
if (!msg.content) throw new Error("Tool message must have content");
|
|
203
|
+
msgs.push({
|
|
204
|
+
role: "user",
|
|
205
|
+
content: [{
|
|
206
|
+
type: "tool_result",
|
|
207
|
+
tool_use_id: msg.toolCallId,
|
|
208
|
+
content: await convertContent(msg.content)
|
|
209
|
+
}]
|
|
210
|
+
});
|
|
211
|
+
} else if (msg.role === "user") {
|
|
212
|
+
if (!msg.content) throw new Error("User message must have content");
|
|
213
|
+
msgs.push({
|
|
214
|
+
role: "user",
|
|
215
|
+
content: await convertContent(msg.content)
|
|
216
|
+
});
|
|
217
|
+
} else if (msg.role === "agent") if (msg.toolCalls?.length) msgs.push({
|
|
218
|
+
role: "assistant",
|
|
219
|
+
content: msg.toolCalls.map((i) => ({
|
|
220
|
+
type: "tool_use",
|
|
221
|
+
id: i.id,
|
|
222
|
+
name: i.function.name,
|
|
223
|
+
input: i.function.arguments
|
|
224
|
+
}))
|
|
225
|
+
});
|
|
226
|
+
else if (msg.content) msgs.push({
|
|
227
|
+
role: "assistant",
|
|
228
|
+
content: await convertContent(msg.content)
|
|
229
|
+
});
|
|
230
|
+
else throw new Error("Agent message must have content or toolCalls");
|
|
231
|
+
if (shouldCache && strategy === "auto") {
|
|
232
|
+
if (autoBreakpoints.system && systemBlocks.length > 0) {
|
|
233
|
+
const lastBlock = systemBlocks[systemBlocks.length - 1];
|
|
234
|
+
if (lastBlock) lastBlock.cache_control = {
|
|
235
|
+
type: "ephemeral",
|
|
236
|
+
ttl
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
if (autoBreakpoints.lastMessage) {
|
|
240
|
+
const lastMsg = msgs[msgs.length - 1];
|
|
241
|
+
if (lastMsg) {
|
|
242
|
+
if (typeof lastMsg.content === "string") lastMsg.content = [{
|
|
243
|
+
type: "text",
|
|
244
|
+
text: lastMsg.content,
|
|
245
|
+
cache_control: {
|
|
246
|
+
type: "ephemeral",
|
|
247
|
+
ttl
|
|
248
|
+
}
|
|
249
|
+
}];
|
|
250
|
+
else if (Array.isArray(lastMsg.content)) {
|
|
251
|
+
const lastBlock = lastMsg.content[lastMsg.content.length - 1];
|
|
252
|
+
if (lastBlock && lastBlock.type !== "thinking" && lastBlock.type !== "redacted_thinking") lastBlock.cache_control = {
|
|
253
|
+
type: "ephemeral",
|
|
254
|
+
ttl
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
if (shouldCache && strategy === "manual") for (const [index, msg] of messages.entries()) {
|
|
261
|
+
const msgWithCache = msg;
|
|
262
|
+
if (msg.role === "system" && msgWithCache.cacheControl) {
|
|
263
|
+
const block = systemBlocks[index];
|
|
264
|
+
if (block) block.cache_control = {
|
|
265
|
+
type: msgWithCache.cacheControl.type,
|
|
266
|
+
...msgWithCache.cacheControl.ttl && { ttl: msgWithCache.cacheControl.ttl }
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
if (msgs.length === 0) {
|
|
271
|
+
if (systemBlocks.length === 0) throw new Error("No messages provided");
|
|
272
|
+
return { messages: [{
|
|
273
|
+
role: "user",
|
|
274
|
+
content: systemBlocks.map((b) => b.text).join("\n")
|
|
275
|
+
}] };
|
|
276
|
+
}
|
|
277
|
+
return {
|
|
278
|
+
messages: msgs,
|
|
279
|
+
system: systemBlocks.length > 0 ? systemBlocks : void 0
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
async function convertContent(content) {
|
|
283
|
+
if (typeof content === "string") return content;
|
|
284
|
+
if (Array.isArray(content)) return Promise.all(content.map(async (item) => {
|
|
285
|
+
if (item.type === "text") return {
|
|
286
|
+
type: "text",
|
|
287
|
+
text: item.text
|
|
288
|
+
};
|
|
289
|
+
const media_type = await _aigne_core.ChatModel.getMimeType(item.mimeType || item.filename || "");
|
|
290
|
+
switch (item.type) {
|
|
291
|
+
case "url": return {
|
|
292
|
+
type: "image",
|
|
293
|
+
source: {
|
|
294
|
+
type: "url",
|
|
295
|
+
url: item.url
|
|
296
|
+
}
|
|
297
|
+
};
|
|
298
|
+
case "file": return {
|
|
299
|
+
type: "image",
|
|
300
|
+
source: {
|
|
301
|
+
type: "base64",
|
|
302
|
+
data: item.data,
|
|
303
|
+
media_type
|
|
304
|
+
}
|
|
305
|
+
};
|
|
306
|
+
case "local": throw new Error(`Unsupported local file: ${item.path}, it should be converted to base64 at ChatModel`);
|
|
307
|
+
}
|
|
308
|
+
}));
|
|
309
|
+
throw new Error("Invalid chat message content");
|
|
310
|
+
}
|
|
311
|
+
function convertTools({ tools, toolChoice, disableParallelToolUse, modelOptions, responseFormat }) {
|
|
312
|
+
const { shouldCache, ttl, strategy, autoBreakpoints } = parseCacheConfig(modelOptions);
|
|
313
|
+
const shouldCacheTools = shouldCache && strategy === "auto" && autoBreakpoints.tools;
|
|
314
|
+
const convertedTools = (tools ?? []).map((i) => {
|
|
315
|
+
const tool = {
|
|
316
|
+
name: i.function.name,
|
|
317
|
+
description: i.function.description,
|
|
318
|
+
input_schema: (0, _aigne_core_utils_type_utils.isEmpty)(i.function.parameters) ? { type: "object" } : i.function.parameters
|
|
319
|
+
};
|
|
320
|
+
if (shouldCache && strategy === "manual" && i.cacheControl) tool.cache_control = {
|
|
321
|
+
type: i.cacheControl.type,
|
|
322
|
+
...i.cacheControl.ttl && { ttl: i.cacheControl.ttl }
|
|
323
|
+
};
|
|
324
|
+
return tool;
|
|
325
|
+
});
|
|
326
|
+
if (responseFormat?.type === "json_schema") convertedTools.push({
|
|
327
|
+
name: OUTPUT_FUNCTION_NAME,
|
|
328
|
+
description: "Generate a json result by given context",
|
|
329
|
+
input_schema: responseFormat.jsonSchema.schema
|
|
330
|
+
});
|
|
331
|
+
if (shouldCacheTools && convertedTools.length) {
|
|
332
|
+
const lastTool = convertedTools[convertedTools.length - 1];
|
|
333
|
+
if (lastTool) lastTool.cache_control = {
|
|
334
|
+
type: "ephemeral",
|
|
335
|
+
...ttl === "1h" && { ttl: "1h" }
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
const choice = responseFormat?.type === "json_schema" ? tools?.length ? {
|
|
339
|
+
type: "any",
|
|
340
|
+
disable_parallel_tool_use: disableParallelToolUse
|
|
341
|
+
} : {
|
|
342
|
+
type: "tool",
|
|
343
|
+
name: OUTPUT_FUNCTION_NAME,
|
|
344
|
+
disable_parallel_tool_use: true
|
|
345
|
+
} : typeof toolChoice === "object" && "type" in toolChoice && toolChoice.type === "function" ? {
|
|
346
|
+
type: "tool",
|
|
347
|
+
name: toolChoice.function.name,
|
|
348
|
+
disable_parallel_tool_use: disableParallelToolUse
|
|
349
|
+
} : toolChoice === "required" ? {
|
|
350
|
+
type: "any",
|
|
351
|
+
disable_parallel_tool_use: disableParallelToolUse
|
|
352
|
+
} : toolChoice === "auto" ? {
|
|
353
|
+
type: "auto",
|
|
354
|
+
disable_parallel_tool_use: disableParallelToolUse
|
|
355
|
+
} : toolChoice === "none" ? { type: "none" } : void 0;
|
|
356
|
+
return {
|
|
357
|
+
tools: convertedTools.length ? convertedTools : void 0,
|
|
358
|
+
tool_choice: choice
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
//#endregion
|
|
363
|
+
exports.AnthropicChatModel = AnthropicChatModel;
|
|
364
|
+
exports.claudeChatModelOptionsSchema = claudeChatModelOptionsSchema;
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import * as _aigne_core0 from "@aigne/core";
|
|
2
|
+
import { AgentInvokeOptions, AgentProcessResult, ChatModel, ChatModelInput, ChatModelOptions, ChatModelOutput } from "@aigne/core";
|
|
3
|
+
import { PromiseOrValue } from "@aigne/core/utils/type-utils";
|
|
4
|
+
import Anthropic, { ClientOptions } from "@anthropic-ai/sdk";
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
|
|
7
|
+
//#region src/anthropic-chat-model.d.ts
|
|
8
|
+
/**
|
|
9
|
+
* Configuration options for Claude Chat Model
|
|
10
|
+
*/
|
|
11
|
+
interface AnthropicChatModelOptions extends ChatModelOptions {
|
|
12
|
+
/**
|
|
13
|
+
* API key for Anthropic's Claude API
|
|
14
|
+
*
|
|
15
|
+
* If not provided, will look for ANTHROPIC_API_KEY or CLAUDE_API_KEY in environment variables
|
|
16
|
+
*/
|
|
17
|
+
apiKey?: string;
|
|
18
|
+
/**
|
|
19
|
+
* Optional client options for the Anthropic SDK
|
|
20
|
+
*/
|
|
21
|
+
clientOptions?: Partial<ClientOptions>;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* @hidden
|
|
25
|
+
*/
|
|
26
|
+
declare const claudeChatModelOptionsSchema: z.ZodObject<{
|
|
27
|
+
apiKey: z.ZodOptional<z.ZodString>;
|
|
28
|
+
model: z.ZodOptional<z.ZodString>;
|
|
29
|
+
modelOptions: z.ZodOptional<z.ZodObject<{
|
|
30
|
+
model: z.ZodOptional<z.ZodString>;
|
|
31
|
+
temperature: z.ZodOptional<z.ZodNumber>;
|
|
32
|
+
topP: z.ZodOptional<z.ZodNumber>;
|
|
33
|
+
frequencyPenalty: z.ZodOptional<z.ZodNumber>;
|
|
34
|
+
presencePenalty: z.ZodOptional<z.ZodNumber>;
|
|
35
|
+
parallelToolCalls: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
36
|
+
}, "strip", z.ZodTypeAny, {
|
|
37
|
+
parallelToolCalls: boolean;
|
|
38
|
+
model?: string | undefined;
|
|
39
|
+
temperature?: number | undefined;
|
|
40
|
+
topP?: number | undefined;
|
|
41
|
+
frequencyPenalty?: number | undefined;
|
|
42
|
+
presencePenalty?: number | undefined;
|
|
43
|
+
}, {
|
|
44
|
+
model?: string | undefined;
|
|
45
|
+
temperature?: number | undefined;
|
|
46
|
+
topP?: number | undefined;
|
|
47
|
+
frequencyPenalty?: number | undefined;
|
|
48
|
+
presencePenalty?: number | undefined;
|
|
49
|
+
parallelToolCalls?: boolean | undefined;
|
|
50
|
+
}>>;
|
|
51
|
+
}, "strip", z.ZodTypeAny, {
|
|
52
|
+
apiKey?: string | undefined;
|
|
53
|
+
model?: string | undefined;
|
|
54
|
+
modelOptions?: {
|
|
55
|
+
parallelToolCalls: boolean;
|
|
56
|
+
model?: string | undefined;
|
|
57
|
+
temperature?: number | undefined;
|
|
58
|
+
topP?: number | undefined;
|
|
59
|
+
frequencyPenalty?: number | undefined;
|
|
60
|
+
presencePenalty?: number | undefined;
|
|
61
|
+
} | undefined;
|
|
62
|
+
}, {
|
|
63
|
+
apiKey?: string | undefined;
|
|
64
|
+
model?: string | undefined;
|
|
65
|
+
modelOptions?: {
|
|
66
|
+
model?: string | undefined;
|
|
67
|
+
temperature?: number | undefined;
|
|
68
|
+
topP?: number | undefined;
|
|
69
|
+
frequencyPenalty?: number | undefined;
|
|
70
|
+
presencePenalty?: number | undefined;
|
|
71
|
+
parallelToolCalls?: boolean | undefined;
|
|
72
|
+
} | undefined;
|
|
73
|
+
}>;
|
|
74
|
+
/**
|
|
75
|
+
* Implementation of the ChatModel interface for Anthropic's Claude API
|
|
76
|
+
*
|
|
77
|
+
* This model provides access to Claude's capabilities including:
|
|
78
|
+
* - Text generation
|
|
79
|
+
* - Tool use
|
|
80
|
+
* - JSON structured output
|
|
81
|
+
*
|
|
82
|
+
* Default model: 'claude-3-7-sonnet-latest'
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* Here's how to create and use a Claude chat model:
|
|
86
|
+
* {@includeCode ../test/anthropic-chat-model.test.ts#example-anthropic-chat-model}
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* Here's an example with streaming response:
|
|
90
|
+
* {@includeCode ../test/anthropic-chat-model.test.ts#example-anthropic-chat-model-streaming-async-generator}
|
|
91
|
+
*/
|
|
92
|
+
declare class AnthropicChatModel extends ChatModel {
|
|
93
|
+
options?: AnthropicChatModelOptions | undefined;
|
|
94
|
+
constructor(options?: AnthropicChatModelOptions | undefined);
|
|
95
|
+
protected apiKeyEnvName: string;
|
|
96
|
+
/**
|
|
97
|
+
* @hidden
|
|
98
|
+
*/
|
|
99
|
+
protected _client?: Anthropic;
|
|
100
|
+
get client(): Anthropic;
|
|
101
|
+
get modelOptions(): Partial<{
|
|
102
|
+
[x: string]: unknown;
|
|
103
|
+
model?: string | {
|
|
104
|
+
$get: string;
|
|
105
|
+
} | undefined;
|
|
106
|
+
temperature?: number | {
|
|
107
|
+
$get: string;
|
|
108
|
+
} | undefined;
|
|
109
|
+
topP?: number | {
|
|
110
|
+
$get: string;
|
|
111
|
+
} | undefined;
|
|
112
|
+
frequencyPenalty?: number | {
|
|
113
|
+
$get: string;
|
|
114
|
+
} | undefined;
|
|
115
|
+
presencePenalty?: number | {
|
|
116
|
+
$get: string;
|
|
117
|
+
} | undefined;
|
|
118
|
+
parallelToolCalls?: boolean | {
|
|
119
|
+
$get: string;
|
|
120
|
+
} | undefined;
|
|
121
|
+
modalities?: {
|
|
122
|
+
$get: string;
|
|
123
|
+
} | _aigne_core0.Modality[] | undefined;
|
|
124
|
+
preferInputFileType?: {
|
|
125
|
+
$get: string;
|
|
126
|
+
} | "file" | "url" | undefined;
|
|
127
|
+
reasoningEffort?: number | {
|
|
128
|
+
$get: string;
|
|
129
|
+
} | "minimal" | "low" | "medium" | "high" | undefined;
|
|
130
|
+
cacheConfig?: {
|
|
131
|
+
$get: string;
|
|
132
|
+
} | _aigne_core0.CacheConfig | undefined;
|
|
133
|
+
}> | undefined;
|
|
134
|
+
get credential(): {
|
|
135
|
+
apiKey: string | undefined;
|
|
136
|
+
model: string;
|
|
137
|
+
};
|
|
138
|
+
countTokens(input: ChatModelInput): Promise<number>;
|
|
139
|
+
private getMessageCreateParams;
|
|
140
|
+
private getMaxTokens;
|
|
141
|
+
/**
|
|
142
|
+
* Process the input using Claude's chat model
|
|
143
|
+
* @param input - The input to process
|
|
144
|
+
* @returns The processed output from the model
|
|
145
|
+
*/
|
|
146
|
+
process(input: ChatModelInput, _options: AgentInvokeOptions): PromiseOrValue<AgentProcessResult<ChatModelOutput>>;
|
|
147
|
+
private processInput;
|
|
148
|
+
}
|
|
149
|
+
//#endregion
|
|
150
|
+
export { AnthropicChatModel, AnthropicChatModelOptions, claudeChatModelOptionsSchema };
|
|
151
|
+
//# sourceMappingURL=anthropic-chat-model.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anthropic-chat-model.d.cts","names":[],"sources":["../src/anthropic-chat-model.ts"],"mappings":";;;;;;;;AAwCA;;UAAiB,yBAAA,SAAkC,gBAAA;EAAA;;AAiBnD;;;EAjBmD,MAAA;EAAA;;AAiBnD;EAjBmD,aAAA,GAWjC,OAAA,CAAQ,aAAA;AAAA;AAAA;;;AAAA,cAMb,4BAAA,EAA4B,CAAA,CAAA,SAAA;EAAA,MAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiCzC;;;;;;;;;;;;;;;cAAa,kBAAA,SAA2B,SAAA;EAAA,OAAA,GACA,yBAAA;EAAA,YAAA,OAAA,GAAA,yBAAA;EAAA,UAAA,aAAA;EAAA;;;EAAA,UAAA,OAAA,GAUlB,SAAA;EAAA,IAAA,OAAA,GAEV,SAAA;EAAA,IAAA,aAAA,GAeM,OAAA;IAAA,CAAA,CAAA;IAAA,KAAA;MAAA,IAAA;IAAA;IAAA,WAAA;MAAA,IAAA;IAAA;IAAA,IAAA;MAAA,IAAA;IAAA;IAAA,gBAAA;MAAA,IAAA;IAAA;IAAA,eAAA;MAAA,IAAA;IAAA;IAAA,iBAAA;MAAA,IAAA;IAAA;IAAA,UAAA;MAAA,IAAA;IAAA,IAfN,YAAA,CAAA,QAAA;IAAA,mBAAA;MAAA,IAAA;IAAA;IAAA,eAAA;MAAA,IAAA;IAAA;IAAA,WAAA;MAAA,IAAA;IAAA;;;;;;qBA6BwB,cAAA,GAAiB,OAAA;EAAA,QAAA,sBAAA;EAAA,QAAA,YAAA;EAAA;;;;;EAAA,QAAA,KAAA,EA8C1C,cAAA,EAAA,QAAA,EACG,kBAAA,GACT,cAAA,CAAe,kBAAA,CAAmB,eAAA;EAAA,QAAA,YAAA;AAAA"}
|