@aigne/core 1.3.0 → 1.3.1
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 +7 -0
- package/lib/cjs/models/claude-chat-model.js +17 -6
- package/lib/cjs/models/openai-chat-model.js +3 -2
- package/lib/cjs/utils/json-schema.d.ts +1 -0
- package/lib/cjs/utils/json-schema.js +11 -0
- package/lib/dts/utils/json-schema.d.ts +1 -0
- package/lib/esm/models/claude-chat-model.js +17 -6
- package/lib/esm/models/openai-chat-model.js +3 -2
- package/lib/esm/utils/json-schema.d.ts +1 -0
- package/lib/esm/utils/json-schema.js +10 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -22,6 +22,13 @@
|
|
|
22
22
|
* rename @aigne/core-next to @aigne/core ([3a81009](https://github.com/AIGNE-io/aigne-framework/commit/3a8100962c81813217b687ae28e8de604419c622))
|
|
23
23
|
* use text resource from MCP correctly ([8b9eba8](https://github.com/AIGNE-io/aigne-framework/commit/8b9eba83352ec096a2a5d4f410d4c4bde7420bce))
|
|
24
24
|
|
|
25
|
+
## [1.3.1](https://github.com/AIGNE-io/aigne-framework/compare/core-v1.3.0...core-v1.3.1) (2025-03-25)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
### Bug Fixes
|
|
29
|
+
|
|
30
|
+
* **core:** use system message as user message for claude model if needed ([#32](https://github.com/AIGNE-io/aigne-framework/issues/32)) ([316a6d5](https://github.com/AIGNE-io/aigne-framework/commit/316a6d51f885cceee4020c24695f6588f6b7425f))
|
|
31
|
+
|
|
25
32
|
## [1.2.0](https://github.com/AIGNE-io/aigne-framework/compare/core-next-v1.1.0...core-next-v1.2.0) (2025-03-18)
|
|
26
33
|
|
|
27
34
|
- chore: release v1.2.0
|
|
@@ -5,6 +5,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.ClaudeChatModel = void 0;
|
|
7
7
|
const sdk_1 = __importDefault(require("@anthropic-ai/sdk"));
|
|
8
|
+
const lodash_es_1 = require("lodash-es");
|
|
9
|
+
const json_schema_js_1 = require("../utils/json-schema.js");
|
|
8
10
|
const type_utils_js_1 = require("../utils/type-utils.js");
|
|
9
11
|
const chat_model_js_1 = require("./chat-model.js");
|
|
10
12
|
const CHAT_MODEL_CLAUDE_DEFAULT_MODEL = "claude-3-7-sonnet-latest";
|
|
@@ -75,7 +77,7 @@ class ClaudeChatModel extends chat_model_js_1.ChatModel {
|
|
|
75
77
|
result.toolCalls = toolCalls
|
|
76
78
|
.map(({ args, ...c }) => ({
|
|
77
79
|
...c,
|
|
78
|
-
function: { ...c.function, arguments:
|
|
80
|
+
function: { ...c.function, arguments: (0, json_schema_js_1.parseJSON)(args) },
|
|
79
81
|
}))
|
|
80
82
|
.filter(type_utils_js_1.isNonNullable);
|
|
81
83
|
}
|
|
@@ -132,7 +134,7 @@ function convertMessages({ messages, responseFormat }) {
|
|
|
132
134
|
else if (msg.role === "user") {
|
|
133
135
|
if (!msg.content)
|
|
134
136
|
throw new Error("User message must have content");
|
|
135
|
-
msgs.push({ role: "user", content:
|
|
137
|
+
msgs.push({ role: "user", content: convertContent(msg.content) });
|
|
136
138
|
}
|
|
137
139
|
else if (msg.role === "agent") {
|
|
138
140
|
if (msg.toolCalls?.length) {
|
|
@@ -147,7 +149,7 @@ function convertMessages({ messages, responseFormat }) {
|
|
|
147
149
|
});
|
|
148
150
|
}
|
|
149
151
|
else if (msg.content) {
|
|
150
|
-
msgs.push({ role: "assistant", content:
|
|
152
|
+
msgs.push({ role: "assistant", content: convertContent(msg.content) });
|
|
151
153
|
}
|
|
152
154
|
else {
|
|
153
155
|
throw new Error("Agent message must have content or toolCalls");
|
|
@@ -157,9 +159,16 @@ function convertMessages({ messages, responseFormat }) {
|
|
|
157
159
|
if (responseFormat?.type === "json_schema") {
|
|
158
160
|
systemMessages.push(`You should provide a json response with schema: ${JSON.stringify(responseFormat.jsonSchema.schema)}`);
|
|
159
161
|
}
|
|
160
|
-
|
|
162
|
+
const system = systemMessages.join("\n").trim() || undefined;
|
|
163
|
+
// Claude requires at least one message, so we add a system message if there are no messages
|
|
164
|
+
if (msgs.length === 0) {
|
|
165
|
+
if (!system)
|
|
166
|
+
throw new Error("No messages provided");
|
|
167
|
+
return { messages: [{ role: "user", content: system }] };
|
|
168
|
+
}
|
|
169
|
+
return { messages: msgs, system };
|
|
161
170
|
}
|
|
162
|
-
function
|
|
171
|
+
function convertContent(content) {
|
|
163
172
|
if (typeof content === "string")
|
|
164
173
|
return content;
|
|
165
174
|
if (Array.isArray(content)) {
|
|
@@ -191,7 +200,9 @@ function convertTools({ tools, toolChoice, }) {
|
|
|
191
200
|
? tools.map((i) => ({
|
|
192
201
|
name: i.function.name,
|
|
193
202
|
description: i.function.description,
|
|
194
|
-
input_schema: i.function.parameters
|
|
203
|
+
input_schema: (0, lodash_es_1.isEmpty)(i.function.parameters)
|
|
204
|
+
? { type: "object" }
|
|
205
|
+
: i.function.parameters,
|
|
195
206
|
}))
|
|
196
207
|
: undefined,
|
|
197
208
|
tool_choice: choice,
|
|
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.OpenAIChatModel = void 0;
|
|
7
7
|
const nanoid_1 = require("nanoid");
|
|
8
8
|
const openai_1 = __importDefault(require("openai"));
|
|
9
|
+
const json_schema_js_1 = require("../utils/json-schema.js");
|
|
9
10
|
const type_utils_js_1 = require("../utils/type-utils.js");
|
|
10
11
|
const chat_model_js_1 = require("./chat-model.js");
|
|
11
12
|
const CHAT_MODEL_OPENAI_DEFAULT_MODEL = "gpt-4o-mini";
|
|
@@ -69,7 +70,7 @@ class OpenAIChatModel extends chat_model_js_1.ChatModel {
|
|
|
69
70
|
}
|
|
70
71
|
const result = {};
|
|
71
72
|
if (input.responseFormat?.type === "json_schema" && text) {
|
|
72
|
-
result.json =
|
|
73
|
+
result.json = (0, json_schema_js_1.parseJSON)(text);
|
|
73
74
|
}
|
|
74
75
|
else {
|
|
75
76
|
result.text = text;
|
|
@@ -77,7 +78,7 @@ class OpenAIChatModel extends chat_model_js_1.ChatModel {
|
|
|
77
78
|
if (toolCalls.length) {
|
|
78
79
|
result.toolCalls = toolCalls.map(({ args, ...c }) => ({
|
|
79
80
|
...c,
|
|
80
|
-
function: { ...c.function, arguments:
|
|
81
|
+
function: { ...c.function, arguments: (0, json_schema_js_1.parseJSON)(args) },
|
|
81
82
|
}));
|
|
82
83
|
}
|
|
83
84
|
return result;
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.outputSchemaToResponseFormatSchema = outputSchemaToResponseFormatSchema;
|
|
4
|
+
exports.parseJSON = parseJSON;
|
|
4
5
|
const lodash_es_1 = require("lodash-es");
|
|
5
6
|
const zod_to_json_schema_1 = require("zod-to-json-schema");
|
|
7
|
+
const logger_js_1 = require("./logger.js");
|
|
6
8
|
function outputSchemaToResponseFormatSchema(agentOutput) {
|
|
7
9
|
return setAdditionPropertiesDeep((0, zod_to_json_schema_1.zodToJsonSchema)(agentOutput), false);
|
|
8
10
|
}
|
|
@@ -21,3 +23,12 @@ function setAdditionPropertiesDeep(schema, additionalProperties) {
|
|
|
21
23
|
}
|
|
22
24
|
return schema;
|
|
23
25
|
}
|
|
26
|
+
function parseJSON(json) {
|
|
27
|
+
try {
|
|
28
|
+
return JSON.parse(json);
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
logger_js_1.logger.debug("Failed to parse JSON", { json, error });
|
|
32
|
+
throw new Error(`Failed to parse JSON ${error.message}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import Anthropic from "@anthropic-ai/sdk";
|
|
2
|
+
import { isEmpty } from "lodash-es";
|
|
3
|
+
import { parseJSON } from "../utils/json-schema.js";
|
|
2
4
|
import { isNonNullable } from "../utils/type-utils.js";
|
|
3
5
|
import { ChatModel, } from "./chat-model.js";
|
|
4
6
|
const CHAT_MODEL_CLAUDE_DEFAULT_MODEL = "claude-3-7-sonnet-latest";
|
|
@@ -69,7 +71,7 @@ export class ClaudeChatModel extends ChatModel {
|
|
|
69
71
|
result.toolCalls = toolCalls
|
|
70
72
|
.map(({ args, ...c }) => ({
|
|
71
73
|
...c,
|
|
72
|
-
function: { ...c.function, arguments:
|
|
74
|
+
function: { ...c.function, arguments: parseJSON(args) },
|
|
73
75
|
}))
|
|
74
76
|
.filter(isNonNullable);
|
|
75
77
|
}
|
|
@@ -125,7 +127,7 @@ function convertMessages({ messages, responseFormat }) {
|
|
|
125
127
|
else if (msg.role === "user") {
|
|
126
128
|
if (!msg.content)
|
|
127
129
|
throw new Error("User message must have content");
|
|
128
|
-
msgs.push({ role: "user", content:
|
|
130
|
+
msgs.push({ role: "user", content: convertContent(msg.content) });
|
|
129
131
|
}
|
|
130
132
|
else if (msg.role === "agent") {
|
|
131
133
|
if (msg.toolCalls?.length) {
|
|
@@ -140,7 +142,7 @@ function convertMessages({ messages, responseFormat }) {
|
|
|
140
142
|
});
|
|
141
143
|
}
|
|
142
144
|
else if (msg.content) {
|
|
143
|
-
msgs.push({ role: "assistant", content:
|
|
145
|
+
msgs.push({ role: "assistant", content: convertContent(msg.content) });
|
|
144
146
|
}
|
|
145
147
|
else {
|
|
146
148
|
throw new Error("Agent message must have content or toolCalls");
|
|
@@ -150,9 +152,16 @@ function convertMessages({ messages, responseFormat }) {
|
|
|
150
152
|
if (responseFormat?.type === "json_schema") {
|
|
151
153
|
systemMessages.push(`You should provide a json response with schema: ${JSON.stringify(responseFormat.jsonSchema.schema)}`);
|
|
152
154
|
}
|
|
153
|
-
|
|
155
|
+
const system = systemMessages.join("\n").trim() || undefined;
|
|
156
|
+
// Claude requires at least one message, so we add a system message if there are no messages
|
|
157
|
+
if (msgs.length === 0) {
|
|
158
|
+
if (!system)
|
|
159
|
+
throw new Error("No messages provided");
|
|
160
|
+
return { messages: [{ role: "user", content: system }] };
|
|
161
|
+
}
|
|
162
|
+
return { messages: msgs, system };
|
|
154
163
|
}
|
|
155
|
-
function
|
|
164
|
+
function convertContent(content) {
|
|
156
165
|
if (typeof content === "string")
|
|
157
166
|
return content;
|
|
158
167
|
if (Array.isArray(content)) {
|
|
@@ -184,7 +193,9 @@ function convertTools({ tools, toolChoice, }) {
|
|
|
184
193
|
? tools.map((i) => ({
|
|
185
194
|
name: i.function.name,
|
|
186
195
|
description: i.function.description,
|
|
187
|
-
input_schema: i.function.parameters
|
|
196
|
+
input_schema: isEmpty(i.function.parameters)
|
|
197
|
+
? { type: "object" }
|
|
198
|
+
: i.function.parameters,
|
|
188
199
|
}))
|
|
189
200
|
: undefined,
|
|
190
201
|
tool_choice: choice,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { nanoid } from "nanoid";
|
|
2
2
|
import OpenAI from "openai";
|
|
3
|
+
import { parseJSON } from "../utils/json-schema.js";
|
|
3
4
|
import { isNonNullable } from "../utils/type-utils.js";
|
|
4
5
|
import { ChatModel, } from "./chat-model.js";
|
|
5
6
|
const CHAT_MODEL_OPENAI_DEFAULT_MODEL = "gpt-4o-mini";
|
|
@@ -63,7 +64,7 @@ export class OpenAIChatModel extends ChatModel {
|
|
|
63
64
|
}
|
|
64
65
|
const result = {};
|
|
65
66
|
if (input.responseFormat?.type === "json_schema" && text) {
|
|
66
|
-
result.json =
|
|
67
|
+
result.json = parseJSON(text);
|
|
67
68
|
}
|
|
68
69
|
else {
|
|
69
70
|
result.text = text;
|
|
@@ -71,7 +72,7 @@ export class OpenAIChatModel extends ChatModel {
|
|
|
71
72
|
if (toolCalls.length) {
|
|
72
73
|
result.toolCalls = toolCalls.map(({ args, ...c }) => ({
|
|
73
74
|
...c,
|
|
74
|
-
function: { ...c.function, arguments:
|
|
75
|
+
function: { ...c.function, arguments: parseJSON(args) },
|
|
75
76
|
}));
|
|
76
77
|
}
|
|
77
78
|
return result;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { isObject } from "lodash-es";
|
|
2
2
|
import { zodToJsonSchema } from "zod-to-json-schema";
|
|
3
|
+
import { logger } from "./logger.js";
|
|
3
4
|
export function outputSchemaToResponseFormatSchema(agentOutput) {
|
|
4
5
|
return setAdditionPropertiesDeep(zodToJsonSchema(agentOutput), false);
|
|
5
6
|
}
|
|
@@ -18,3 +19,12 @@ function setAdditionPropertiesDeep(schema, additionalProperties) {
|
|
|
18
19
|
}
|
|
19
20
|
return schema;
|
|
20
21
|
}
|
|
22
|
+
export function parseJSON(json) {
|
|
23
|
+
try {
|
|
24
|
+
return JSON.parse(json);
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
logger.debug("Failed to parse JSON", { json, error });
|
|
28
|
+
throw new Error(`Failed to parse JSON ${error.message}`);
|
|
29
|
+
}
|
|
30
|
+
}
|