@aigne/anthropic 0.11.16 → 0.12.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/CHANGELOG.md CHANGED
@@ -1,5 +1,32 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.12.0](https://github.com/AIGNE-io/aigne-framework/compare/anthropic-v0.11.17...anthropic-v0.12.0) (2025-09-05)
4
+
5
+
6
+ ### Features
7
+
8
+ * add modalities support for chat model ([#454](https://github.com/AIGNE-io/aigne-framework/issues/454)) ([70d1bf6](https://github.com/AIGNE-io/aigne-framework/commit/70d1bf631f4e711235d89c6df8ee210a19179b30))
9
+
10
+
11
+ ### Dependencies
12
+
13
+ * The following workspace dependencies were updated
14
+ * dependencies
15
+ * @aigne/core bumped to 1.58.0
16
+ * devDependencies
17
+ * @aigne/test-utils bumped to 0.5.44
18
+
19
+ ## [0.11.17](https://github.com/AIGNE-io/aigne-framework/compare/anthropic-v0.11.16...anthropic-v0.11.17) (2025-09-01)
20
+
21
+
22
+ ### Dependencies
23
+
24
+ * The following workspace dependencies were updated
25
+ * dependencies
26
+ * @aigne/core bumped to 1.57.5
27
+ * devDependencies
28
+ * @aigne/test-utils bumped to 0.5.43
29
+
3
30
  ## [0.11.16](https://github.com/AIGNE-io/aigne-framework/compare/anthropic-v0.11.15...anthropic-v0.11.16) (2025-08-30)
4
31
 
5
32
 
@@ -10,6 +10,7 @@ const logger_js_1 = require("@aigne/core/utils/logger.js");
10
10
  const model_utils_js_1 = require("@aigne/core/utils/model-utils.js");
11
11
  const stream_utils_js_1 = require("@aigne/core/utils/stream-utils.js");
12
12
  const type_utils_js_1 = require("@aigne/core/utils/type-utils.js");
13
+ const index_js_1 = require("@aigne/platform-helpers/nodejs/index.js");
13
14
  const sdk_1 = __importDefault(require("@anthropic-ai/sdk"));
14
15
  const ajv_1 = require("ajv");
15
16
  const zod_1 = require("zod");
@@ -117,7 +118,7 @@ class AnthropicChatModel extends core_1.ChatModel {
117
118
  top_p: input.modelOptions?.topP ?? this.modelOptions?.topP,
118
119
  // TODO: make dynamic based on model https://docs.anthropic.com/en/docs/about-claude/models/all-models
119
120
  max_tokens: this.getMaxTokens(model),
120
- ...convertMessages(input),
121
+ ...(await convertMessages(input)),
121
122
  ...convertTools({ ...input, disableParallelToolUse }),
122
123
  };
123
124
  // Claude does not support json_schema response and tool calls in the same request,
@@ -260,7 +261,7 @@ class AnthropicChatModel extends core_1.ChatModel {
260
261
  }
261
262
  }
262
263
  exports.AnthropicChatModel = AnthropicChatModel;
263
- function convertMessages({ messages, responseFormat, tools }) {
264
+ async function convertMessages({ messages, responseFormat, tools }) {
264
265
  const systemMessages = [];
265
266
  const msgs = [];
266
267
  for (const msg of messages) {
@@ -288,7 +289,7 @@ function convertMessages({ messages, responseFormat, tools }) {
288
289
  else if (msg.role === "user") {
289
290
  if (!msg.content)
290
291
  throw new Error("User message must have content");
291
- msgs.push({ role: "user", content: convertContent(msg.content) });
292
+ msgs.push({ role: "user", content: await convertContent(msg.content) });
292
293
  }
293
294
  else if (msg.role === "agent") {
294
295
  if (msg.toolCalls?.length) {
@@ -303,7 +304,7 @@ function convertMessages({ messages, responseFormat, tools }) {
303
304
  });
304
305
  }
305
306
  else if (msg.content) {
306
- msgs.push({ role: "assistant", content: convertContent(msg.content) });
307
+ msgs.push({ role: "assistant", content: await convertContent(msg.content) });
307
308
  }
308
309
  else {
309
310
  throw new Error("Agent message must have content or toolCalls");
@@ -324,13 +325,33 @@ function convertMessages({ messages, responseFormat, tools }) {
324
325
  }
325
326
  return { messages: msgs, system };
326
327
  }
327
- function convertContent(content) {
328
+ async function convertContent(content) {
328
329
  if (typeof content === "string")
329
330
  return content;
330
331
  if (Array.isArray(content)) {
331
- return content.map((item) => item.type === "image_url"
332
- ? { type: "image", source: { type: "url", url: item.url } }
333
- : { type: "text", text: item.text });
332
+ return Promise.all(content.map(async (item) => {
333
+ if (item.type === "text")
334
+ return { type: "text", text: item.text };
335
+ const media_type = core_1.ChatModel.getMimeType(item.mimeType || item.filename || "");
336
+ switch (item.type) {
337
+ case "url":
338
+ return { type: "image", source: { type: "url", url: item.url } };
339
+ case "file":
340
+ return {
341
+ type: "image",
342
+ source: { type: "base64", data: item.data, media_type },
343
+ };
344
+ case "local":
345
+ return {
346
+ type: "image",
347
+ source: {
348
+ type: "base64",
349
+ data: await index_js_1.nodejs.fs.readFile(item.path, "base64"),
350
+ media_type,
351
+ },
352
+ };
353
+ }
354
+ }));
334
355
  }
335
356
  throw new Error("Invalid chat message content");
336
357
  }
@@ -4,6 +4,7 @@ import { logger } from "@aigne/core/utils/logger.js";
4
4
  import { mergeUsage } from "@aigne/core/utils/model-utils.js";
5
5
  import { agentResponseStreamToObject } from "@aigne/core/utils/stream-utils.js";
6
6
  import { checkArguments, isEmpty, isNonNullable, } from "@aigne/core/utils/type-utils.js";
7
+ import { nodejs } from "@aigne/platform-helpers/nodejs/index.js";
7
8
  import Anthropic from "@anthropic-ai/sdk";
8
9
  import { Ajv } from "ajv";
9
10
  import { z } from "zod";
@@ -111,7 +112,7 @@ export class AnthropicChatModel extends ChatModel {
111
112
  top_p: input.modelOptions?.topP ?? this.modelOptions?.topP,
112
113
  // TODO: make dynamic based on model https://docs.anthropic.com/en/docs/about-claude/models/all-models
113
114
  max_tokens: this.getMaxTokens(model),
114
- ...convertMessages(input),
115
+ ...(await convertMessages(input)),
115
116
  ...convertTools({ ...input, disableParallelToolUse }),
116
117
  };
117
118
  // Claude does not support json_schema response and tool calls in the same request,
@@ -253,7 +254,7 @@ export class AnthropicChatModel extends ChatModel {
253
254
  };
254
255
  }
255
256
  }
256
- function convertMessages({ messages, responseFormat, tools }) {
257
+ async function convertMessages({ messages, responseFormat, tools }) {
257
258
  const systemMessages = [];
258
259
  const msgs = [];
259
260
  for (const msg of messages) {
@@ -281,7 +282,7 @@ function convertMessages({ messages, responseFormat, tools }) {
281
282
  else if (msg.role === "user") {
282
283
  if (!msg.content)
283
284
  throw new Error("User message must have content");
284
- msgs.push({ role: "user", content: convertContent(msg.content) });
285
+ msgs.push({ role: "user", content: await convertContent(msg.content) });
285
286
  }
286
287
  else if (msg.role === "agent") {
287
288
  if (msg.toolCalls?.length) {
@@ -296,7 +297,7 @@ function convertMessages({ messages, responseFormat, tools }) {
296
297
  });
297
298
  }
298
299
  else if (msg.content) {
299
- msgs.push({ role: "assistant", content: convertContent(msg.content) });
300
+ msgs.push({ role: "assistant", content: await convertContent(msg.content) });
300
301
  }
301
302
  else {
302
303
  throw new Error("Agent message must have content or toolCalls");
@@ -317,13 +318,33 @@ function convertMessages({ messages, responseFormat, tools }) {
317
318
  }
318
319
  return { messages: msgs, system };
319
320
  }
320
- function convertContent(content) {
321
+ async function convertContent(content) {
321
322
  if (typeof content === "string")
322
323
  return content;
323
324
  if (Array.isArray(content)) {
324
- return content.map((item) => item.type === "image_url"
325
- ? { type: "image", source: { type: "url", url: item.url } }
326
- : { type: "text", text: item.text });
325
+ return Promise.all(content.map(async (item) => {
326
+ if (item.type === "text")
327
+ return { type: "text", text: item.text };
328
+ const media_type = ChatModel.getMimeType(item.mimeType || item.filename || "");
329
+ switch (item.type) {
330
+ case "url":
331
+ return { type: "image", source: { type: "url", url: item.url } };
332
+ case "file":
333
+ return {
334
+ type: "image",
335
+ source: { type: "base64", data: item.data, media_type },
336
+ };
337
+ case "local":
338
+ return {
339
+ type: "image",
340
+ source: {
341
+ type: "base64",
342
+ data: await nodejs.fs.readFile(item.path, "base64"),
343
+ media_type,
344
+ },
345
+ };
346
+ }
347
+ }));
327
348
  }
328
349
  throw new Error("Invalid chat message content");
329
350
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aigne/anthropic",
3
- "version": "0.11.16",
3
+ "version": "0.12.0",
4
4
  "description": "AIGNE Anthropic SDK for integrating with Claude AI models",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -38,7 +38,8 @@
38
38
  "@anthropic-ai/sdk": "^0.56.0",
39
39
  "ajv": "^8.17.1",
40
40
  "zod": "^3.25.67",
41
- "@aigne/core": "^1.57.4"
41
+ "@aigne/core": "^1.58.0",
42
+ "@aigne/platform-helpers": "^0.6.2"
42
43
  },
43
44
  "devDependencies": {
44
45
  "@types/bun": "^1.2.18",
@@ -46,7 +47,7 @@
46
47
  "npm-run-all": "^4.1.5",
47
48
  "rimraf": "^6.0.1",
48
49
  "typescript": "^5.8.3",
49
- "@aigne/test-utils": "^0.5.42"
50
+ "@aigne/test-utils": "^0.5.44"
50
51
  },
51
52
  "scripts": {
52
53
  "lint": "tsc --noEmit",