@aigne/anthropic 1.74.0-beta → 1.74.0-beta.10

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 CHANGED
@@ -42,19 +42,19 @@ AIGNE Anthropic SDK for integrating with Claude AI models within the [AIGNE Fram
42
42
  ### Using npm
43
43
 
44
44
  ```bash
45
- npm install @aigne/anthropic @aigne/core
45
+ npm install @aigne/anthropic @aigne/model-base
46
46
  ```
47
47
 
48
48
  ### Using yarn
49
49
 
50
50
  ```bash
51
- yarn add @aigne/anthropic @aigne/core
51
+ yarn add @aigne/anthropic @aigne/model-base
52
52
  ```
53
53
 
54
54
  ### Using pnpm
55
55
 
56
56
  ```bash
57
- pnpm add @aigne/anthropic @aigne/core
57
+ pnpm add @aigne/anthropic @aigne/model-base
58
58
  ```
59
59
 
60
60
  ## Basic Usage
@@ -94,7 +94,7 @@ console.log(result);
94
94
 
95
95
  ```typescript file="test/anthropic-chat-model.test.ts" region="example-anthropic-chat-model-streaming-async-generator"
96
96
  import { AnthropicChatModel } from "@aigne/anthropic";
97
- import { isAgentResponseDelta } from "@aigne/core";
97
+ import { isAgentResponseDelta } from "@aigne/model-base";
98
98
 
99
99
  const model = new AnthropicChatModel({
100
100
  apiKey: "your-api-key",
@@ -1,7 +1,7 @@
1
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");
2
+ let _aigne_model_base = require("@aigne/model-base");
3
+ let _aigne_model_base_utils_json_schema = require("@aigne/model-base/utils/json-schema");
4
+ let _aigne_model_base_utils_type_utils = require("@aigne/model-base/utils/type-utils");
5
5
  let _anthropic_ai_sdk = require("@anthropic-ai/sdk");
6
6
  _anthropic_ai_sdk = require_rolldown_runtime.__toESM(_anthropic_ai_sdk);
7
7
  let zod = require("zod");
@@ -42,9 +42,9 @@ const claudeChatModelOptionsSchema = zod.z.object({
42
42
  * Here's an example with streaming response:
43
43
  * {@includeCode ../test/anthropic-chat-model.test.ts#example-anthropic-chat-model-streaming-async-generator}
44
44
  */
45
- var AnthropicChatModel = class extends _aigne_core.ChatModel {
45
+ var AnthropicChatModel = class extends _aigne_model_base.ChatModel {
46
46
  constructor(options) {
47
- if (options) (0, _aigne_core_utils_type_utils.checkArguments)("AnthropicChatModel", claudeChatModelOptionsSchema, options);
47
+ if (options) (0, _aigne_model_base_utils_type_utils.checkArguments)("AnthropicChatModel", claudeChatModelOptionsSchema, options);
48
48
  super();
49
49
  this.options = options;
50
50
  }
@@ -74,7 +74,7 @@ var AnthropicChatModel = class extends _aigne_core.ChatModel {
74
74
  }
75
75
  async countTokens(input) {
76
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;
77
+ return (await this.client.messages.countTokens((0, _aigne_model_base_utils_type_utils.omit)(request, "max_tokens"))).input_tokens;
78
78
  }
79
79
  async getMessageCreateParams(input) {
80
80
  const { modelOptions = {} } = input;
@@ -94,8 +94,11 @@ var AnthropicChatModel = class extends _aigne_core.ChatModel {
94
94
  }
95
95
  getMaxTokens(model) {
96
96
  for (const [regex, maxTokens] of [
97
+ [/claude-opus-4-6/, 128e3],
98
+ [/claude-opus-4-5/, 64e3],
97
99
  [/claude-opus-4-/, 32e3],
98
100
  [/claude-sonnet-4-/, 64e3],
101
+ [/claude-haiku-4-/, 64e3],
99
102
  [/claude-3-7-sonnet-/, 64e3],
100
103
  [/claude-3-5-sonnet-/, 8192],
101
104
  [/claude-3-5-haiku-/, 8192]
@@ -147,16 +150,16 @@ var AnthropicChatModel = class extends _aigne_core.ChatModel {
147
150
  call.args += chunk.delta.partial_json;
148
151
  }
149
152
  }
150
- const toolCalls = blocks.filter(_aigne_core_utils_type_utils.isNonNullable);
153
+ const toolCalls = blocks.filter(_aigne_model_base_utils_type_utils.isNonNullable);
151
154
  const outputToolCall = toolCalls.find((c) => c.function.name === OUTPUT_FUNCTION_NAME);
152
155
  const businessToolCalls = toolCalls.filter((c) => c.function.name !== OUTPUT_FUNCTION_NAME).map(({ args, ...c }) => ({
153
156
  ...c,
154
157
  function: {
155
158
  ...c.function,
156
- arguments: args.trim() ? (0, _aigne_core_utils_json_schema.parseJSON)(args) : {}
159
+ arguments: args.trim() ? (0, _aigne_model_base_utils_json_schema.parseJSON)(args) : {}
157
160
  }
158
- })).filter(_aigne_core_utils_type_utils.isNonNullable);
159
- if (outputToolCall) json = outputToolCall.args.trim() ? (0, _aigne_core_utils_json_schema.parseJSON)(outputToolCall.args) : {};
161
+ })).filter(_aigne_model_base_utils_type_utils.isNonNullable);
162
+ if (outputToolCall) json = outputToolCall.args.trim() ? (0, _aigne_model_base_utils_json_schema.parseJSON)(outputToolCall.args) : {};
160
163
  if (businessToolCalls.length) yield { delta: { json: { toolCalls: businessToolCalls } } };
161
164
  if (json !== void 0) yield { delta: { json: { json } } };
162
165
  yield { delta: { json: { usage } } };
@@ -286,7 +289,7 @@ async function convertContent(content) {
286
289
  type: "text",
287
290
  text: item.text
288
291
  };
289
- const media_type = await _aigne_core.ChatModel.getMimeType(item.mimeType || item.filename || "");
292
+ const media_type = item.mimeType || await _aigne_model_base.ChatModel.getMimeType(item.filename || "");
290
293
  switch (item.type) {
291
294
  case "url": return {
292
295
  type: "image",
@@ -315,7 +318,7 @@ function convertTools({ tools, toolChoice, disableParallelToolUse, modelOptions,
315
318
  const tool = {
316
319
  name: i.function.name,
317
320
  description: i.function.description,
318
- input_schema: (0, _aigne_core_utils_type_utils.isEmpty)(i.function.parameters) ? { type: "object" } : i.function.parameters
321
+ input_schema: (0, _aigne_model_base_utils_type_utils.isEmpty)(i.function.parameters) ? { type: "object" } : i.function.parameters
319
322
  };
320
323
  if (shouldCache && strategy === "manual" && i.cacheControl) tool.cache_control = {
321
324
  type: i.cacheControl.type,
@@ -1,6 +1,6 @@
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";
1
+ import * as _aigne_model_base0 from "@aigne/model-base";
2
+ import { ChatModel, ChatModelInput, ChatModelOptions, ChatModelOutput, ModelInvokeOptions, ModelProcessResult } from "@aigne/model-base";
3
+ import { PromiseOrValue } from "@aigne/model-base/utils/type-utils";
4
4
  import Anthropic, { ClientOptions } from "@anthropic-ai/sdk";
5
5
  import { z } from "zod";
6
6
 
@@ -10,14 +10,14 @@ import { z } from "zod";
10
10
  */
11
11
  interface AnthropicChatModelOptions extends ChatModelOptions {
12
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
- */
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
17
  apiKey?: string;
18
18
  /**
19
- * Optional client options for the Anthropic SDK
20
- */
19
+ * Optional client options for the Anthropic SDK
20
+ */
21
21
  clientOptions?: Partial<ClientOptions>;
22
22
  }
23
23
  /**
@@ -94,43 +94,11 @@ declare class AnthropicChatModel extends ChatModel {
94
94
  constructor(options?: AnthropicChatModelOptions | undefined);
95
95
  protected apiKeyEnvName: string;
96
96
  /**
97
- * @hidden
98
- */
97
+ * @hidden
98
+ */
99
99
  protected _client?: Anthropic;
100
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;
101
+ get modelOptions(): _aigne_model_base0.ChatModelInputOptions | undefined;
134
102
  get credential(): {
135
103
  apiKey: string | undefined;
136
104
  model: string;
@@ -139,11 +107,11 @@ declare class AnthropicChatModel extends ChatModel {
139
107
  private getMessageCreateParams;
140
108
  private getMaxTokens;
141
109
  /**
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>>;
110
+ * Process the input using Claude's chat model
111
+ * @param input - The input to process
112
+ * @returns The processed output from the model
113
+ */
114
+ process(input: ChatModelInput, _options: ModelInvokeOptions): PromiseOrValue<ModelProcessResult<ChatModelOutput>>;
147
115
  private processInput;
148
116
  }
149
117
  //#endregion
@@ -1 +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"}
1
+ {"version":3,"file":"anthropic-chat-model.d.cts","names":[],"sources":["../src/anthropic-chat-model.ts"],"mappings":";;;;;;;;;;UAwCiB,yBAAA,SAAkC,gBAAA;EAAR;;;;;EAMzC,MAAA;EANiE;;;EAWjE,aAAA,GAAgB,OAAA,CAAQ,aAAA;AAAA;;;;cAMb,4BAAA,EAA4B,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAiC5B,kBAAA,SAA2B,SAAA;EACV,OAAA,GAAU,yBAAA;cAAV,OAAA,GAAU,yBAAA;EAAA,UAK5B,aAAA;;;;YAKA,OAAA,GAAU,SAAA;EAAA,IAEhB,MAAA,CAAA,GAAM,SAAA;EAAA,IAeN,YAAA,CAAA,GAfM,kBAAA,CAeM,qBAAA;EAAA,IAIH,UAAA,CAAA;;;;EAUE,WAAA,CAAY,KAAA,EAAO,cAAA,GAAiB,OAAA;EAAA,QAKrC,sBAAA;EAAA,QAiBN,YAAA;;;;;;EA4BC,OAAA,CACP,KAAA,EAAO,cAAA,EACP,QAAA,EAAU,kBAAA,GACT,cAAA,CAAe,kBAAA,CAAmB,eAAA;EAAA,QAItB,YAAA;AAAA"}
@@ -1,6 +1,6 @@
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";
1
+ import * as _aigne_model_base0 from "@aigne/model-base";
2
+ import { ChatModel, ChatModelInput, ChatModelOptions, ChatModelOutput, ModelInvokeOptions, ModelProcessResult } from "@aigne/model-base";
3
+ import { PromiseOrValue } from "@aigne/model-base/utils/type-utils";
4
4
  import Anthropic, { ClientOptions } from "@anthropic-ai/sdk";
5
5
  import { z } from "zod";
6
6
 
@@ -10,14 +10,14 @@ import { z } from "zod";
10
10
  */
11
11
  interface AnthropicChatModelOptions extends ChatModelOptions {
12
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
- */
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
17
  apiKey?: string;
18
18
  /**
19
- * Optional client options for the Anthropic SDK
20
- */
19
+ * Optional client options for the Anthropic SDK
20
+ */
21
21
  clientOptions?: Partial<ClientOptions>;
22
22
  }
23
23
  /**
@@ -94,43 +94,11 @@ declare class AnthropicChatModel extends ChatModel {
94
94
  constructor(options?: AnthropicChatModelOptions | undefined);
95
95
  protected apiKeyEnvName: string;
96
96
  /**
97
- * @hidden
98
- */
97
+ * @hidden
98
+ */
99
99
  protected _client?: Anthropic;
100
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;
101
+ get modelOptions(): _aigne_model_base0.ChatModelInputOptions | undefined;
134
102
  get credential(): {
135
103
  apiKey: string | undefined;
136
104
  model: string;
@@ -139,11 +107,11 @@ declare class AnthropicChatModel extends ChatModel {
139
107
  private getMessageCreateParams;
140
108
  private getMaxTokens;
141
109
  /**
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>>;
110
+ * Process the input using Claude's chat model
111
+ * @param input - The input to process
112
+ * @returns The processed output from the model
113
+ */
114
+ process(input: ChatModelInput, _options: ModelInvokeOptions): PromiseOrValue<ModelProcessResult<ChatModelOutput>>;
147
115
  private processInput;
148
116
  }
149
117
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"anthropic-chat-model.d.mts","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"}
1
+ {"version":3,"file":"anthropic-chat-model.d.mts","names":[],"sources":["../src/anthropic-chat-model.ts"],"mappings":";;;;;;;;;;UAwCiB,yBAAA,SAAkC,gBAAA;EAAR;;;;;EAMzC,MAAA;EANiE;;;EAWjE,aAAA,GAAgB,OAAA,CAAQ,aAAA;AAAA;;;;cAMb,4BAAA,EAA4B,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAiC5B,kBAAA,SAA2B,SAAA;EACV,OAAA,GAAU,yBAAA;cAAV,OAAA,GAAU,yBAAA;EAAA,UAK5B,aAAA;;;;YAKA,OAAA,GAAU,SAAA;EAAA,IAEhB,MAAA,CAAA,GAAM,SAAA;EAAA,IAeN,YAAA,CAAA,GAfM,kBAAA,CAeM,qBAAA;EAAA,IAIH,UAAA,CAAA;;;;EAUE,WAAA,CAAY,KAAA,EAAO,cAAA,GAAiB,OAAA;EAAA,QAKrC,sBAAA;EAAA,QAiBN,YAAA;;;;;;EA4BC,OAAA,CACP,KAAA,EAAO,cAAA,EACP,QAAA,EAAU,kBAAA,GACT,cAAA,CAAe,kBAAA,CAAmB,eAAA;EAAA,QAItB,YAAA;AAAA"}
@@ -1,6 +1,6 @@
1
- import { ChatModel } from "@aigne/core";
2
- import { parseJSON } from "@aigne/core/utils/json-schema";
3
- import { checkArguments, isEmpty, isNonNullable, omit } from "@aigne/core/utils/type-utils";
1
+ import { ChatModel } from "@aigne/model-base";
2
+ import { parseJSON } from "@aigne/model-base/utils/json-schema";
3
+ import { checkArguments, isEmpty, isNonNullable, omit } from "@aigne/model-base/utils/type-utils";
4
4
  import Anthropic from "@anthropic-ai/sdk";
5
5
  import { z } from "zod";
6
6
 
@@ -92,8 +92,11 @@ var AnthropicChatModel = class extends ChatModel {
92
92
  }
93
93
  getMaxTokens(model) {
94
94
  for (const [regex, maxTokens] of [
95
+ [/claude-opus-4-6/, 128e3],
96
+ [/claude-opus-4-5/, 64e3],
95
97
  [/claude-opus-4-/, 32e3],
96
98
  [/claude-sonnet-4-/, 64e3],
99
+ [/claude-haiku-4-/, 64e3],
97
100
  [/claude-3-7-sonnet-/, 64e3],
98
101
  [/claude-3-5-sonnet-/, 8192],
99
102
  [/claude-3-5-haiku-/, 8192]
@@ -284,7 +287,7 @@ async function convertContent(content) {
284
287
  type: "text",
285
288
  text: item.text
286
289
  };
287
- const media_type = await ChatModel.getMimeType(item.mimeType || item.filename || "");
290
+ const media_type = item.mimeType || await ChatModel.getMimeType(item.filename || "");
288
291
  switch (item.type) {
289
292
  case "url": return {
290
293
  type: "image",
@@ -1 +1 @@
1
- {"version":3,"file":"anthropic-chat-model.mjs","names":[],"sources":["../src/anthropic-chat-model.ts"],"sourcesContent":["import {\n type AgentInvokeOptions,\n type AgentProcessAsyncGenerator,\n type AgentProcessResult,\n ChatModel,\n type ChatModelInput,\n type ChatModelInputMessageContent,\n type ChatModelOptions,\n type ChatModelOutput,\n type ChatModelOutputToolCall,\n type ChatModelOutputUsage,\n} from \"@aigne/core\";\nimport { parseJSON } from \"@aigne/core/utils/json-schema\";\nimport {\n checkArguments,\n isEmpty,\n isNonNullable,\n omit,\n type PromiseOrValue,\n} from \"@aigne/core/utils/type-utils\";\nimport Anthropic, { type ClientOptions } from \"@anthropic-ai/sdk\";\nimport type {\n Base64ImageSource,\n ImageBlockParam,\n TextBlockParam,\n} from \"@anthropic-ai/sdk/resources\";\nimport type {\n MessageParam,\n Tool,\n ToolChoice,\n ToolUnion,\n} from \"@anthropic-ai/sdk/resources/index.js\";\nimport { z } from \"zod\";\n\nconst CHAT_MODEL_CLAUDE_DEFAULT_MODEL = \"claude-3-7-sonnet-latest\";\nconst OUTPUT_FUNCTION_NAME = \"generate_json\";\n\n/**\n * Configuration options for Claude Chat Model\n */\nexport interface AnthropicChatModelOptions extends ChatModelOptions {\n /**\n * API key for Anthropic's Claude API\n *\n * If not provided, will look for ANTHROPIC_API_KEY or CLAUDE_API_KEY in environment variables\n */\n apiKey?: string;\n\n /**\n * Optional client options for the Anthropic SDK\n */\n clientOptions?: Partial<ClientOptions>;\n}\n\n/**\n * @hidden\n */\nexport const claudeChatModelOptionsSchema = z.object({\n apiKey: z.string().optional(),\n model: z.string().optional(),\n modelOptions: z\n .object({\n model: z.string().optional(),\n temperature: z.number().optional(),\n topP: z.number().optional(),\n frequencyPenalty: z.number().optional(),\n presencePenalty: z.number().optional(),\n parallelToolCalls: z.boolean().optional().default(true),\n })\n .optional(),\n});\n\n/**\n * Implementation of the ChatModel interface for Anthropic's Claude API\n *\n * This model provides access to Claude's capabilities including:\n * - Text generation\n * - Tool use\n * - JSON structured output\n *\n * Default model: 'claude-3-7-sonnet-latest'\n *\n * @example\n * Here's how to create and use a Claude chat model:\n * {@includeCode ../test/anthropic-chat-model.test.ts#example-anthropic-chat-model}\n *\n * @example\n * Here's an example with streaming response:\n * {@includeCode ../test/anthropic-chat-model.test.ts#example-anthropic-chat-model-streaming-async-generator}\n */\nexport class AnthropicChatModel extends ChatModel {\n constructor(public override options?: AnthropicChatModelOptions) {\n if (options) checkArguments(\"AnthropicChatModel\", claudeChatModelOptionsSchema, options);\n super();\n }\n\n protected apiKeyEnvName = \"ANTHROPIC_API_KEY\";\n\n /**\n * @hidden\n */\n protected _client?: Anthropic;\n\n get client() {\n const { apiKey } = this.credential;\n if (!apiKey)\n throw new Error(\n \"AnthropicChatModel requires an API key. Please provide it via `options.apiKey`, or set the `ANTHROPIC_API_KEY` or `CLAUDE_API_KEY` environment variable\",\n );\n\n this._client ??= new Anthropic({\n apiKey,\n ...this.options?.clientOptions,\n timeout: this.options?.clientOptions?.timeout ?? 600e3,\n });\n return this._client;\n }\n\n get modelOptions() {\n return this.options?.modelOptions;\n }\n\n override get credential() {\n const apiKey =\n this.options?.apiKey || process.env[this.apiKeyEnvName] || process.env.CLAUDE_API_KEY;\n\n return {\n apiKey,\n model: this.options?.model || CHAT_MODEL_CLAUDE_DEFAULT_MODEL,\n };\n }\n\n override async countTokens(input: ChatModelInput): Promise<number> {\n const request = await this.getMessageCreateParams(input);\n return (await this.client.messages.countTokens(omit(request, \"max_tokens\"))).input_tokens;\n }\n\n private async getMessageCreateParams(\n input: ChatModelInput,\n ): Promise<Anthropic.Messages.MessageCreateParams> {\n const { modelOptions = {} } = input;\n const model = modelOptions.model || this.credential.model;\n const disableParallelToolUse = modelOptions.parallelToolCalls === false;\n\n return {\n model,\n temperature: modelOptions.temperature,\n top_p: modelOptions.topP,\n max_tokens: this.getMaxTokens(model),\n ...(await convertMessages(input)),\n ...convertTools({ ...input, disableParallelToolUse }),\n };\n }\n\n private getMaxTokens(model: string): number {\n const matchers = [\n [/claude-opus-4-/, 32000],\n [/claude-sonnet-4-/, 64000],\n [/claude-3-7-sonnet-/, 64000],\n [/claude-3-5-sonnet-/, 8192],\n [/claude-3-5-haiku-/, 8192],\n ] as const;\n\n for (const [regex, maxTokens] of matchers) {\n if (regex.test(model)) {\n return maxTokens;\n }\n }\n\n return 4096;\n }\n\n /**\n * Process the input using Claude's chat model\n * @param input - The input to process\n * @returns The processed output from the model\n */\n override process(\n input: ChatModelInput,\n _options: AgentInvokeOptions,\n ): PromiseOrValue<AgentProcessResult<ChatModelOutput>> {\n return this.processInput(input);\n }\n\n private async *processInput(input: ChatModelInput): AgentProcessAsyncGenerator<ChatModelOutput> {\n const body = await this.getMessageCreateParams(input);\n const stream = this.client.messages.stream({ ...body, stream: true });\n\n const blocks: ((ChatModelOutputToolCall & { args: string }) | null)[] = [];\n let usage: ChatModelOutputUsage | undefined;\n let json: unknown;\n\n for await (const chunk of stream) {\n if (chunk.type === \"message_start\") {\n yield { delta: { json: { model: chunk.message.model } } };\n\n const {\n input_tokens,\n output_tokens,\n cache_creation_input_tokens,\n cache_read_input_tokens,\n } = chunk.message.usage;\n usage = {\n inputTokens: input_tokens,\n outputTokens: output_tokens,\n cacheCreationInputTokens: cache_creation_input_tokens ?? undefined,\n cacheReadInputTokens: cache_read_input_tokens ?? undefined,\n };\n }\n\n if (chunk.type === \"message_delta\" && usage) {\n usage.outputTokens = chunk.usage.output_tokens;\n }\n\n if (chunk.type === \"content_block_delta\" && chunk.delta.type === \"text_delta\") {\n yield { delta: { text: { text: chunk.delta.text } } };\n }\n\n if (chunk.type === \"content_block_start\" && chunk.content_block.type === \"tool_use\") {\n blocks[chunk.index] = {\n type: \"function\",\n id: chunk.content_block.id,\n function: { name: chunk.content_block.name, arguments: {} },\n args: \"\",\n };\n }\n\n if (chunk.type === \"content_block_delta\" && chunk.delta.type === \"input_json_delta\") {\n const call = blocks[chunk.index];\n if (!call) throw new Error(\"Tool call not found\");\n call.args += chunk.delta.partial_json;\n }\n }\n\n const toolCalls = blocks.filter(isNonNullable);\n\n // Separate output tool from business tool calls\n const outputToolCall = toolCalls.find((c) => c.function.name === OUTPUT_FUNCTION_NAME);\n const businessToolCalls = toolCalls\n .filter((c) => c.function.name !== OUTPUT_FUNCTION_NAME)\n .map(({ args, ...c }) => ({\n ...c,\n function: {\n ...c.function,\n arguments: args.trim() ? parseJSON(args) : {},\n },\n }))\n .filter(isNonNullable);\n\n if (outputToolCall) {\n json = outputToolCall.args.trim() ? parseJSON(outputToolCall.args) : {};\n }\n\n if (businessToolCalls.length) {\n yield { delta: { json: { toolCalls: businessToolCalls } } };\n }\n\n if (json !== undefined) {\n yield { delta: { json: { json: json as object } } };\n }\n\n yield { delta: { json: { usage } } };\n }\n}\n\n/**\n * Parse cache configuration from model options\n */\nfunction parseCacheConfig(modelOptions?: ChatModelInput[\"modelOptions\"]) {\n const cacheConfig = modelOptions?.cacheConfig || {};\n const shouldCache = cacheConfig.enabled !== false; // Default: enabled\n const ttl = cacheConfig.ttl === \"1h\" ? \"1h\" : \"5m\"; // Default: 5m\n const strategy = cacheConfig.strategy || \"auto\"; // Default: auto\n const autoBreakpoints = {\n tools: cacheConfig.autoBreakpoints?.tools !== false, // Default: true\n system: cacheConfig.autoBreakpoints?.system !== false, // Default: true\n lastMessage: cacheConfig.autoBreakpoints?.lastMessage === true, // Default: false\n };\n\n return {\n shouldCache,\n ttl,\n strategy,\n autoBreakpoints,\n };\n}\n\nasync function convertMessages({ messages, modelOptions }: ChatModelInput): Promise<{\n messages: MessageParam[];\n system?: Anthropic.Messages.TextBlockParam[];\n}> {\n const systemBlocks: Anthropic.Messages.TextBlockParam[] = [];\n const msgs: MessageParam[] = [];\n\n // Extract cache configuration with defaults\n const { shouldCache, strategy, autoBreakpoints, ...cacheConfig } = parseCacheConfig(modelOptions);\n const ttl = cacheConfig.ttl === \"1h\" ? \"1h\" : undefined;\n\n for (const msg of messages) {\n if (msg.role === \"system\") {\n if (typeof msg.content === \"string\") {\n const block: Anthropic.Messages.TextBlockParam = {\n type: \"text\",\n text: msg.content,\n };\n\n systemBlocks.push(block);\n } else if (Array.isArray(msg.content)) {\n systemBlocks.push(\n ...msg.content.map((item) => {\n if (item.type !== \"text\")\n throw new Error(\"System message only supports text content blocks\");\n return { type: \"text\" as const, text: item.text };\n }),\n );\n } else {\n throw new Error(\"System message must have string or array content\");\n }\n } else if (msg.role === \"tool\") {\n if (!msg.toolCallId) throw new Error(\"Tool message must have toolCallId\");\n if (!msg.content) throw new Error(\"Tool message must have content\");\n\n msgs.push({\n role: \"user\",\n content: [\n {\n type: \"tool_result\",\n tool_use_id: msg.toolCallId,\n content: await convertContent(msg.content),\n },\n ],\n });\n } else if (msg.role === \"user\") {\n if (!msg.content) throw new Error(\"User message must have content\");\n\n msgs.push({ role: \"user\", content: await convertContent(msg.content) });\n } else if (msg.role === \"agent\") {\n if (msg.toolCalls?.length) {\n msgs.push({\n role: \"assistant\",\n content: msg.toolCalls.map((i) => ({\n type: \"tool_use\",\n id: i.id,\n name: i.function.name,\n input: i.function.arguments,\n })),\n });\n } else if (msg.content) {\n msgs.push({ role: \"assistant\", content: await convertContent(msg.content) });\n } else {\n throw new Error(\"Agent message must have content or toolCalls\");\n }\n }\n }\n\n // Apply cache_control to the last system block if auto strategy is enabled\n if (shouldCache && strategy === \"auto\") {\n if (autoBreakpoints.system && systemBlocks.length > 0) {\n const lastBlock = systemBlocks[systemBlocks.length - 1];\n if (lastBlock) {\n lastBlock.cache_control = { type: \"ephemeral\", ttl };\n }\n }\n\n if (autoBreakpoints.lastMessage) {\n const lastMsg = msgs[msgs.length - 1];\n if (lastMsg) {\n if (typeof lastMsg.content === \"string\") {\n lastMsg.content = [\n { type: \"text\", text: lastMsg.content, cache_control: { type: \"ephemeral\", ttl } },\n ];\n } else if (Array.isArray(lastMsg.content)) {\n const lastBlock = lastMsg.content[lastMsg.content.length - 1];\n if (\n lastBlock &&\n lastBlock.type !== \"thinking\" &&\n lastBlock.type !== \"redacted_thinking\"\n ) {\n lastBlock.cache_control = { type: \"ephemeral\", ttl };\n }\n }\n }\n }\n }\n\n // Manual cache control: apply user-specified cacheControl from system messages\n if (shouldCache && strategy === \"manual\") {\n for (const [index, msg] of messages.entries()) {\n const msgWithCache = msg;\n if (msg.role === \"system\" && msgWithCache.cacheControl) {\n const block = systemBlocks[index];\n if (block) {\n block.cache_control = {\n type: msgWithCache.cacheControl.type,\n ...(msgWithCache.cacheControl.ttl && { ttl: msgWithCache.cacheControl.ttl }),\n };\n }\n }\n }\n }\n\n // Claude requires at least one message, so we add a system message if there are no messages\n if (msgs.length === 0) {\n if (systemBlocks.length === 0) throw new Error(\"No messages provided\");\n // Convert system blocks to a single user message\n const systemText = systemBlocks.map((b) => b.text).join(\"\\n\");\n return { messages: [{ role: \"user\", content: systemText }] };\n }\n\n return {\n messages: msgs,\n system: systemBlocks.length > 0 ? systemBlocks : undefined,\n };\n}\n\nasync function convertContent(\n content: ChatModelInputMessageContent,\n): Promise<string | (TextBlockParam | ImageBlockParam)[]> {\n if (typeof content === \"string\") return content;\n\n if (Array.isArray(content)) {\n return Promise.all(\n content.map<Promise<TextBlockParam | ImageBlockParam>>(async (item) => {\n if (item.type === \"text\") return { type: \"text\", text: item.text };\n\n const media_type = (await ChatModel.getMimeType(\n item.mimeType || item.filename || \"\",\n )) as Base64ImageSource[\"media_type\"];\n\n switch (item.type) {\n case \"url\":\n return { type: \"image\", source: { type: \"url\", url: item.url } };\n case \"file\":\n return {\n type: \"image\",\n source: { type: \"base64\", data: item.data, media_type },\n };\n case \"local\":\n throw new Error(\n `Unsupported local file: ${item.path}, it should be converted to base64 at ChatModel`,\n );\n }\n }),\n );\n }\n\n throw new Error(\"Invalid chat message content\");\n}\n\nfunction convertTools({\n tools,\n toolChoice,\n disableParallelToolUse,\n modelOptions,\n responseFormat,\n}: ChatModelInput & {\n disableParallelToolUse?: boolean;\n}): { tools?: ToolUnion[]; tool_choice?: ToolChoice } | undefined {\n // Extract cache configuration with defaults\n const { shouldCache, ttl, strategy, autoBreakpoints } = parseCacheConfig(modelOptions);\n const shouldCacheTools = shouldCache && strategy === \"auto\" && autoBreakpoints.tools;\n\n // Convert business tools\n const convertedTools: Tool[] = (tools ?? []).map((i) => {\n const tool: Tool = {\n name: i.function.name,\n description: i.function.description,\n input_schema: isEmpty(i.function.parameters)\n ? { type: \"object\" }\n : (i.function.parameters as Anthropic.Messages.Tool.InputSchema),\n };\n\n // Manual cache mode: apply tool-specific cacheControl\n if (shouldCache && strategy === \"manual\" && i.cacheControl) {\n tool.cache_control = {\n type: i.cacheControl.type,\n ...(i.cacheControl.ttl && { ttl: i.cacheControl.ttl }),\n };\n }\n\n return tool;\n });\n\n // Add output tool for structured output\n if (responseFormat?.type === \"json_schema\") {\n convertedTools.push({\n name: OUTPUT_FUNCTION_NAME,\n description: \"Generate a json result by given context\",\n input_schema: responseFormat.jsonSchema.schema as Anthropic.Messages.Tool.InputSchema,\n });\n }\n\n // Auto cache mode: add cache_control to the last tool\n if (shouldCacheTools && convertedTools.length) {\n const lastTool = convertedTools[convertedTools.length - 1];\n if (lastTool) {\n lastTool.cache_control = { type: \"ephemeral\", ...(ttl === \"1h\" && { ttl: \"1h\" }) };\n }\n }\n\n // Determine tool choice\n const choice: ToolChoice | undefined =\n responseFormat?.type === \"json_schema\"\n ? // For structured output: force output tool if no business tools, otherwise let model choose\n tools?.length\n ? { type: \"any\", disable_parallel_tool_use: disableParallelToolUse }\n : { type: \"tool\", name: OUTPUT_FUNCTION_NAME, disable_parallel_tool_use: true }\n : typeof toolChoice === \"object\" && \"type\" in toolChoice && toolChoice.type === \"function\"\n ? {\n type: \"tool\",\n name: toolChoice.function.name,\n disable_parallel_tool_use: disableParallelToolUse,\n }\n : toolChoice === \"required\"\n ? { type: \"any\", disable_parallel_tool_use: disableParallelToolUse }\n : toolChoice === \"auto\"\n ? { type: \"auto\", disable_parallel_tool_use: disableParallelToolUse }\n : toolChoice === \"none\"\n ? { type: \"none\" }\n : undefined;\n\n return {\n tools: convertedTools.length ? convertedTools : undefined,\n tool_choice: choice,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"anthropic-chat-model.mjs","names":[],"sources":["../src/anthropic-chat-model.ts"],"sourcesContent":["import {\n ChatModel,\n type ChatModelInput,\n type ChatModelInputMessageContent,\n type ChatModelOptions,\n type ChatModelOutput,\n type ChatModelOutputToolCall,\n type ChatModelOutputUsage,\n type ModelInvokeOptions,\n type ModelProcessAsyncGenerator,\n type ModelProcessResult,\n} from \"@aigne/model-base\";\nimport { parseJSON } from \"@aigne/model-base/utils/json-schema\";\nimport {\n checkArguments,\n isEmpty,\n isNonNullable,\n omit,\n type PromiseOrValue,\n} from \"@aigne/model-base/utils/type-utils\";\nimport Anthropic, { type ClientOptions } from \"@anthropic-ai/sdk\";\nimport type {\n Base64ImageSource,\n ImageBlockParam,\n TextBlockParam,\n} from \"@anthropic-ai/sdk/resources\";\nimport type {\n MessageParam,\n Tool,\n ToolChoice,\n ToolUnion,\n} from \"@anthropic-ai/sdk/resources/index.js\";\nimport { z } from \"zod\";\n\nconst CHAT_MODEL_CLAUDE_DEFAULT_MODEL = \"claude-3-7-sonnet-latest\";\nconst OUTPUT_FUNCTION_NAME = \"generate_json\";\n\n/**\n * Configuration options for Claude Chat Model\n */\nexport interface AnthropicChatModelOptions extends ChatModelOptions {\n /**\n * API key for Anthropic's Claude API\n *\n * If not provided, will look for ANTHROPIC_API_KEY or CLAUDE_API_KEY in environment variables\n */\n apiKey?: string;\n\n /**\n * Optional client options for the Anthropic SDK\n */\n clientOptions?: Partial<ClientOptions>;\n}\n\n/**\n * @hidden\n */\nexport const claudeChatModelOptionsSchema = z.object({\n apiKey: z.string().optional(),\n model: z.string().optional(),\n modelOptions: z\n .object({\n model: z.string().optional(),\n temperature: z.number().optional(),\n topP: z.number().optional(),\n frequencyPenalty: z.number().optional(),\n presencePenalty: z.number().optional(),\n parallelToolCalls: z.boolean().optional().default(true),\n })\n .optional(),\n});\n\n/**\n * Implementation of the ChatModel interface for Anthropic's Claude API\n *\n * This model provides access to Claude's capabilities including:\n * - Text generation\n * - Tool use\n * - JSON structured output\n *\n * Default model: 'claude-3-7-sonnet-latest'\n *\n * @example\n * Here's how to create and use a Claude chat model:\n * {@includeCode ../test/anthropic-chat-model.test.ts#example-anthropic-chat-model}\n *\n * @example\n * Here's an example with streaming response:\n * {@includeCode ../test/anthropic-chat-model.test.ts#example-anthropic-chat-model-streaming-async-generator}\n */\nexport class AnthropicChatModel extends ChatModel {\n constructor(public override options?: AnthropicChatModelOptions) {\n if (options) checkArguments(\"AnthropicChatModel\", claudeChatModelOptionsSchema, options);\n super();\n }\n\n protected apiKeyEnvName = \"ANTHROPIC_API_KEY\";\n\n /**\n * @hidden\n */\n protected _client?: Anthropic;\n\n get client() {\n const { apiKey } = this.credential;\n if (!apiKey)\n throw new Error(\n \"AnthropicChatModel requires an API key. Please provide it via `options.apiKey`, or set the `ANTHROPIC_API_KEY` or `CLAUDE_API_KEY` environment variable\",\n );\n\n this._client ??= new Anthropic({\n apiKey,\n ...this.options?.clientOptions,\n timeout: this.options?.clientOptions?.timeout ?? 600e3,\n });\n return this._client;\n }\n\n get modelOptions() {\n return this.options?.modelOptions;\n }\n\n override get credential() {\n const apiKey =\n this.options?.apiKey || process.env[this.apiKeyEnvName] || process.env.CLAUDE_API_KEY;\n\n return {\n apiKey,\n model: this.options?.model || CHAT_MODEL_CLAUDE_DEFAULT_MODEL,\n };\n }\n\n override async countTokens(input: ChatModelInput): Promise<number> {\n const request = await this.getMessageCreateParams(input);\n return (await this.client.messages.countTokens(omit(request, \"max_tokens\"))).input_tokens;\n }\n\n private async getMessageCreateParams(\n input: ChatModelInput,\n ): Promise<Anthropic.Messages.MessageCreateParams> {\n const { modelOptions = {} } = input;\n const model = modelOptions.model || this.credential.model;\n const disableParallelToolUse = modelOptions.parallelToolCalls === false;\n\n return {\n model,\n temperature: modelOptions.temperature,\n top_p: modelOptions.topP,\n max_tokens: this.getMaxTokens(model),\n ...(await convertMessages(input)),\n ...convertTools({ ...input, disableParallelToolUse }),\n };\n }\n\n private getMaxTokens(model: string): number {\n // Order matters: more specific patterns first.\n // Source: https://platform.claude.com/docs/en/docs/about-claude/models/all-models\n const matchers = [\n [/claude-opus-4-6/, 128000], // Opus 4.6: 128K\n [/claude-opus-4-5/, 64000], // Opus 4.5: 64K\n [/claude-opus-4-/, 32000], // Opus 4.0, 4.1: 32K\n [/claude-sonnet-4-/, 64000], // Sonnet 4.0, 4.5, 4.6: 64K\n [/claude-haiku-4-/, 64000], // Haiku 4.5: 64K\n [/claude-3-7-sonnet-/, 64000], // 3.7 Sonnet: 64K\n [/claude-3-5-sonnet-/, 8192], // 3.5 Sonnet: 8K\n [/claude-3-5-haiku-/, 8192], // 3.5 Haiku: 8K\n ] as const;\n\n for (const [regex, maxTokens] of matchers) {\n if (regex.test(model)) {\n return maxTokens;\n }\n }\n\n return 4096; // Claude 3 Haiku: 4K\n }\n\n /**\n * Process the input using Claude's chat model\n * @param input - The input to process\n * @returns The processed output from the model\n */\n override process(\n input: ChatModelInput,\n _options: ModelInvokeOptions,\n ): PromiseOrValue<ModelProcessResult<ChatModelOutput>> {\n return this.processInput(input);\n }\n\n private async *processInput(input: ChatModelInput): ModelProcessAsyncGenerator<ChatModelOutput> {\n const body = await this.getMessageCreateParams(input);\n const stream = this.client.messages.stream({ ...body, stream: true });\n\n const blocks: ((ChatModelOutputToolCall & { args: string }) | null)[] = [];\n let usage: ChatModelOutputUsage | undefined;\n let json: unknown;\n\n for await (const chunk of stream) {\n if (chunk.type === \"message_start\") {\n yield { delta: { json: { model: chunk.message.model } } };\n\n const {\n input_tokens,\n output_tokens,\n cache_creation_input_tokens,\n cache_read_input_tokens,\n } = chunk.message.usage;\n usage = {\n inputTokens: input_tokens,\n outputTokens: output_tokens,\n cacheCreationInputTokens: cache_creation_input_tokens ?? undefined,\n cacheReadInputTokens: cache_read_input_tokens ?? undefined,\n };\n }\n\n if (chunk.type === \"message_delta\" && usage) {\n usage.outputTokens = chunk.usage.output_tokens;\n }\n\n if (chunk.type === \"content_block_delta\" && chunk.delta.type === \"text_delta\") {\n yield { delta: { text: { text: chunk.delta.text } } };\n }\n\n if (chunk.type === \"content_block_start\" && chunk.content_block.type === \"tool_use\") {\n blocks[chunk.index] = {\n type: \"function\",\n id: chunk.content_block.id,\n function: { name: chunk.content_block.name, arguments: {} },\n args: \"\",\n };\n }\n\n if (chunk.type === \"content_block_delta\" && chunk.delta.type === \"input_json_delta\") {\n const call = blocks[chunk.index];\n if (!call) throw new Error(\"Tool call not found\");\n call.args += chunk.delta.partial_json;\n }\n }\n\n const toolCalls = blocks.filter(isNonNullable);\n\n // Separate output tool from business tool calls\n const outputToolCall = toolCalls.find((c) => c.function.name === OUTPUT_FUNCTION_NAME);\n const businessToolCalls = toolCalls\n .filter((c) => c.function.name !== OUTPUT_FUNCTION_NAME)\n .map(({ args, ...c }) => ({\n ...c,\n function: {\n ...c.function,\n arguments: args.trim() ? parseJSON(args) : {},\n },\n }))\n .filter(isNonNullable);\n\n if (outputToolCall) {\n json = outputToolCall.args.trim() ? parseJSON(outputToolCall.args) : {};\n }\n\n if (businessToolCalls.length) {\n yield { delta: { json: { toolCalls: businessToolCalls } } };\n }\n\n if (json !== undefined) {\n yield { delta: { json: { json: json as object } } };\n }\n\n yield { delta: { json: { usage } } };\n }\n}\n\n/**\n * Parse cache configuration from model options\n */\nfunction parseCacheConfig(modelOptions?: ChatModelInput[\"modelOptions\"]) {\n const cacheConfig = modelOptions?.cacheConfig || {};\n const shouldCache = cacheConfig.enabled !== false; // Default: enabled\n const ttl = cacheConfig.ttl === \"1h\" ? \"1h\" : \"5m\"; // Default: 5m\n const strategy = cacheConfig.strategy || \"auto\"; // Default: auto\n const autoBreakpoints = {\n tools: cacheConfig.autoBreakpoints?.tools !== false, // Default: true\n system: cacheConfig.autoBreakpoints?.system !== false, // Default: true\n lastMessage: cacheConfig.autoBreakpoints?.lastMessage === true, // Default: false\n };\n\n return {\n shouldCache,\n ttl,\n strategy,\n autoBreakpoints,\n };\n}\n\nasync function convertMessages({ messages, modelOptions }: ChatModelInput): Promise<{\n messages: MessageParam[];\n system?: Anthropic.Messages.TextBlockParam[];\n}> {\n const systemBlocks: Anthropic.Messages.TextBlockParam[] = [];\n const msgs: MessageParam[] = [];\n\n // Extract cache configuration with defaults\n const { shouldCache, strategy, autoBreakpoints, ...cacheConfig } = parseCacheConfig(modelOptions);\n const ttl = cacheConfig.ttl === \"1h\" ? \"1h\" : undefined;\n\n for (const msg of messages) {\n if (msg.role === \"system\") {\n if (typeof msg.content === \"string\") {\n const block: Anthropic.Messages.TextBlockParam = {\n type: \"text\",\n text: msg.content,\n };\n\n systemBlocks.push(block);\n } else if (Array.isArray(msg.content)) {\n systemBlocks.push(\n ...msg.content.map((item) => {\n if (item.type !== \"text\")\n throw new Error(\"System message only supports text content blocks\");\n return { type: \"text\" as const, text: item.text };\n }),\n );\n } else {\n throw new Error(\"System message must have string or array content\");\n }\n } else if (msg.role === \"tool\") {\n if (!msg.toolCallId) throw new Error(\"Tool message must have toolCallId\");\n if (!msg.content) throw new Error(\"Tool message must have content\");\n\n msgs.push({\n role: \"user\",\n content: [\n {\n type: \"tool_result\",\n tool_use_id: msg.toolCallId,\n content: await convertContent(msg.content),\n },\n ],\n });\n } else if (msg.role === \"user\") {\n if (!msg.content) throw new Error(\"User message must have content\");\n\n msgs.push({ role: \"user\", content: await convertContent(msg.content) });\n } else if (msg.role === \"agent\") {\n if (msg.toolCalls?.length) {\n msgs.push({\n role: \"assistant\",\n content: msg.toolCalls.map((i) => ({\n type: \"tool_use\",\n id: i.id,\n name: i.function.name,\n input: i.function.arguments,\n })),\n });\n } else if (msg.content) {\n msgs.push({ role: \"assistant\", content: await convertContent(msg.content) });\n } else {\n throw new Error(\"Agent message must have content or toolCalls\");\n }\n }\n }\n\n // Apply cache_control to the last system block if auto strategy is enabled\n if (shouldCache && strategy === \"auto\") {\n if (autoBreakpoints.system && systemBlocks.length > 0) {\n const lastBlock = systemBlocks[systemBlocks.length - 1];\n if (lastBlock) {\n lastBlock.cache_control = { type: \"ephemeral\", ttl };\n }\n }\n\n if (autoBreakpoints.lastMessage) {\n const lastMsg = msgs[msgs.length - 1];\n if (lastMsg) {\n if (typeof lastMsg.content === \"string\") {\n lastMsg.content = [\n { type: \"text\", text: lastMsg.content, cache_control: { type: \"ephemeral\", ttl } },\n ];\n } else if (Array.isArray(lastMsg.content)) {\n const lastBlock = lastMsg.content[lastMsg.content.length - 1];\n if (\n lastBlock &&\n lastBlock.type !== \"thinking\" &&\n lastBlock.type !== \"redacted_thinking\"\n ) {\n lastBlock.cache_control = { type: \"ephemeral\", ttl };\n }\n }\n }\n }\n }\n\n // Manual cache control: apply user-specified cacheControl from system messages\n if (shouldCache && strategy === \"manual\") {\n for (const [index, msg] of messages.entries()) {\n const msgWithCache = msg;\n if (msg.role === \"system\" && msgWithCache.cacheControl) {\n const block = systemBlocks[index];\n if (block) {\n block.cache_control = {\n type: msgWithCache.cacheControl.type,\n ...(msgWithCache.cacheControl.ttl && { ttl: msgWithCache.cacheControl.ttl }),\n };\n }\n }\n }\n }\n\n // Claude requires at least one message, so we add a system message if there are no messages\n if (msgs.length === 0) {\n if (systemBlocks.length === 0) throw new Error(\"No messages provided\");\n // Convert system blocks to a single user message\n const systemText = systemBlocks.map((b) => b.text).join(\"\\n\");\n return { messages: [{ role: \"user\", content: systemText }] };\n }\n\n return {\n messages: msgs,\n system: systemBlocks.length > 0 ? systemBlocks : undefined,\n };\n}\n\nasync function convertContent(\n content: ChatModelInputMessageContent,\n): Promise<string | (TextBlockParam | ImageBlockParam)[]> {\n if (typeof content === \"string\") return content;\n\n if (Array.isArray(content)) {\n return Promise.all(\n content.map<Promise<TextBlockParam | ImageBlockParam>>(async (item) => {\n if (item.type === \"text\") return { type: \"text\", text: item.text };\n\n const media_type = (item.mimeType ||\n (await ChatModel.getMimeType(item.filename || \"\"))) as Base64ImageSource[\"media_type\"];\n\n switch (item.type) {\n case \"url\":\n return { type: \"image\", source: { type: \"url\", url: item.url } };\n case \"file\":\n return {\n type: \"image\",\n source: { type: \"base64\", data: item.data, media_type },\n };\n case \"local\":\n throw new Error(\n `Unsupported local file: ${item.path}, it should be converted to base64 at ChatModel`,\n );\n }\n }),\n );\n }\n\n throw new Error(\"Invalid chat message content\");\n}\n\nfunction convertTools({\n tools,\n toolChoice,\n disableParallelToolUse,\n modelOptions,\n responseFormat,\n}: ChatModelInput & {\n disableParallelToolUse?: boolean;\n}): { tools?: ToolUnion[]; tool_choice?: ToolChoice } | undefined {\n // Extract cache configuration with defaults\n const { shouldCache, ttl, strategy, autoBreakpoints } = parseCacheConfig(modelOptions);\n const shouldCacheTools = shouldCache && strategy === \"auto\" && autoBreakpoints.tools;\n\n // Convert business tools\n const convertedTools: Tool[] = (tools ?? []).map((i) => {\n const tool: Tool = {\n name: i.function.name,\n description: i.function.description,\n input_schema: isEmpty(i.function.parameters)\n ? { type: \"object\" }\n : (i.function.parameters as Anthropic.Messages.Tool.InputSchema),\n };\n\n // Manual cache mode: apply tool-specific cacheControl\n if (shouldCache && strategy === \"manual\" && i.cacheControl) {\n tool.cache_control = {\n type: i.cacheControl.type,\n ...(i.cacheControl.ttl && { ttl: i.cacheControl.ttl }),\n };\n }\n\n return tool;\n });\n\n // Add output tool for structured output\n if (responseFormat?.type === \"json_schema\") {\n convertedTools.push({\n name: OUTPUT_FUNCTION_NAME,\n description: \"Generate a json result by given context\",\n input_schema: responseFormat.jsonSchema.schema as Anthropic.Messages.Tool.InputSchema,\n });\n }\n\n // Auto cache mode: add cache_control to the last tool\n if (shouldCacheTools && convertedTools.length) {\n const lastTool = convertedTools[convertedTools.length - 1];\n if (lastTool) {\n lastTool.cache_control = { type: \"ephemeral\", ...(ttl === \"1h\" && { ttl: \"1h\" }) };\n }\n }\n\n // Determine tool choice\n const choice: ToolChoice | undefined =\n responseFormat?.type === \"json_schema\"\n ? // For structured output: force output tool if no business tools, otherwise let model choose\n tools?.length\n ? { type: \"any\", disable_parallel_tool_use: disableParallelToolUse }\n : { type: \"tool\", name: OUTPUT_FUNCTION_NAME, disable_parallel_tool_use: true }\n : typeof toolChoice === \"object\" && \"type\" in toolChoice && toolChoice.type === \"function\"\n ? {\n type: \"tool\",\n name: toolChoice.function.name,\n disable_parallel_tool_use: disableParallelToolUse,\n }\n : toolChoice === \"required\"\n ? { type: \"any\", disable_parallel_tool_use: disableParallelToolUse }\n : toolChoice === \"auto\"\n ? { type: \"auto\", disable_parallel_tool_use: disableParallelToolUse }\n : toolChoice === \"none\"\n ? { type: \"none\" }\n : undefined;\n\n return {\n tools: convertedTools.length ? convertedTools : undefined,\n tool_choice: choice,\n };\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aigne/anthropic",
3
- "version": "1.74.0-beta",
3
+ "version": "1.74.0-beta.10",
4
4
  "description": "AIGNE Anthropic SDK for integrating with Claude AI models",
5
5
  "license": "Elastic-2.0",
6
6
  "publishConfig": {
@@ -35,8 +35,7 @@
35
35
  "dependencies": {
36
36
  "@anthropic-ai/sdk": "^0.63.0",
37
37
  "zod": "^3.25.67",
38
- "@aigne/core": "^1.74.0-beta",
39
- "@aigne/utils": "^1.74.0-beta"
38
+ "@aigne/model-base": "^1.74.0-beta.10"
40
39
  },
41
40
  "devDependencies": {
42
41
  "@types/bun": "^1.3.6",
@@ -44,9 +43,7 @@
44
43
  "rimraf": "^6.1.2",
45
44
  "tsdown": "0.20.0-beta.3",
46
45
  "typescript": "5.9.2",
47
- "@aigne/scripts": "0.0.0",
48
- "@aigne/typescript-config": "0.0.0",
49
- "@aigne/utils": "1.74.0-beta"
46
+ "@aigne/typescript-config": "0.0.0"
50
47
  },
51
48
  "scripts": {
52
49
  "build": "tsdown",
package/LICENSE.md DELETED
@@ -1,93 +0,0 @@
1
- Elastic License 2.0
2
-
3
- URL: https://www.elastic.co/licensing/elastic-license
4
-
5
- ## Acceptance
6
-
7
- By using the software, you agree to all of the terms and conditions below.
8
-
9
- ## Copyright License
10
-
11
- The licensor grants you a non-exclusive, royalty-free, worldwide,
12
- non-sublicensable, non-transferable license to use, copy, distribute, make
13
- available, and prepare derivative works of the software, in each case subject to
14
- the limitations and conditions below.
15
-
16
- ## Limitations
17
-
18
- You may not provide the software to third parties as a hosted or managed
19
- service, where the service provides users with access to any substantial set of
20
- the features or functionality of the software.
21
-
22
- You may not move, change, disable, or circumvent the license key functionality
23
- in the software, and you may not remove or obscure any functionality in the
24
- software that is protected by the license key.
25
-
26
- You may not alter, remove, or obscure any licensing, copyright, or other notices
27
- of the licensor in the software. Any use of the licensor’s trademarks is subject
28
- to applicable law.
29
-
30
- ## Patents
31
-
32
- The licensor grants you a license, under any patent claims the licensor can
33
- license, or becomes able to license, to make, have made, use, sell, offer for
34
- sale, import and have imported the software, in each case subject to the
35
- limitations and conditions in this license. This license does not cover any
36
- patent claims that you cause to be infringed by modifications or additions to
37
- the software. If you or your company make any written claim that the software
38
- infringes or contributes to infringement of any patent, your patent license for
39
- the software granted under these terms ends immediately. If your company makes
40
- such a claim, your patent license ends immediately for work on behalf of your
41
- company.
42
-
43
- ## Notices
44
-
45
- You must ensure that anyone who gets a copy of any part of the software from you
46
- also gets a copy of these terms.
47
-
48
- If you modify the software, you must include in any modified copies of the
49
- software prominent notices stating that you have modified the software.
50
-
51
- ## No Other Rights
52
-
53
- These terms do not imply any licenses other than those expressly granted in
54
- these terms.
55
-
56
- ## Termination
57
-
58
- If you use the software in violation of these terms, such use is not licensed,
59
- and your licenses will automatically terminate. If the licensor provides you
60
- with a notice of your violation, and you cease all violation of this license no
61
- later than 30 days after you receive that notice, your licenses will be
62
- reinstated retroactively. However, if you violate these terms after such
63
- reinstatement, any additional violation of these terms will cause your licenses
64
- to terminate automatically and permanently.
65
-
66
- ## No Liability
67
-
68
- *As far as the law allows, the software comes as is, without any warranty or
69
- condition, and the licensor will not be liable to you for any damages arising
70
- out of these terms or the use or nature of the software, under any kind of
71
- legal claim.*
72
-
73
- ## Definitions
74
-
75
- The **licensor** is the entity offering these terms, and the **software** is the
76
- software the licensor makes available under these terms, including any portion
77
- of it.
78
-
79
- **you** refers to the individual or entity agreeing to these terms.
80
-
81
- **your company** is any legal entity, sole proprietorship, or other kind of
82
- organization that you work for, plus all organizations that have control over,
83
- are under the control of, or are under common control with that
84
- organization. **control** means ownership of substantially all the assets of an
85
- entity, or the power to direct its management and policies by vote, contract, or
86
- otherwise. Control can be direct or indirect.
87
-
88
- **your licenses** are all the licenses granted to you for the software under
89
- these terms.
90
-
91
- **use** means anything you do with the software requiring one of your licenses.
92
-
93
- **trademark** means trademarks, service marks, and similar rights.