@aigne/core 1.62.0 → 1.63.0-beta.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 +27 -0
- package/lib/cjs/agents/agent.d.ts +5 -0
- package/lib/cjs/agents/agent.js +14 -0
- package/lib/cjs/agents/ai-agent.d.ts +15 -2
- package/lib/cjs/agents/ai-agent.js +45 -18
- package/lib/cjs/loader/agent-yaml.d.ts +2 -0
- package/lib/cjs/loader/agent-yaml.js +3 -0
- package/lib/cjs/prompt/prompt-builder.js +13 -0
- package/lib/cjs/utils/agent-utils.d.ts +2 -2
- package/lib/dts/agents/agent.d.ts +5 -0
- package/lib/dts/agents/ai-agent.d.ts +15 -2
- package/lib/dts/loader/agent-yaml.d.ts +2 -0
- package/lib/dts/utils/agent-utils.d.ts +2 -2
- package/lib/esm/agents/agent.d.ts +5 -0
- package/lib/esm/agents/agent.js +14 -0
- package/lib/esm/agents/ai-agent.d.ts +15 -2
- package/lib/esm/agents/ai-agent.js +42 -18
- package/lib/esm/loader/agent-yaml.d.ts +2 -0
- package/lib/esm/loader/agent-yaml.js +3 -0
- package/lib/esm/prompt/prompt-builder.js +14 -1
- package/lib/esm/utils/agent-utils.d.ts +2 -2
- package/package.json +3 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,32 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [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)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* **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))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* **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))
|
|
14
|
+
|
|
15
|
+
## [1.63.0-beta](https://github.com/AIGNE-io/aigne-framework/compare/core-v1.62.0...core-v1.63.0-beta) (2025-10-07)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Features
|
|
19
|
+
|
|
20
|
+
* **afs:** add basic AFS(AIGNE File System) support ([#505](https://github.com/AIGNE-io/aigne-framework/issues/505)) ([ac2a18a](https://github.com/AIGNE-io/aigne-framework/commit/ac2a18a82470a2f31c466f329386525eb1cdab6d))
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
### Dependencies
|
|
24
|
+
|
|
25
|
+
* The following workspace dependencies were updated
|
|
26
|
+
* dependencies
|
|
27
|
+
* @aigne/afs bumped to 1.0.0
|
|
28
|
+
* @aigne/observability-api bumped to 0.11.2-beta
|
|
29
|
+
|
|
3
30
|
## [1.62.0](https://github.com/AIGNE-io/aigne-framework/compare/core-v1.62.0-beta.6...core-v1.62.0) (2025-10-04)
|
|
4
31
|
|
|
5
32
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { AFS, type AFSOptions } from "@aigne/afs";
|
|
1
2
|
import { nodejs } from "@aigne/platform-helpers/nodejs/index.js";
|
|
2
3
|
import type * as prompts from "@inquirer/prompts";
|
|
3
4
|
import { type ZodObject, type ZodType } from "zod";
|
|
@@ -120,6 +121,7 @@ export interface AgentOptions<I extends Message = Message, O extends Message = M
|
|
|
120
121
|
* One or more memory agents this agent can use
|
|
121
122
|
*/
|
|
122
123
|
memory?: MemoryAgent | MemoryAgent[];
|
|
124
|
+
afs?: true | AFSOptions | AFS | ((afs: AFS) => AFS);
|
|
123
125
|
asyncMemoryRecord?: boolean;
|
|
124
126
|
/**
|
|
125
127
|
* Maximum number of memory items to retrieve
|
|
@@ -205,8 +207,11 @@ export declare abstract class Agent<I extends Message = any, O extends Message =
|
|
|
205
207
|
constructor(options?: AgentOptions<I, O>);
|
|
206
208
|
/**
|
|
207
209
|
* List of memories this agent can use
|
|
210
|
+
*
|
|
211
|
+
* @deprecated use afs instead
|
|
208
212
|
*/
|
|
209
213
|
readonly memories: MemoryAgent[];
|
|
214
|
+
afs?: AFS;
|
|
210
215
|
asyncMemoryRecord?: boolean;
|
|
211
216
|
tag?: string;
|
|
212
217
|
/**
|
package/lib/cjs/agents/agent.js
CHANGED
|
@@ -46,6 +46,7 @@ exports.isAgentResponseProgress = isAgentResponseProgress;
|
|
|
46
46
|
exports.textDelta = textDelta;
|
|
47
47
|
exports.jsonDelta = jsonDelta;
|
|
48
48
|
exports.agentProcessResultToObject = agentProcessResultToObject;
|
|
49
|
+
const afs_1 = require("@aigne/afs");
|
|
49
50
|
const index_js_1 = require("@aigne/platform-helpers/nodejs/index.js");
|
|
50
51
|
const fast_deep_equal_1 = __importDefault(require("fast-deep-equal"));
|
|
51
52
|
const nunjucks_1 = __importDefault(require("nunjucks"));
|
|
@@ -151,6 +152,15 @@ class Agent {
|
|
|
151
152
|
else if (options.memory) {
|
|
152
153
|
this.memories.push(options.memory);
|
|
153
154
|
}
|
|
155
|
+
this.afs = !options.afs
|
|
156
|
+
? undefined
|
|
157
|
+
: options.afs === true
|
|
158
|
+
? new afs_1.AFS()
|
|
159
|
+
: typeof options.afs === "function"
|
|
160
|
+
? options.afs(new afs_1.AFS())
|
|
161
|
+
: options.afs instanceof afs_1.AFS
|
|
162
|
+
? options.afs
|
|
163
|
+
: new afs_1.AFS(options.afs);
|
|
154
164
|
this.asyncMemoryRecord = options.asyncMemoryRecord;
|
|
155
165
|
this.maxRetrieveMemoryCount = options.maxRetrieveMemoryCount;
|
|
156
166
|
this.hooks = (0, type_utils_js_1.flat)(options.hooks);
|
|
@@ -164,8 +174,11 @@ class Agent {
|
|
|
164
174
|
}
|
|
165
175
|
/**
|
|
166
176
|
* List of memories this agent can use
|
|
177
|
+
*
|
|
178
|
+
* @deprecated use afs instead
|
|
167
179
|
*/
|
|
168
180
|
memories = [];
|
|
181
|
+
afs;
|
|
169
182
|
asyncMemoryRecord;
|
|
170
183
|
tag;
|
|
171
184
|
/**
|
|
@@ -537,6 +550,7 @@ class Agent {
|
|
|
537
550
|
const o = await this.callHooks(["onSuccess", "onEnd"], { input, output: finalOutput }, options);
|
|
538
551
|
if (o?.output)
|
|
539
552
|
finalOutput = o.output;
|
|
553
|
+
this.afs?.emit("agentSucceed", { input, output: finalOutput });
|
|
540
554
|
if (!this.disableEvents)
|
|
541
555
|
context.emit("agentSucceed", { agent: this, output: finalOutput });
|
|
542
556
|
return finalOutput;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type ZodObject, type ZodType, z } from "zod";
|
|
2
2
|
import { PromptBuilder } from "../prompt/prompt-builder.js";
|
|
3
|
-
import { Agent, type AgentInvokeOptions, type AgentOptions, type AgentProcessAsyncGenerator, type Message } from "./agent.js";
|
|
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
6
|
import type { FileType } from "./model.js";
|
|
@@ -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
|
*/
|
|
@@ -304,7 +316,8 @@ export declare class AIAgent<I extends Message = any, O extends Message = any> e
|
|
|
304
316
|
*
|
|
305
317
|
* @protected
|
|
306
318
|
*/
|
|
307
|
-
process(input: I, options: AgentInvokeOptions):
|
|
319
|
+
process(input: I, options: AgentInvokeOptions): AgentProcessResult<O>;
|
|
320
|
+
private _process;
|
|
308
321
|
protected onGuideRailError(error: GuideRailAgentOutput): Promise<O | GuideRailAgentOutput>;
|
|
309
322
|
/**
|
|
310
323
|
* Process router mode requests
|
|
@@ -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");
|
|
@@ -58,6 +62,7 @@ exports.aiAgentOptionsSchema = agent_js_1.agentOptionsSchema.extend({
|
|
|
58
62
|
inputKey: zod_1.z.string().optional(),
|
|
59
63
|
outputKey: zod_1.z.string().optional(),
|
|
60
64
|
toolChoice: exports.aiAgentToolChoiceSchema.optional(),
|
|
65
|
+
toolCallsConcurrency: zod_1.z.number().int().min(0).optional(),
|
|
61
66
|
keepTextInToolUses: zod_1.z.boolean().optional(),
|
|
62
67
|
memoryAgentsAsTools: zod_1.z.boolean().optional(),
|
|
63
68
|
memoryPromptTemplate: zod_1.z.string().optional(),
|
|
@@ -117,6 +122,7 @@ class AIAgent extends agent_js_1.Agent {
|
|
|
117
122
|
this.outputFileKey = options.outputFileKey || exports.DEFAULT_OUTPUT_FILE_KEY;
|
|
118
123
|
this.outputFileType = options.outputFileType;
|
|
119
124
|
this.toolChoice = options.toolChoice;
|
|
125
|
+
this.toolCallsConcurrency = options.toolCallsConcurrency || 1;
|
|
120
126
|
this.keepTextInToolUses = options.keepTextInToolUses;
|
|
121
127
|
this.memoryAgentsAsTools = options.memoryAgentsAsTools;
|
|
122
128
|
this.memoryPromptTemplate = options.memoryPromptTemplate;
|
|
@@ -173,6 +179,12 @@ class AIAgent extends agent_js_1.Agent {
|
|
|
173
179
|
* {@includeCode ../../test/agents/ai-agent.test.ts#example-ai-agent-router}
|
|
174
180
|
*/
|
|
175
181
|
toolChoice;
|
|
182
|
+
/**
|
|
183
|
+
* Maximum number of tool calls to execute concurrently
|
|
184
|
+
*
|
|
185
|
+
* @default 1
|
|
186
|
+
*/
|
|
187
|
+
toolCallsConcurrency;
|
|
176
188
|
/**
|
|
177
189
|
* Whether to preserve text generated during tool usage in the final output
|
|
178
190
|
*/
|
|
@@ -235,7 +247,10 @@ class AIAgent extends agent_js_1.Agent {
|
|
|
235
247
|
*
|
|
236
248
|
* @protected
|
|
237
249
|
*/
|
|
238
|
-
|
|
250
|
+
process(input, options) {
|
|
251
|
+
return this._process(input, options);
|
|
252
|
+
}
|
|
253
|
+
async *_process(input, options) {
|
|
239
254
|
const model = this.model || options.model || options.context.model;
|
|
240
255
|
if (!model)
|
|
241
256
|
throw new Error("model is required to run AIAgent");
|
|
@@ -284,31 +299,43 @@ class AIAgent extends agent_js_1.Agent {
|
|
|
284
299
|
yield { delta: { text: { [outputKey]: "\n" } } };
|
|
285
300
|
}
|
|
286
301
|
const executedToolCalls = [];
|
|
302
|
+
let error;
|
|
303
|
+
const queue = fastq_1.default.promise(async ({ tool, call }) => {
|
|
304
|
+
try {
|
|
305
|
+
// NOTE: should pass both arguments (model generated) and input (user provided) to the tool
|
|
306
|
+
const output = await this.invokeSkill(tool, { ...input, ...call.function.arguments }, options).catch((error) => {
|
|
307
|
+
if (!this.catchToolsError) {
|
|
308
|
+
return Promise.reject(error);
|
|
309
|
+
}
|
|
310
|
+
return {
|
|
311
|
+
isError: true,
|
|
312
|
+
error: {
|
|
313
|
+
message: error.message,
|
|
314
|
+
},
|
|
315
|
+
};
|
|
316
|
+
});
|
|
317
|
+
executedToolCalls.push({ call, output });
|
|
318
|
+
}
|
|
319
|
+
catch (e) {
|
|
320
|
+
error = e;
|
|
321
|
+
queue.killAndDrain();
|
|
322
|
+
}
|
|
323
|
+
}, this.toolCallsConcurrency || 1);
|
|
287
324
|
// Execute tools
|
|
288
325
|
for (const call of toolCalls) {
|
|
289
326
|
const tool = toolsMap.get(call.function.name);
|
|
290
327
|
if (!tool)
|
|
291
328
|
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 ((0, types_js_1.isTransferAgentOutput)(output)) {
|
|
306
|
-
return output;
|
|
307
|
-
}
|
|
308
|
-
executedToolCalls.push({ call, output });
|
|
329
|
+
queue.push({ tool, call });
|
|
309
330
|
}
|
|
331
|
+
await queue.drained();
|
|
332
|
+
if (error)
|
|
333
|
+
throw error;
|
|
310
334
|
// Continue LLM function calling loop if any tools were executed
|
|
311
335
|
if (executedToolCalls.length) {
|
|
336
|
+
const transferOutput = executedToolCalls.find((i) => (0, types_js_1.isTransferAgentOutput)(i.output))?.output;
|
|
337
|
+
if (transferOutput)
|
|
338
|
+
return transferOutput;
|
|
312
339
|
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()))));
|
|
313
340
|
continue;
|
|
314
341
|
}
|
|
@@ -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
|
})
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.PromptBuilder = void 0;
|
|
4
|
+
const afs_1 = require("@aigne/afs");
|
|
4
5
|
const index_js_1 = require("@aigne/platform-helpers/nodejs/index.js");
|
|
5
6
|
const yaml_1 = require("yaml");
|
|
6
7
|
const zod_1 = require("zod");
|
|
@@ -98,6 +99,18 @@ class PromptBuilder {
|
|
|
98
99
|
if (options.agent?.useMemoriesFromContext && options.context?.memories?.length) {
|
|
99
100
|
memories.push(...options.context.memories);
|
|
100
101
|
}
|
|
102
|
+
if (options.agent?.afs) {
|
|
103
|
+
const history = await options.agent.afs.list(afs_1.AFSHistory.Path, {
|
|
104
|
+
limit: options.agent.maxRetrieveMemoryCount || 1,
|
|
105
|
+
orderBy: [["createdAt", "desc"]],
|
|
106
|
+
});
|
|
107
|
+
if (message) {
|
|
108
|
+
const result = await options.agent.afs.search("/", message);
|
|
109
|
+
const ms = result.list.map((entry) => ({ content: (0, yaml_1.stringify)(entry.content) }));
|
|
110
|
+
memories.push(...ms);
|
|
111
|
+
}
|
|
112
|
+
memories.push(...history.list.filter((i) => (0, type_utils_js_1.isNonNullable)(i.content)));
|
|
113
|
+
}
|
|
101
114
|
if (memories.length)
|
|
102
115
|
messages.push(...(await this.convertMemoriesToMessages(memories, options)));
|
|
103
116
|
// if the agent is using structured stream mode, add the instructions
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AgentHooks } from "../agents/agent.
|
|
1
|
+
import type { AgentHooks } from "../agents/agent.js";
|
|
2
2
|
import type { AIGNECLIAgents } from "../aigne/type.js";
|
|
3
3
|
export declare function sortHooks(hooks: AgentHooks[]): AgentHooks[];
|
|
4
4
|
export interface CLIAgent<T> {
|
|
@@ -9,4 +9,4 @@ export interface CLIAgent<T> {
|
|
|
9
9
|
agents?: CLIAgent<T>[];
|
|
10
10
|
}
|
|
11
11
|
export declare function mapCliAgent<A, O>({ agent, agents, ...input }: CLIAgent<A>, transform: (input: A) => O): CLIAgent<O>;
|
|
12
|
-
export declare function findCliAgent(cli: AIGNECLIAgents, parent: string[] | "*", name: string): import("../agents/agent.
|
|
12
|
+
export declare function findCliAgent(cli: AIGNECLIAgents, parent: string[] | "*", name: string): import("../agents/agent.js").Agent<any, any> | undefined;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { AFS, type AFSOptions } from "@aigne/afs";
|
|
1
2
|
import { nodejs } from "@aigne/platform-helpers/nodejs/index.js";
|
|
2
3
|
import type * as prompts from "@inquirer/prompts";
|
|
3
4
|
import { type ZodObject, type ZodType } from "zod";
|
|
@@ -120,6 +121,7 @@ export interface AgentOptions<I extends Message = Message, O extends Message = M
|
|
|
120
121
|
* One or more memory agents this agent can use
|
|
121
122
|
*/
|
|
122
123
|
memory?: MemoryAgent | MemoryAgent[];
|
|
124
|
+
afs?: true | AFSOptions | AFS | ((afs: AFS) => AFS);
|
|
123
125
|
asyncMemoryRecord?: boolean;
|
|
124
126
|
/**
|
|
125
127
|
* Maximum number of memory items to retrieve
|
|
@@ -205,8 +207,11 @@ export declare abstract class Agent<I extends Message = any, O extends Message =
|
|
|
205
207
|
constructor(options?: AgentOptions<I, O>);
|
|
206
208
|
/**
|
|
207
209
|
* List of memories this agent can use
|
|
210
|
+
*
|
|
211
|
+
* @deprecated use afs instead
|
|
208
212
|
*/
|
|
209
213
|
readonly memories: MemoryAgent[];
|
|
214
|
+
afs?: AFS;
|
|
210
215
|
asyncMemoryRecord?: boolean;
|
|
211
216
|
tag?: string;
|
|
212
217
|
/**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type ZodObject, type ZodType, z } from "zod";
|
|
2
2
|
import { PromptBuilder } from "../prompt/prompt-builder.js";
|
|
3
|
-
import { Agent, type AgentInvokeOptions, type AgentOptions, type AgentProcessAsyncGenerator, type Message } from "./agent.js";
|
|
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
6
|
import type { FileType } from "./model.js";
|
|
@@ -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
|
*/
|
|
@@ -304,7 +316,8 @@ export declare class AIAgent<I extends Message = any, O extends Message = any> e
|
|
|
304
316
|
*
|
|
305
317
|
* @protected
|
|
306
318
|
*/
|
|
307
|
-
process(input: I, options: AgentInvokeOptions):
|
|
319
|
+
process(input: I, options: AgentInvokeOptions): AgentProcessResult<O>;
|
|
320
|
+
private _process;
|
|
308
321
|
protected onGuideRailError(error: GuideRailAgentOutput): Promise<O | GuideRailAgentOutput>;
|
|
309
322
|
/**
|
|
310
323
|
* Process router mode requests
|
|
@@ -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 {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AgentHooks } from "../agents/agent.
|
|
1
|
+
import type { AgentHooks } from "../agents/agent.js";
|
|
2
2
|
import type { AIGNECLIAgents } from "../aigne/type.js";
|
|
3
3
|
export declare function sortHooks(hooks: AgentHooks[]): AgentHooks[];
|
|
4
4
|
export interface CLIAgent<T> {
|
|
@@ -9,4 +9,4 @@ export interface CLIAgent<T> {
|
|
|
9
9
|
agents?: CLIAgent<T>[];
|
|
10
10
|
}
|
|
11
11
|
export declare function mapCliAgent<A, O>({ agent, agents, ...input }: CLIAgent<A>, transform: (input: A) => O): CLIAgent<O>;
|
|
12
|
-
export declare function findCliAgent(cli: AIGNECLIAgents, parent: string[] | "*", name: string): import("../agents/agent.
|
|
12
|
+
export declare function findCliAgent(cli: AIGNECLIAgents, parent: string[] | "*", name: string): import("../agents/agent.js").Agent<any, any> | undefined;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { AFS, type AFSOptions } from "@aigne/afs";
|
|
1
2
|
import { nodejs } from "@aigne/platform-helpers/nodejs/index.js";
|
|
2
3
|
import type * as prompts from "@inquirer/prompts";
|
|
3
4
|
import { type ZodObject, type ZodType } from "zod";
|
|
@@ -120,6 +121,7 @@ export interface AgentOptions<I extends Message = Message, O extends Message = M
|
|
|
120
121
|
* One or more memory agents this agent can use
|
|
121
122
|
*/
|
|
122
123
|
memory?: MemoryAgent | MemoryAgent[];
|
|
124
|
+
afs?: true | AFSOptions | AFS | ((afs: AFS) => AFS);
|
|
123
125
|
asyncMemoryRecord?: boolean;
|
|
124
126
|
/**
|
|
125
127
|
* Maximum number of memory items to retrieve
|
|
@@ -205,8 +207,11 @@ export declare abstract class Agent<I extends Message = any, O extends Message =
|
|
|
205
207
|
constructor(options?: AgentOptions<I, O>);
|
|
206
208
|
/**
|
|
207
209
|
* List of memories this agent can use
|
|
210
|
+
*
|
|
211
|
+
* @deprecated use afs instead
|
|
208
212
|
*/
|
|
209
213
|
readonly memories: MemoryAgent[];
|
|
214
|
+
afs?: AFS;
|
|
210
215
|
asyncMemoryRecord?: boolean;
|
|
211
216
|
tag?: string;
|
|
212
217
|
/**
|
package/lib/esm/agents/agent.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { AFS } from "@aigne/afs";
|
|
1
2
|
import { nodejs } from "@aigne/platform-helpers/nodejs/index.js";
|
|
2
3
|
import equal from "fast-deep-equal";
|
|
3
4
|
import nunjucks from "nunjucks";
|
|
@@ -103,6 +104,15 @@ export class Agent {
|
|
|
103
104
|
else if (options.memory) {
|
|
104
105
|
this.memories.push(options.memory);
|
|
105
106
|
}
|
|
107
|
+
this.afs = !options.afs
|
|
108
|
+
? undefined
|
|
109
|
+
: options.afs === true
|
|
110
|
+
? new AFS()
|
|
111
|
+
: typeof options.afs === "function"
|
|
112
|
+
? options.afs(new AFS())
|
|
113
|
+
: options.afs instanceof AFS
|
|
114
|
+
? options.afs
|
|
115
|
+
: new AFS(options.afs);
|
|
106
116
|
this.asyncMemoryRecord = options.asyncMemoryRecord;
|
|
107
117
|
this.maxRetrieveMemoryCount = options.maxRetrieveMemoryCount;
|
|
108
118
|
this.hooks = flat(options.hooks);
|
|
@@ -116,8 +126,11 @@ export class Agent {
|
|
|
116
126
|
}
|
|
117
127
|
/**
|
|
118
128
|
* List of memories this agent can use
|
|
129
|
+
*
|
|
130
|
+
* @deprecated use afs instead
|
|
119
131
|
*/
|
|
120
132
|
memories = [];
|
|
133
|
+
afs;
|
|
121
134
|
asyncMemoryRecord;
|
|
122
135
|
tag;
|
|
123
136
|
/**
|
|
@@ -489,6 +502,7 @@ export class Agent {
|
|
|
489
502
|
const o = await this.callHooks(["onSuccess", "onEnd"], { input, output: finalOutput }, options);
|
|
490
503
|
if (o?.output)
|
|
491
504
|
finalOutput = o.output;
|
|
505
|
+
this.afs?.emit("agentSucceed", { input, output: finalOutput });
|
|
492
506
|
if (!this.disableEvents)
|
|
493
507
|
context.emit("agentSucceed", { agent: this, output: finalOutput });
|
|
494
508
|
return finalOutput;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type ZodObject, type ZodType, z } from "zod";
|
|
2
2
|
import { PromptBuilder } from "../prompt/prompt-builder.js";
|
|
3
|
-
import { Agent, type AgentInvokeOptions, type AgentOptions, type AgentProcessAsyncGenerator, type Message } from "./agent.js";
|
|
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
6
|
import type { FileType } from "./model.js";
|
|
@@ -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
|
*/
|
|
@@ -304,7 +316,8 @@ export declare class AIAgent<I extends Message = any, O extends Message = any> e
|
|
|
304
316
|
*
|
|
305
317
|
* @protected
|
|
306
318
|
*/
|
|
307
|
-
process(input: I, options: AgentInvokeOptions):
|
|
319
|
+
process(input: I, options: AgentInvokeOptions): AgentProcessResult<O>;
|
|
320
|
+
private _process;
|
|
308
321
|
protected onGuideRailError(error: GuideRailAgentOutput): Promise<O | GuideRailAgentOutput>;
|
|
309
322
|
/**
|
|
310
323
|
* Process router mode requests
|
|
@@ -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";
|
|
@@ -55,6 +56,7 @@ export const aiAgentOptionsSchema = agentOptionsSchema.extend({
|
|
|
55
56
|
inputKey: z.string().optional(),
|
|
56
57
|
outputKey: z.string().optional(),
|
|
57
58
|
toolChoice: aiAgentToolChoiceSchema.optional(),
|
|
59
|
+
toolCallsConcurrency: z.number().int().min(0).optional(),
|
|
58
60
|
keepTextInToolUses: z.boolean().optional(),
|
|
59
61
|
memoryAgentsAsTools: z.boolean().optional(),
|
|
60
62
|
memoryPromptTemplate: z.string().optional(),
|
|
@@ -114,6 +116,7 @@ export class AIAgent extends Agent {
|
|
|
114
116
|
this.outputFileKey = options.outputFileKey || DEFAULT_OUTPUT_FILE_KEY;
|
|
115
117
|
this.outputFileType = options.outputFileType;
|
|
116
118
|
this.toolChoice = options.toolChoice;
|
|
119
|
+
this.toolCallsConcurrency = options.toolCallsConcurrency || 1;
|
|
117
120
|
this.keepTextInToolUses = options.keepTextInToolUses;
|
|
118
121
|
this.memoryAgentsAsTools = options.memoryAgentsAsTools;
|
|
119
122
|
this.memoryPromptTemplate = options.memoryPromptTemplate;
|
|
@@ -170,6 +173,12 @@ export class AIAgent extends Agent {
|
|
|
170
173
|
* {@includeCode ../../test/agents/ai-agent.test.ts#example-ai-agent-router}
|
|
171
174
|
*/
|
|
172
175
|
toolChoice;
|
|
176
|
+
/**
|
|
177
|
+
* Maximum number of tool calls to execute concurrently
|
|
178
|
+
*
|
|
179
|
+
* @default 1
|
|
180
|
+
*/
|
|
181
|
+
toolCallsConcurrency;
|
|
173
182
|
/**
|
|
174
183
|
* Whether to preserve text generated during tool usage in the final output
|
|
175
184
|
*/
|
|
@@ -232,7 +241,10 @@ export class AIAgent extends Agent {
|
|
|
232
241
|
*
|
|
233
242
|
* @protected
|
|
234
243
|
*/
|
|
235
|
-
|
|
244
|
+
process(input, options) {
|
|
245
|
+
return this._process(input, options);
|
|
246
|
+
}
|
|
247
|
+
async *_process(input, options) {
|
|
236
248
|
const model = this.model || options.model || options.context.model;
|
|
237
249
|
if (!model)
|
|
238
250
|
throw new Error("model is required to run AIAgent");
|
|
@@ -281,31 +293,43 @@ export class AIAgent extends Agent {
|
|
|
281
293
|
yield { delta: { text: { [outputKey]: "\n" } } };
|
|
282
294
|
}
|
|
283
295
|
const executedToolCalls = [];
|
|
296
|
+
let error;
|
|
297
|
+
const queue = fastq.promise(async ({ tool, call }) => {
|
|
298
|
+
try {
|
|
299
|
+
// NOTE: should pass both arguments (model generated) and input (user provided) to the tool
|
|
300
|
+
const output = await this.invokeSkill(tool, { ...input, ...call.function.arguments }, options).catch((error) => {
|
|
301
|
+
if (!this.catchToolsError) {
|
|
302
|
+
return Promise.reject(error);
|
|
303
|
+
}
|
|
304
|
+
return {
|
|
305
|
+
isError: true,
|
|
306
|
+
error: {
|
|
307
|
+
message: error.message,
|
|
308
|
+
},
|
|
309
|
+
};
|
|
310
|
+
});
|
|
311
|
+
executedToolCalls.push({ call, output });
|
|
312
|
+
}
|
|
313
|
+
catch (e) {
|
|
314
|
+
error = e;
|
|
315
|
+
queue.killAndDrain();
|
|
316
|
+
}
|
|
317
|
+
}, this.toolCallsConcurrency || 1);
|
|
284
318
|
// Execute tools
|
|
285
319
|
for (const call of toolCalls) {
|
|
286
320
|
const tool = toolsMap.get(call.function.name);
|
|
287
321
|
if (!tool)
|
|
288
322
|
throw new Error(`Tool not found: ${call.function.name}`);
|
|
289
|
-
|
|
290
|
-
const output = await this.invokeSkill(tool, { ...input, ...call.function.arguments }, options).catch((error) => {
|
|
291
|
-
if (!this.catchToolsError) {
|
|
292
|
-
return Promise.reject(error);
|
|
293
|
-
}
|
|
294
|
-
return {
|
|
295
|
-
isError: true,
|
|
296
|
-
error: {
|
|
297
|
-
message: error.message,
|
|
298
|
-
},
|
|
299
|
-
};
|
|
300
|
-
});
|
|
301
|
-
// NOTE: Return transfer output immediately
|
|
302
|
-
if (isTransferAgentOutput(output)) {
|
|
303
|
-
return output;
|
|
304
|
-
}
|
|
305
|
-
executedToolCalls.push({ call, output });
|
|
323
|
+
queue.push({ tool, call });
|
|
306
324
|
}
|
|
325
|
+
await queue.drained();
|
|
326
|
+
if (error)
|
|
327
|
+
throw error;
|
|
307
328
|
// Continue LLM function calling loop if any tools were executed
|
|
308
329
|
if (executedToolCalls.length) {
|
|
330
|
+
const transferOutput = executedToolCalls.find((i) => isTransferAgentOutput(i.output))?.output;
|
|
331
|
+
if (transferOutput)
|
|
332
|
+
return transferOutput;
|
|
309
333
|
toolCallMessages.push(await AgentMessageTemplate.from(undefined, executedToolCalls.map(({ call }) => call)).format(), ...(await Promise.all(executedToolCalls.map(({ call, output }) => ToolMessageTemplate.from(output, call.id).format()))));
|
|
310
334
|
continue;
|
|
311
335
|
}
|
|
@@ -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
|
})
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { AFSHistory } from "@aigne/afs";
|
|
1
2
|
import { nodejs } from "@aigne/platform-helpers/nodejs/index.js";
|
|
2
3
|
import { stringify } from "yaml";
|
|
3
4
|
import { ZodObject } from "zod";
|
|
@@ -7,7 +8,7 @@ import { DEFAULT_OUTPUT_FILE_KEY, DEFAULT_OUTPUT_KEY } from "../agents/ai-agent.
|
|
|
7
8
|
import { fileUnionContentsSchema } from "../agents/model.js";
|
|
8
9
|
import { optionalize } from "../loader/schema.js";
|
|
9
10
|
import { outputSchemaToResponseFormatSchema } from "../utils/json-schema.js";
|
|
10
|
-
import { checkArguments, flat, isRecord, unique } from "../utils/type-utils.js";
|
|
11
|
+
import { checkArguments, flat, isNonNullable, isRecord, unique } from "../utils/type-utils.js";
|
|
11
12
|
import { MEMORY_MESSAGE_TEMPLATE } from "./prompts/memory-message-template.js";
|
|
12
13
|
import { STRUCTURED_STREAM_INSTRUCTIONS } from "./prompts/structured-stream-instructions.js";
|
|
13
14
|
import { AgentMessageTemplate, ChatMessagesTemplate, PromptTemplate, SystemMessageTemplate, UserMessageTemplate, } from "./template.js";
|
|
@@ -95,6 +96,18 @@ export class PromptBuilder {
|
|
|
95
96
|
if (options.agent?.useMemoriesFromContext && options.context?.memories?.length) {
|
|
96
97
|
memories.push(...options.context.memories);
|
|
97
98
|
}
|
|
99
|
+
if (options.agent?.afs) {
|
|
100
|
+
const history = await options.agent.afs.list(AFSHistory.Path, {
|
|
101
|
+
limit: options.agent.maxRetrieveMemoryCount || 1,
|
|
102
|
+
orderBy: [["createdAt", "desc"]],
|
|
103
|
+
});
|
|
104
|
+
if (message) {
|
|
105
|
+
const result = await options.agent.afs.search("/", message);
|
|
106
|
+
const ms = result.list.map((entry) => ({ content: stringify(entry.content) }));
|
|
107
|
+
memories.push(...ms);
|
|
108
|
+
}
|
|
109
|
+
memories.push(...history.list.filter((i) => isNonNullable(i.content)));
|
|
110
|
+
}
|
|
98
111
|
if (memories.length)
|
|
99
112
|
messages.push(...(await this.convertMemoriesToMessages(memories, options)));
|
|
100
113
|
// if the agent is using structured stream mode, add the instructions
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AgentHooks } from "../agents/agent.
|
|
1
|
+
import type { AgentHooks } from "../agents/agent.js";
|
|
2
2
|
import type { AIGNECLIAgents } from "../aigne/type.js";
|
|
3
3
|
export declare function sortHooks(hooks: AgentHooks[]): AgentHooks[];
|
|
4
4
|
export interface CLIAgent<T> {
|
|
@@ -9,4 +9,4 @@ export interface CLIAgent<T> {
|
|
|
9
9
|
agents?: CLIAgent<T>[];
|
|
10
10
|
}
|
|
11
11
|
export declare function mapCliAgent<A, O>({ agent, agents, ...input }: CLIAgent<A>, transform: (input: A) => O): CLIAgent<O>;
|
|
12
|
-
export declare function findCliAgent(cli: AIGNECLIAgents, parent: string[] | "*", name: string): import("../agents/agent.
|
|
12
|
+
export declare function findCliAgent(cli: AIGNECLIAgents, parent: string[] | "*", name: string): import("../agents/agent.js").Agent<any, any> | undefined;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aigne/core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.63.0-beta.1",
|
|
4
4
|
"description": "The functional core of agentic AI",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -92,7 +92,8 @@
|
|
|
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
|
+
"@aigne/observability-api": "^0.11.2-beta",
|
|
96
97
|
"@aigne/platform-helpers": "^0.6.3"
|
|
97
98
|
},
|
|
98
99
|
"devDependencies": {
|