@aigne/core 1.63.0-beta → 1.63.0-beta.2
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 +19 -0
- package/lib/cjs/agents/ai-agent.d.ts +14 -1
- package/lib/cjs/agents/ai-agent.js +56 -17
- package/lib/cjs/loader/agent-yaml.d.ts +2 -0
- package/lib/cjs/loader/agent-yaml.js +3 -0
- package/lib/dts/agents/ai-agent.d.ts +14 -1
- package/lib/dts/loader/agent-yaml.d.ts +2 -0
- package/lib/esm/agents/ai-agent.d.ts +14 -1
- package/lib/esm/agents/ai-agent.js +53 -17
- package/lib/esm/loader/agent-yaml.d.ts +2 -0
- package/lib/esm/loader/agent-yaml.js +3 -0
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.63.0-beta.2](https://github.com/AIGNE-io/aigne-framework/compare/core-v1.63.0-beta.1...core-v1.63.0-beta.2) (2025-10-09)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* input schema of AI agent should includes input key and input file key ([#600](https://github.com/AIGNE-io/aigne-framework/issues/600)) ([b4ca076](https://github.com/AIGNE-io/aigne-framework/commit/b4ca076d6b4a1a1ecb8d4ebb008abd0d7561aadd))
|
|
9
|
+
|
|
10
|
+
## [1.63.0-beta.1](https://github.com/AIGNE-io/aigne-framework/compare/core-v1.63.0-beta...core-v1.63.0-beta.1) (2025-10-09)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Features
|
|
14
|
+
|
|
15
|
+
* **core:** add `toolCallsConcurrency` support for AI agent ([#598](https://github.com/AIGNE-io/aigne-framework/issues/598)) ([84df406](https://github.com/AIGNE-io/aigne-framework/commit/84df406bfa9e3bdf159509f4b9cf2301ec80b155))
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Bug Fixes
|
|
19
|
+
|
|
20
|
+
* **core:** add input_file_key support for agent yaml ([#597](https://github.com/AIGNE-io/aigne-framework/issues/597)) ([63414a3](https://github.com/AIGNE-io/aigne-framework/commit/63414a3d46c74c686e7f033c224ca6175bea8c3f))
|
|
21
|
+
|
|
3
22
|
## [1.63.0-beta](https://github.com/AIGNE-io/aigne-framework/compare/core-v1.62.0...core-v1.63.0-beta) (2025-10-07)
|
|
4
23
|
|
|
5
24
|
|
|
@@ -3,7 +3,7 @@ import { PromptBuilder } from "../prompt/prompt-builder.js";
|
|
|
3
3
|
import { Agent, type AgentInvokeOptions, type AgentOptions, type AgentProcessAsyncGenerator, type AgentProcessResult, type Message } from "./agent.js";
|
|
4
4
|
import type { ChatModel, ChatModelInput } from "./chat-model.js";
|
|
5
5
|
import type { GuideRailAgentOutput } from "./guide-rail-agent.js";
|
|
6
|
-
import type
|
|
6
|
+
import { type FileType } from "./model.js";
|
|
7
7
|
export declare const DEFAULT_OUTPUT_KEY = "message";
|
|
8
8
|
export declare const DEFAULT_OUTPUT_FILE_KEY = "files";
|
|
9
9
|
/**
|
|
@@ -42,6 +42,12 @@ export interface AIAgentOptions<I extends Message = Message, O extends Message =
|
|
|
42
42
|
* @default AIAgentToolChoice.auto
|
|
43
43
|
*/
|
|
44
44
|
toolChoice?: AIAgentToolChoice | Agent;
|
|
45
|
+
/**
|
|
46
|
+
* Maximum number of tool calls to execute concurrently
|
|
47
|
+
*
|
|
48
|
+
* @default 1
|
|
49
|
+
*/
|
|
50
|
+
toolCallsConcurrency?: number;
|
|
45
51
|
/**
|
|
46
52
|
* Whether to preserve text generated during tool usage in the final output
|
|
47
53
|
*/
|
|
@@ -237,6 +243,12 @@ export declare class AIAgent<I extends Message = any, O extends Message = any> e
|
|
|
237
243
|
* {@includeCode ../../test/agents/ai-agent.test.ts#example-ai-agent-router}
|
|
238
244
|
*/
|
|
239
245
|
toolChoice?: AIAgentToolChoice | Agent;
|
|
246
|
+
/**
|
|
247
|
+
* Maximum number of tool calls to execute concurrently
|
|
248
|
+
*
|
|
249
|
+
* @default 1
|
|
250
|
+
*/
|
|
251
|
+
toolCallsConcurrency?: number;
|
|
240
252
|
/**
|
|
241
253
|
* Whether to preserve text generated during tool usage in the final output
|
|
242
254
|
*/
|
|
@@ -299,6 +311,7 @@ export declare class AIAgent<I extends Message = any, O extends Message = any> e
|
|
|
299
311
|
metadataEnd: string;
|
|
300
312
|
parse: (raw: string) => object;
|
|
301
313
|
};
|
|
314
|
+
get inputSchema(): ZodType<I>;
|
|
302
315
|
/**
|
|
303
316
|
* Process an input message and generate a response
|
|
304
317
|
*
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.AIAgent = exports.aiAgentOptionsSchema = exports.aiAgentToolChoiceSchema = exports.AIAgentToolChoice = exports.DEFAULT_OUTPUT_FILE_KEY = exports.DEFAULT_OUTPUT_KEY = void 0;
|
|
7
|
+
const fastq_1 = __importDefault(require("fastq"));
|
|
4
8
|
const zod_1 = require("zod");
|
|
5
9
|
const prompt_builder_js_1 = require("../prompt/prompt-builder.js");
|
|
6
10
|
const structured_stream_instructions_js_1 = require("../prompt/prompts/structured-stream-instructions.js");
|
|
@@ -8,6 +12,7 @@ const template_js_1 = require("../prompt/template.js");
|
|
|
8
12
|
const structured_stream_extractor_js_1 = require("../utils/structured-stream-extractor.js");
|
|
9
13
|
const type_utils_js_1 = require("../utils/type-utils.js");
|
|
10
14
|
const agent_js_1 = require("./agent.js");
|
|
15
|
+
const model_js_1 = require("./model.js");
|
|
11
16
|
const types_js_1 = require("./types.js");
|
|
12
17
|
exports.DEFAULT_OUTPUT_KEY = "message";
|
|
13
18
|
exports.DEFAULT_OUTPUT_FILE_KEY = "files";
|
|
@@ -58,6 +63,7 @@ exports.aiAgentOptionsSchema = agent_js_1.agentOptionsSchema.extend({
|
|
|
58
63
|
inputKey: zod_1.z.string().optional(),
|
|
59
64
|
outputKey: zod_1.z.string().optional(),
|
|
60
65
|
toolChoice: exports.aiAgentToolChoiceSchema.optional(),
|
|
66
|
+
toolCallsConcurrency: zod_1.z.number().int().min(0).optional(),
|
|
61
67
|
keepTextInToolUses: zod_1.z.boolean().optional(),
|
|
62
68
|
memoryAgentsAsTools: zod_1.z.boolean().optional(),
|
|
63
69
|
memoryPromptTemplate: zod_1.z.string().optional(),
|
|
@@ -117,6 +123,7 @@ class AIAgent extends agent_js_1.Agent {
|
|
|
117
123
|
this.outputFileKey = options.outputFileKey || exports.DEFAULT_OUTPUT_FILE_KEY;
|
|
118
124
|
this.outputFileType = options.outputFileType;
|
|
119
125
|
this.toolChoice = options.toolChoice;
|
|
126
|
+
this.toolCallsConcurrency = options.toolCallsConcurrency || 1;
|
|
120
127
|
this.keepTextInToolUses = options.keepTextInToolUses;
|
|
121
128
|
this.memoryAgentsAsTools = options.memoryAgentsAsTools;
|
|
122
129
|
this.memoryPromptTemplate = options.memoryPromptTemplate;
|
|
@@ -173,6 +180,12 @@ class AIAgent extends agent_js_1.Agent {
|
|
|
173
180
|
* {@includeCode ../../test/agents/ai-agent.test.ts#example-ai-agent-router}
|
|
174
181
|
*/
|
|
175
182
|
toolChoice;
|
|
183
|
+
/**
|
|
184
|
+
* Maximum number of tool calls to execute concurrently
|
|
185
|
+
*
|
|
186
|
+
* @default 1
|
|
187
|
+
*/
|
|
188
|
+
toolCallsConcurrency;
|
|
176
189
|
/**
|
|
177
190
|
* Whether to preserve text generated during tool usage in the final output
|
|
178
191
|
*/
|
|
@@ -230,6 +243,20 @@ class AIAgent extends agent_js_1.Agent {
|
|
|
230
243
|
* which outputs structured data in YAML format within <metadata> tags.
|
|
231
244
|
*/
|
|
232
245
|
customStructuredStreamInstructions;
|
|
246
|
+
get inputSchema() {
|
|
247
|
+
let schema = super.inputSchema;
|
|
248
|
+
if (this.inputKey) {
|
|
249
|
+
schema = schema.extend({
|
|
250
|
+
[this.inputKey]: zod_1.z.string().nullish(),
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
if (this.inputFileKey) {
|
|
254
|
+
schema = schema.extend({
|
|
255
|
+
[this.inputFileKey]: model_js_1.fileUnionContentsSchema.nullish(),
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
return schema;
|
|
259
|
+
}
|
|
233
260
|
/**
|
|
234
261
|
* Process an input message and generate a response
|
|
235
262
|
*
|
|
@@ -287,31 +314,43 @@ class AIAgent extends agent_js_1.Agent {
|
|
|
287
314
|
yield { delta: { text: { [outputKey]: "\n" } } };
|
|
288
315
|
}
|
|
289
316
|
const executedToolCalls = [];
|
|
317
|
+
let error;
|
|
318
|
+
const queue = fastq_1.default.promise(async ({ tool, call }) => {
|
|
319
|
+
try {
|
|
320
|
+
// NOTE: should pass both arguments (model generated) and input (user provided) to the tool
|
|
321
|
+
const output = await this.invokeSkill(tool, { ...input, ...call.function.arguments }, options).catch((error) => {
|
|
322
|
+
if (!this.catchToolsError) {
|
|
323
|
+
return Promise.reject(error);
|
|
324
|
+
}
|
|
325
|
+
return {
|
|
326
|
+
isError: true,
|
|
327
|
+
error: {
|
|
328
|
+
message: error.message,
|
|
329
|
+
},
|
|
330
|
+
};
|
|
331
|
+
});
|
|
332
|
+
executedToolCalls.push({ call, output });
|
|
333
|
+
}
|
|
334
|
+
catch (e) {
|
|
335
|
+
error = e;
|
|
336
|
+
queue.killAndDrain();
|
|
337
|
+
}
|
|
338
|
+
}, this.toolCallsConcurrency || 1);
|
|
290
339
|
// Execute tools
|
|
291
340
|
for (const call of toolCalls) {
|
|
292
341
|
const tool = toolsMap.get(call.function.name);
|
|
293
342
|
if (!tool)
|
|
294
343
|
throw new Error(`Tool not found: ${call.function.name}`);
|
|
295
|
-
|
|
296
|
-
const output = await this.invokeSkill(tool, { ...input, ...call.function.arguments }, options).catch((error) => {
|
|
297
|
-
if (!this.catchToolsError) {
|
|
298
|
-
return Promise.reject(error);
|
|
299
|
-
}
|
|
300
|
-
return {
|
|
301
|
-
isError: true,
|
|
302
|
-
error: {
|
|
303
|
-
message: error.message,
|
|
304
|
-
},
|
|
305
|
-
};
|
|
306
|
-
});
|
|
307
|
-
// NOTE: Return transfer output immediately
|
|
308
|
-
if ((0, types_js_1.isTransferAgentOutput)(output)) {
|
|
309
|
-
return output;
|
|
310
|
-
}
|
|
311
|
-
executedToolCalls.push({ call, output });
|
|
344
|
+
queue.push({ tool, call });
|
|
312
345
|
}
|
|
346
|
+
await queue.drained();
|
|
347
|
+
if (error)
|
|
348
|
+
throw error;
|
|
313
349
|
// Continue LLM function calling loop if any tools were executed
|
|
314
350
|
if (executedToolCalls.length) {
|
|
351
|
+
const transferOutput = executedToolCalls.find((i) => (0, types_js_1.isTransferAgentOutput)(i.output))?.output;
|
|
352
|
+
if (transferOutput)
|
|
353
|
+
return transferOutput;
|
|
315
354
|
toolCallMessages.push(await template_js_1.AgentMessageTemplate.from(undefined, executedToolCalls.map(({ call }) => call)).format(), ...(await Promise.all(executedToolCalls.map(({ call, output }) => template_js_1.ToolMessageTemplate.from(output, call.id).format()))));
|
|
316
355
|
continue;
|
|
317
356
|
}
|
|
@@ -46,8 +46,10 @@ export interface AIAgentSchema extends BaseAgentSchema {
|
|
|
46
46
|
type: "ai";
|
|
47
47
|
instructions?: Instructions;
|
|
48
48
|
inputKey?: string;
|
|
49
|
+
inputFileKey?: string;
|
|
49
50
|
outputKey?: string;
|
|
50
51
|
toolChoice?: AIAgentToolChoice;
|
|
52
|
+
toolCallsConcurrency?: number;
|
|
51
53
|
keepTextInToolUses?: boolean;
|
|
52
54
|
}
|
|
53
55
|
export interface ImageAgentSchema extends BaseAgentSchema {
|
|
@@ -95,7 +95,10 @@ async function parseAgentFile(path, data) {
|
|
|
95
95
|
instructions: (0, schema_js_1.optionalize)(instructionsSchema),
|
|
96
96
|
inputKey: (0, schema_js_1.optionalize)(zod_1.z.string()),
|
|
97
97
|
outputKey: (0, schema_js_1.optionalize)(zod_1.z.string()),
|
|
98
|
+
inputFileKey: (0, schema_js_1.optionalize)(zod_1.z.string()),
|
|
99
|
+
outputFileKey: (0, schema_js_1.optionalize)(zod_1.z.string()),
|
|
98
100
|
toolChoice: (0, schema_js_1.optionalize)(zod_1.z.nativeEnum(ai_agent_js_1.AIAgentToolChoice)),
|
|
101
|
+
toolCallsConcurrency: (0, schema_js_1.optionalize)(zod_1.z.number().int().min(0)),
|
|
99
102
|
keepTextInToolUses: (0, schema_js_1.optionalize)(zod_1.z.boolean()),
|
|
100
103
|
structuredStreamMode: (0, schema_js_1.optionalize)(zod_1.z.boolean()),
|
|
101
104
|
})
|
|
@@ -3,7 +3,7 @@ import { PromptBuilder } from "../prompt/prompt-builder.js";
|
|
|
3
3
|
import { Agent, type AgentInvokeOptions, type AgentOptions, type AgentProcessAsyncGenerator, type AgentProcessResult, type Message } from "./agent.js";
|
|
4
4
|
import type { ChatModel, ChatModelInput } from "./chat-model.js";
|
|
5
5
|
import type { GuideRailAgentOutput } from "./guide-rail-agent.js";
|
|
6
|
-
import type
|
|
6
|
+
import { type FileType } from "./model.js";
|
|
7
7
|
export declare const DEFAULT_OUTPUT_KEY = "message";
|
|
8
8
|
export declare const DEFAULT_OUTPUT_FILE_KEY = "files";
|
|
9
9
|
/**
|
|
@@ -42,6 +42,12 @@ export interface AIAgentOptions<I extends Message = Message, O extends Message =
|
|
|
42
42
|
* @default AIAgentToolChoice.auto
|
|
43
43
|
*/
|
|
44
44
|
toolChoice?: AIAgentToolChoice | Agent;
|
|
45
|
+
/**
|
|
46
|
+
* Maximum number of tool calls to execute concurrently
|
|
47
|
+
*
|
|
48
|
+
* @default 1
|
|
49
|
+
*/
|
|
50
|
+
toolCallsConcurrency?: number;
|
|
45
51
|
/**
|
|
46
52
|
* Whether to preserve text generated during tool usage in the final output
|
|
47
53
|
*/
|
|
@@ -237,6 +243,12 @@ export declare class AIAgent<I extends Message = any, O extends Message = any> e
|
|
|
237
243
|
* {@includeCode ../../test/agents/ai-agent.test.ts#example-ai-agent-router}
|
|
238
244
|
*/
|
|
239
245
|
toolChoice?: AIAgentToolChoice | Agent;
|
|
246
|
+
/**
|
|
247
|
+
* Maximum number of tool calls to execute concurrently
|
|
248
|
+
*
|
|
249
|
+
* @default 1
|
|
250
|
+
*/
|
|
251
|
+
toolCallsConcurrency?: number;
|
|
240
252
|
/**
|
|
241
253
|
* Whether to preserve text generated during tool usage in the final output
|
|
242
254
|
*/
|
|
@@ -299,6 +311,7 @@ export declare class AIAgent<I extends Message = any, O extends Message = any> e
|
|
|
299
311
|
metadataEnd: string;
|
|
300
312
|
parse: (raw: string) => object;
|
|
301
313
|
};
|
|
314
|
+
get inputSchema(): ZodType<I>;
|
|
302
315
|
/**
|
|
303
316
|
* Process an input message and generate a response
|
|
304
317
|
*
|
|
@@ -46,8 +46,10 @@ export interface AIAgentSchema extends BaseAgentSchema {
|
|
|
46
46
|
type: "ai";
|
|
47
47
|
instructions?: Instructions;
|
|
48
48
|
inputKey?: string;
|
|
49
|
+
inputFileKey?: string;
|
|
49
50
|
outputKey?: string;
|
|
50
51
|
toolChoice?: AIAgentToolChoice;
|
|
52
|
+
toolCallsConcurrency?: number;
|
|
51
53
|
keepTextInToolUses?: boolean;
|
|
52
54
|
}
|
|
53
55
|
export interface ImageAgentSchema extends BaseAgentSchema {
|
|
@@ -3,7 +3,7 @@ import { PromptBuilder } from "../prompt/prompt-builder.js";
|
|
|
3
3
|
import { Agent, type AgentInvokeOptions, type AgentOptions, type AgentProcessAsyncGenerator, type AgentProcessResult, type Message } from "./agent.js";
|
|
4
4
|
import type { ChatModel, ChatModelInput } from "./chat-model.js";
|
|
5
5
|
import type { GuideRailAgentOutput } from "./guide-rail-agent.js";
|
|
6
|
-
import type
|
|
6
|
+
import { type FileType } from "./model.js";
|
|
7
7
|
export declare const DEFAULT_OUTPUT_KEY = "message";
|
|
8
8
|
export declare const DEFAULT_OUTPUT_FILE_KEY = "files";
|
|
9
9
|
/**
|
|
@@ -42,6 +42,12 @@ export interface AIAgentOptions<I extends Message = Message, O extends Message =
|
|
|
42
42
|
* @default AIAgentToolChoice.auto
|
|
43
43
|
*/
|
|
44
44
|
toolChoice?: AIAgentToolChoice | Agent;
|
|
45
|
+
/**
|
|
46
|
+
* Maximum number of tool calls to execute concurrently
|
|
47
|
+
*
|
|
48
|
+
* @default 1
|
|
49
|
+
*/
|
|
50
|
+
toolCallsConcurrency?: number;
|
|
45
51
|
/**
|
|
46
52
|
* Whether to preserve text generated during tool usage in the final output
|
|
47
53
|
*/
|
|
@@ -237,6 +243,12 @@ export declare class AIAgent<I extends Message = any, O extends Message = any> e
|
|
|
237
243
|
* {@includeCode ../../test/agents/ai-agent.test.ts#example-ai-agent-router}
|
|
238
244
|
*/
|
|
239
245
|
toolChoice?: AIAgentToolChoice | Agent;
|
|
246
|
+
/**
|
|
247
|
+
* Maximum number of tool calls to execute concurrently
|
|
248
|
+
*
|
|
249
|
+
* @default 1
|
|
250
|
+
*/
|
|
251
|
+
toolCallsConcurrency?: number;
|
|
240
252
|
/**
|
|
241
253
|
* Whether to preserve text generated during tool usage in the final output
|
|
242
254
|
*/
|
|
@@ -299,6 +311,7 @@ export declare class AIAgent<I extends Message = any, O extends Message = any> e
|
|
|
299
311
|
metadataEnd: string;
|
|
300
312
|
parse: (raw: string) => object;
|
|
301
313
|
};
|
|
314
|
+
get inputSchema(): ZodType<I>;
|
|
302
315
|
/**
|
|
303
316
|
* Process an input message and generate a response
|
|
304
317
|
*
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import fastq from "fastq";
|
|
1
2
|
import { z } from "zod";
|
|
2
3
|
import { PromptBuilder } from "../prompt/prompt-builder.js";
|
|
3
4
|
import { STRUCTURED_STREAM_INSTRUCTIONS } from "../prompt/prompts/structured-stream-instructions.js";
|
|
@@ -5,6 +6,7 @@ import { AgentMessageTemplate, ToolMessageTemplate } from "../prompt/template.js
|
|
|
5
6
|
import { ExtractMetadataTransform } from "../utils/structured-stream-extractor.js";
|
|
6
7
|
import { checkArguments, isEmpty } from "../utils/type-utils.js";
|
|
7
8
|
import { Agent, agentOptionsSchema, isAgentResponseDelta, } from "./agent.js";
|
|
9
|
+
import { fileUnionContentsSchema } from "./model.js";
|
|
8
10
|
import { isTransferAgentOutput } from "./types.js";
|
|
9
11
|
export const DEFAULT_OUTPUT_KEY = "message";
|
|
10
12
|
export const DEFAULT_OUTPUT_FILE_KEY = "files";
|
|
@@ -55,6 +57,7 @@ export const aiAgentOptionsSchema = agentOptionsSchema.extend({
|
|
|
55
57
|
inputKey: z.string().optional(),
|
|
56
58
|
outputKey: z.string().optional(),
|
|
57
59
|
toolChoice: aiAgentToolChoiceSchema.optional(),
|
|
60
|
+
toolCallsConcurrency: z.number().int().min(0).optional(),
|
|
58
61
|
keepTextInToolUses: z.boolean().optional(),
|
|
59
62
|
memoryAgentsAsTools: z.boolean().optional(),
|
|
60
63
|
memoryPromptTemplate: z.string().optional(),
|
|
@@ -114,6 +117,7 @@ export class AIAgent extends Agent {
|
|
|
114
117
|
this.outputFileKey = options.outputFileKey || DEFAULT_OUTPUT_FILE_KEY;
|
|
115
118
|
this.outputFileType = options.outputFileType;
|
|
116
119
|
this.toolChoice = options.toolChoice;
|
|
120
|
+
this.toolCallsConcurrency = options.toolCallsConcurrency || 1;
|
|
117
121
|
this.keepTextInToolUses = options.keepTextInToolUses;
|
|
118
122
|
this.memoryAgentsAsTools = options.memoryAgentsAsTools;
|
|
119
123
|
this.memoryPromptTemplate = options.memoryPromptTemplate;
|
|
@@ -170,6 +174,12 @@ export class AIAgent extends Agent {
|
|
|
170
174
|
* {@includeCode ../../test/agents/ai-agent.test.ts#example-ai-agent-router}
|
|
171
175
|
*/
|
|
172
176
|
toolChoice;
|
|
177
|
+
/**
|
|
178
|
+
* Maximum number of tool calls to execute concurrently
|
|
179
|
+
*
|
|
180
|
+
* @default 1
|
|
181
|
+
*/
|
|
182
|
+
toolCallsConcurrency;
|
|
173
183
|
/**
|
|
174
184
|
* Whether to preserve text generated during tool usage in the final output
|
|
175
185
|
*/
|
|
@@ -227,6 +237,20 @@ export class AIAgent extends Agent {
|
|
|
227
237
|
* which outputs structured data in YAML format within <metadata> tags.
|
|
228
238
|
*/
|
|
229
239
|
customStructuredStreamInstructions;
|
|
240
|
+
get inputSchema() {
|
|
241
|
+
let schema = super.inputSchema;
|
|
242
|
+
if (this.inputKey) {
|
|
243
|
+
schema = schema.extend({
|
|
244
|
+
[this.inputKey]: z.string().nullish(),
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
if (this.inputFileKey) {
|
|
248
|
+
schema = schema.extend({
|
|
249
|
+
[this.inputFileKey]: fileUnionContentsSchema.nullish(),
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
return schema;
|
|
253
|
+
}
|
|
230
254
|
/**
|
|
231
255
|
* Process an input message and generate a response
|
|
232
256
|
*
|
|
@@ -284,31 +308,43 @@ export class AIAgent extends Agent {
|
|
|
284
308
|
yield { delta: { text: { [outputKey]: "\n" } } };
|
|
285
309
|
}
|
|
286
310
|
const executedToolCalls = [];
|
|
311
|
+
let error;
|
|
312
|
+
const queue = fastq.promise(async ({ tool, call }) => {
|
|
313
|
+
try {
|
|
314
|
+
// NOTE: should pass both arguments (model generated) and input (user provided) to the tool
|
|
315
|
+
const output = await this.invokeSkill(tool, { ...input, ...call.function.arguments }, options).catch((error) => {
|
|
316
|
+
if (!this.catchToolsError) {
|
|
317
|
+
return Promise.reject(error);
|
|
318
|
+
}
|
|
319
|
+
return {
|
|
320
|
+
isError: true,
|
|
321
|
+
error: {
|
|
322
|
+
message: error.message,
|
|
323
|
+
},
|
|
324
|
+
};
|
|
325
|
+
});
|
|
326
|
+
executedToolCalls.push({ call, output });
|
|
327
|
+
}
|
|
328
|
+
catch (e) {
|
|
329
|
+
error = e;
|
|
330
|
+
queue.killAndDrain();
|
|
331
|
+
}
|
|
332
|
+
}, this.toolCallsConcurrency || 1);
|
|
287
333
|
// Execute tools
|
|
288
334
|
for (const call of toolCalls) {
|
|
289
335
|
const tool = toolsMap.get(call.function.name);
|
|
290
336
|
if (!tool)
|
|
291
337
|
throw new Error(`Tool not found: ${call.function.name}`);
|
|
292
|
-
|
|
293
|
-
const output = await this.invokeSkill(tool, { ...input, ...call.function.arguments }, options).catch((error) => {
|
|
294
|
-
if (!this.catchToolsError) {
|
|
295
|
-
return Promise.reject(error);
|
|
296
|
-
}
|
|
297
|
-
return {
|
|
298
|
-
isError: true,
|
|
299
|
-
error: {
|
|
300
|
-
message: error.message,
|
|
301
|
-
},
|
|
302
|
-
};
|
|
303
|
-
});
|
|
304
|
-
// NOTE: Return transfer output immediately
|
|
305
|
-
if (isTransferAgentOutput(output)) {
|
|
306
|
-
return output;
|
|
307
|
-
}
|
|
308
|
-
executedToolCalls.push({ call, output });
|
|
338
|
+
queue.push({ tool, call });
|
|
309
339
|
}
|
|
340
|
+
await queue.drained();
|
|
341
|
+
if (error)
|
|
342
|
+
throw error;
|
|
310
343
|
// Continue LLM function calling loop if any tools were executed
|
|
311
344
|
if (executedToolCalls.length) {
|
|
345
|
+
const transferOutput = executedToolCalls.find((i) => isTransferAgentOutput(i.output))?.output;
|
|
346
|
+
if (transferOutput)
|
|
347
|
+
return transferOutput;
|
|
312
348
|
toolCallMessages.push(await AgentMessageTemplate.from(undefined, executedToolCalls.map(({ call }) => call)).format(), ...(await Promise.all(executedToolCalls.map(({ call, output }) => ToolMessageTemplate.from(output, call.id).format()))));
|
|
313
349
|
continue;
|
|
314
350
|
}
|
|
@@ -46,8 +46,10 @@ export interface AIAgentSchema extends BaseAgentSchema {
|
|
|
46
46
|
type: "ai";
|
|
47
47
|
instructions?: Instructions;
|
|
48
48
|
inputKey?: string;
|
|
49
|
+
inputFileKey?: string;
|
|
49
50
|
outputKey?: string;
|
|
50
51
|
toolChoice?: AIAgentToolChoice;
|
|
52
|
+
toolCallsConcurrency?: number;
|
|
51
53
|
keepTextInToolUses?: boolean;
|
|
52
54
|
}
|
|
53
55
|
export interface ImageAgentSchema extends BaseAgentSchema {
|
|
@@ -91,7 +91,10 @@ export async function parseAgentFile(path, data) {
|
|
|
91
91
|
instructions: optionalize(instructionsSchema),
|
|
92
92
|
inputKey: optionalize(z.string()),
|
|
93
93
|
outputKey: optionalize(z.string()),
|
|
94
|
+
inputFileKey: optionalize(z.string()),
|
|
95
|
+
outputFileKey: optionalize(z.string()),
|
|
94
96
|
toolChoice: optionalize(z.nativeEnum(AIAgentToolChoice)),
|
|
97
|
+
toolCallsConcurrency: optionalize(z.number().int().min(0)),
|
|
95
98
|
keepTextInToolUses: optionalize(z.boolean()),
|
|
96
99
|
structuredStreamMode: optionalize(z.boolean()),
|
|
97
100
|
})
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aigne/core",
|
|
3
|
-
"version": "1.63.0-beta",
|
|
3
|
+
"version": "1.63.0-beta.2",
|
|
4
4
|
"description": "The functional core of agentic AI",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -92,9 +92,9 @@
|
|
|
92
92
|
"zod": "^3.25.67",
|
|
93
93
|
"zod-from-json-schema": "^0.0.5",
|
|
94
94
|
"zod-to-json-schema": "^3.24.6",
|
|
95
|
-
"@aigne/
|
|
95
|
+
"@aigne/afs": "^1.0.0",
|
|
96
96
|
"@aigne/platform-helpers": "^0.6.3",
|
|
97
|
-
"@aigne/
|
|
97
|
+
"@aigne/observability-api": "^0.11.2-beta"
|
|
98
98
|
},
|
|
99
99
|
"devDependencies": {
|
|
100
100
|
"@types/bun": "^1.2.22",
|