@aigne/core 1.36.0 → 1.37.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 +12 -0
- package/lib/cjs/agents/team-agent.d.ts +93 -1
- package/lib/cjs/agents/team-agent.js +42 -4
- package/lib/cjs/loader/agent-js.d.ts +2 -8
- package/lib/cjs/loader/agent-js.js +3 -11
- package/lib/cjs/loader/agent-yaml.d.ts +12 -7
- package/lib/cjs/loader/agent-yaml.js +12 -2
- package/lib/cjs/loader/index.js +7 -1
- package/lib/dts/agents/team-agent.d.ts +93 -1
- package/lib/dts/loader/agent-js.d.ts +2 -8
- package/lib/dts/loader/agent-yaml.d.ts +12 -7
- package/lib/esm/agents/team-agent.d.ts +93 -1
- package/lib/esm/agents/team-agent.js +41 -3
- package/lib/esm/loader/agent-js.d.ts +2 -8
- package/lib/esm/loader/agent-js.js +3 -11
- package/lib/esm/loader/agent-yaml.d.ts +12 -7
- package/lib/esm/loader/agent-yaml.js +11 -2
- package/lib/esm/loader/index.js +7 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -12,6 +12,18 @@
|
|
|
12
12
|
* dependencies
|
|
13
13
|
* @aigne/observability bumped to 0.1.0
|
|
14
14
|
|
|
15
|
+
## [1.37.0](https://github.com/AIGNE-io/aigne-framework/compare/core-v1.36.0...core-v1.37.0) (2025-07-22)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Features
|
|
19
|
+
|
|
20
|
+
* **core:** add reflection mode support to TeamAgent ([#273](https://github.com/AIGNE-io/aigne-framework/issues/273)) ([4e2dad6](https://github.com/AIGNE-io/aigne-framework/commit/4e2dad687c1caefa231c7a7620651d060f8c8b9d))
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
### Bug Fixes
|
|
24
|
+
|
|
25
|
+
* **core:** function agent should use common schema from yaml definition ([#270](https://github.com/AIGNE-io/aigne-framework/issues/270)) ([076a489](https://github.com/AIGNE-io/aigne-framework/commit/076a4896948c397518e99df46c1a443ea43daa64))
|
|
26
|
+
|
|
15
27
|
## [1.36.0](https://github.com/AIGNE-io/aigne-framework/compare/core-v1.35.0...core-v1.36.0) (2025-07-17)
|
|
16
28
|
|
|
17
29
|
|
|
@@ -22,6 +22,73 @@ export declare enum ProcessMode {
|
|
|
22
22
|
*/
|
|
23
23
|
parallel = "parallel"
|
|
24
24
|
}
|
|
25
|
+
export declare const DEFAULT_REFLECTION_MAX_ITERATIONS = 3;
|
|
26
|
+
/**
|
|
27
|
+
* Configuration for reflection mode processing in TeamAgent.
|
|
28
|
+
*
|
|
29
|
+
* Reflection mode enables iterative refinement of agent outputs through a review process.
|
|
30
|
+
* The team agent will repeatedly process the input and have a reviewer agent evaluate
|
|
31
|
+
* the output until it meets approval criteria or reaches the maximum iteration limit.
|
|
32
|
+
*
|
|
33
|
+
* This is particularly useful for:
|
|
34
|
+
* - Quality assurance workflows where outputs need validation
|
|
35
|
+
* - Iterative improvement processes where initial results can be refined
|
|
36
|
+
* - Self-correcting agent systems that learn from feedback
|
|
37
|
+
*/
|
|
38
|
+
export interface ReflectionMode {
|
|
39
|
+
/**
|
|
40
|
+
* The agent responsible for reviewing and providing feedback on the team's output.
|
|
41
|
+
*
|
|
42
|
+
* The reviewer agent receives the combined output from the team's processing
|
|
43
|
+
* and should provide feedback or evaluation that can be used to determine
|
|
44
|
+
* whether the output meets the required standards.
|
|
45
|
+
*/
|
|
46
|
+
reviewer: Agent;
|
|
47
|
+
/**
|
|
48
|
+
* Function that determines whether the reviewer's output indicates approval.
|
|
49
|
+
*
|
|
50
|
+
* This function receives the reviewer agent's output message and should return:
|
|
51
|
+
* - `true` or truthy value: The output is approved and processing should stop
|
|
52
|
+
* - `false` or falsy value: The output needs improvement and another iteration should run
|
|
53
|
+
*
|
|
54
|
+
* The function can be synchronous or asynchronous, allowing for complex approval logic
|
|
55
|
+
* including external validation, scoring systems, or human-in-the-loop approval.
|
|
56
|
+
*
|
|
57
|
+
* @param output - The message output from the reviewer agent
|
|
58
|
+
* @returns A boolean or truthy/falsy value indicating approval status
|
|
59
|
+
*/
|
|
60
|
+
isApproved: (output: Message) => PromiseOrValue<boolean | unknown>;
|
|
61
|
+
/**
|
|
62
|
+
* Maximum number of reflection iterations before giving up.
|
|
63
|
+
*
|
|
64
|
+
* This prevents infinite loops when the approval criteria cannot be met.
|
|
65
|
+
* If the maximum iterations are reached without approval, the process will
|
|
66
|
+
* throw an error indicating the reflection failed to converge.
|
|
67
|
+
*
|
|
68
|
+
* @default 3
|
|
69
|
+
*/
|
|
70
|
+
maxIterations?: number;
|
|
71
|
+
/**
|
|
72
|
+
* Controls the behavior when maximum iterations are reached without approval.
|
|
73
|
+
*
|
|
74
|
+
* When set to `true`, the TeamAgent will return the last generated output
|
|
75
|
+
* instead of throwing an error when the maximum number of reflection iterations
|
|
76
|
+
* is reached without the reviewer's approval.
|
|
77
|
+
*
|
|
78
|
+
* When set to `false` or undefined, the TeamAgent will throw an error
|
|
79
|
+
* indicating that the reflection process failed to converge within the
|
|
80
|
+
* maximum iteration limit.
|
|
81
|
+
*
|
|
82
|
+
* This option is useful for scenarios where:
|
|
83
|
+
* - You want to get the best available result even if it's not perfect
|
|
84
|
+
* - The approval criteria might be too strict for the given context
|
|
85
|
+
* - You prefer graceful degradation over complete failure
|
|
86
|
+
* - You want to implement custom error handling based on the returned result
|
|
87
|
+
*
|
|
88
|
+
* @default false
|
|
89
|
+
*/
|
|
90
|
+
returnLastOnMaxIterations?: boolean;
|
|
91
|
+
}
|
|
25
92
|
/**
|
|
26
93
|
* Configuration options for creating a TeamAgent.
|
|
27
94
|
*
|
|
@@ -33,6 +100,21 @@ export interface TeamAgentOptions<I extends Message, O extends Message> extends
|
|
|
33
100
|
* @default {ProcessMode.sequential}
|
|
34
101
|
*/
|
|
35
102
|
mode?: ProcessMode;
|
|
103
|
+
/**
|
|
104
|
+
* Configuration for reflection mode processing.
|
|
105
|
+
*
|
|
106
|
+
* When enabled, the TeamAgent will use an iterative refinement process where:
|
|
107
|
+
* 1. The team processes the input normally
|
|
108
|
+
* 2. A reviewer agent evaluates the output
|
|
109
|
+
* 3. If not approved, the process repeats with the previous output as context
|
|
110
|
+
* 4. This continues until approval or maximum iterations are reached
|
|
111
|
+
*
|
|
112
|
+
* This enables self-improving agent workflows that can iteratively refine
|
|
113
|
+
* their outputs based on feedback from a specialized reviewer agent.
|
|
114
|
+
*
|
|
115
|
+
* @see ReflectionMode for detailed configuration options
|
|
116
|
+
*/
|
|
117
|
+
reflection?: ReflectionMode;
|
|
36
118
|
/**
|
|
37
119
|
* Specifies which input field should be treated as an array for iterative processing.
|
|
38
120
|
*
|
|
@@ -116,6 +198,14 @@ export declare class TeamAgent<I extends Message, O extends Message> extends Age
|
|
|
116
198
|
* This can be either sequential (one after another) or parallel (all at once).
|
|
117
199
|
*/
|
|
118
200
|
mode: ProcessMode;
|
|
201
|
+
/**
|
|
202
|
+
* The reflection mode configuration with guaranteed maxIterations value.
|
|
203
|
+
*
|
|
204
|
+
* This is the internal representation after processing the user-provided
|
|
205
|
+
* reflection configuration, ensuring that maxIterations always has a value
|
|
206
|
+
* (defaulting to DEFAULT_REFLECTION_MAX_ITERATIONS if not specified).
|
|
207
|
+
*/
|
|
208
|
+
reflection?: ReflectionMode & Required<Pick<ReflectionMode, "maxIterations">>;
|
|
119
209
|
/**
|
|
120
210
|
* The input field key to iterate over when processing array inputs.
|
|
121
211
|
*
|
|
@@ -148,8 +238,10 @@ export declare class TeamAgent<I extends Message, O extends Message> extends Age
|
|
|
148
238
|
* @returns A stream of message chunks that collectively form the response
|
|
149
239
|
*/
|
|
150
240
|
process(input: I, options: AgentInvokeOptions): PromiseOrValue<AgentProcessResult<O>>;
|
|
241
|
+
private _processNonReflection;
|
|
242
|
+
private _processReflection;
|
|
151
243
|
private _processIterator;
|
|
152
|
-
private
|
|
244
|
+
private _processNonIterator;
|
|
153
245
|
/**
|
|
154
246
|
* Process input sequentially through each agent in the team.
|
|
155
247
|
*
|
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.TeamAgent = exports.ProcessMode = void 0;
|
|
6
|
+
exports.TeamAgent = exports.DEFAULT_REFLECTION_MAX_ITERATIONS = exports.ProcessMode = void 0;
|
|
7
7
|
const node_assert_1 = __importDefault(require("node:assert"));
|
|
8
8
|
const immer_1 = require("immer");
|
|
9
9
|
const stream_utils_js_1 = require("../utils/stream-utils.js");
|
|
@@ -32,6 +32,7 @@ var ProcessMode;
|
|
|
32
32
|
*/
|
|
33
33
|
ProcessMode["parallel"] = "parallel";
|
|
34
34
|
})(ProcessMode || (exports.ProcessMode = ProcessMode = {}));
|
|
35
|
+
exports.DEFAULT_REFLECTION_MAX_ITERATIONS = 3;
|
|
35
36
|
/**
|
|
36
37
|
* TeamAgent coordinates a group of agents working together to accomplish tasks.
|
|
37
38
|
*
|
|
@@ -76,6 +77,10 @@ class TeamAgent extends agent_js_1.Agent {
|
|
|
76
77
|
constructor(options) {
|
|
77
78
|
super(options);
|
|
78
79
|
this.mode = options.mode ?? ProcessMode.sequential;
|
|
80
|
+
this.reflection = options.reflection && {
|
|
81
|
+
...options.reflection,
|
|
82
|
+
maxIterations: options.reflection.maxIterations ?? exports.DEFAULT_REFLECTION_MAX_ITERATIONS,
|
|
83
|
+
};
|
|
79
84
|
this.iterateOn = options.iterateOn;
|
|
80
85
|
this.iterateWithPreviousOutput = options.iterateWithPreviousOutput;
|
|
81
86
|
}
|
|
@@ -85,6 +90,14 @@ class TeamAgent extends agent_js_1.Agent {
|
|
|
85
90
|
* This can be either sequential (one after another) or parallel (all at once).
|
|
86
91
|
*/
|
|
87
92
|
mode;
|
|
93
|
+
/**
|
|
94
|
+
* The reflection mode configuration with guaranteed maxIterations value.
|
|
95
|
+
*
|
|
96
|
+
* This is the internal representation after processing the user-provided
|
|
97
|
+
* reflection configuration, ensuring that maxIterations always has a value
|
|
98
|
+
* (defaulting to DEFAULT_REFLECTION_MAX_ITERATIONS if not specified).
|
|
99
|
+
*/
|
|
100
|
+
reflection;
|
|
88
101
|
/**
|
|
89
102
|
* The input field key to iterate over when processing array inputs.
|
|
90
103
|
*
|
|
@@ -119,10 +132,35 @@ class TeamAgent extends agent_js_1.Agent {
|
|
|
119
132
|
process(input, options) {
|
|
120
133
|
if (!this.skills.length)
|
|
121
134
|
throw new Error("TeamAgent must have at least one skill defined.");
|
|
135
|
+
if (this.reflection)
|
|
136
|
+
return this._processReflection(input, options);
|
|
137
|
+
return this._processNonReflection(input, options);
|
|
138
|
+
}
|
|
139
|
+
_processNonReflection(input, options) {
|
|
122
140
|
if (this.iterateOn) {
|
|
123
141
|
return this._processIterator(this.iterateOn, input, options);
|
|
124
142
|
}
|
|
125
|
-
return this.
|
|
143
|
+
return this._processNonIterator(input, options);
|
|
144
|
+
}
|
|
145
|
+
async _processReflection(input, options) {
|
|
146
|
+
(0, node_assert_1.default)(this.reflection, "Reflection mode must be defined for reflection processing");
|
|
147
|
+
let iterations = 0;
|
|
148
|
+
const previousOutput = { ...input };
|
|
149
|
+
for (;;) {
|
|
150
|
+
const output = await (0, agent_js_1.agentProcessResultToObject)(await this._processNonReflection(previousOutput, options));
|
|
151
|
+
Object.assign(previousOutput, output);
|
|
152
|
+
const reviewOutput = await options.context.invoke(this.reflection.reviewer, previousOutput);
|
|
153
|
+
Object.assign(previousOutput, reviewOutput);
|
|
154
|
+
const approved = await this.reflection.isApproved(reviewOutput);
|
|
155
|
+
if (approved)
|
|
156
|
+
return output;
|
|
157
|
+
if (++iterations >= this.reflection.maxIterations) {
|
|
158
|
+
if (this.reflection.returnLastOnMaxIterations)
|
|
159
|
+
return output;
|
|
160
|
+
break;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
throw new Error(`Reflection mode exceeded max iterations ${this.reflection.maxIterations}. Please review the feedback and try again.`);
|
|
126
164
|
}
|
|
127
165
|
async *_processIterator(key, input, options) {
|
|
128
166
|
(0, node_assert_1.default)(this.iterateOn, "iterateInputKey must be defined for iterator processing");
|
|
@@ -133,7 +171,7 @@ class TeamAgent extends agent_js_1.Agent {
|
|
|
133
171
|
const item = arr[i];
|
|
134
172
|
if (!(0, type_utils_js_1.isRecord)(item))
|
|
135
173
|
throw new TypeError(`Expected ${String(key)} to be an object, got ${typeof item}`);
|
|
136
|
-
const res = await (0, agent_js_1.agentProcessResultToObject)(await this.
|
|
174
|
+
const res = await (0, agent_js_1.agentProcessResultToObject)(await this._processNonIterator({ ...input, [key]: arr, ...item }, { ...options, streaming: false }));
|
|
137
175
|
// Merge the item result with the original item used for next iteration
|
|
138
176
|
if (this.iterateWithPreviousOutput) {
|
|
139
177
|
arr = (0, immer_1.produce)(arr, (draft) => {
|
|
@@ -146,7 +184,7 @@ class TeamAgent extends agent_js_1.Agent {
|
|
|
146
184
|
yield { delta: { json: { [key]: result } } };
|
|
147
185
|
}
|
|
148
186
|
}
|
|
149
|
-
|
|
187
|
+
_processNonIterator(input, options) {
|
|
150
188
|
switch (this.mode) {
|
|
151
189
|
case ProcessMode.sequential:
|
|
152
190
|
return this._processSequential(input, options);
|
|
@@ -1,8 +1,2 @@
|
|
|
1
|
-
import { Agent
|
|
2
|
-
export declare function loadAgentFromJsFile(path: string): Promise<Agent<any, any> |
|
|
3
|
-
process: FunctionAgentFn;
|
|
4
|
-
name: string;
|
|
5
|
-
description?: string | undefined;
|
|
6
|
-
inputSchema?: any;
|
|
7
|
-
outputSchema?: any;
|
|
8
|
-
}>;
|
|
1
|
+
import { Agent } from "../agents/agent.js";
|
|
2
|
+
export declare function loadAgentFromJsFile(path: string): Promise<Agent<any, any> | import("./agent-yaml.js").AgentSchema>;
|
|
@@ -34,27 +34,19 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.loadAgentFromJsFile = loadAgentFromJsFile;
|
|
37
|
-
const json_schema_to_zod_1 = require("@aigne/json-schema-to-zod");
|
|
38
|
-
const zod_1 = require("zod");
|
|
39
37
|
const agent_js_1 = require("../agents/agent.js");
|
|
40
38
|
const type_utils_js_1 = require("../utils/type-utils.js");
|
|
41
|
-
const
|
|
39
|
+
const agent_yaml_js_1 = require("./agent-yaml.js");
|
|
42
40
|
async function loadAgentFromJsFile(path) {
|
|
43
|
-
const agentJsFileSchema = (0, schema_js_1.camelizeSchema)(zod_1.z.object({
|
|
44
|
-
name: zod_1.z.string(),
|
|
45
|
-
description: (0, schema_js_1.optionalize)(zod_1.z.string()),
|
|
46
|
-
inputSchema: (0, schema_js_1.optionalize)((0, schema_js_1.inputOutputSchema)({ path })).transform((v) => v ? (0, json_schema_to_zod_1.jsonSchemaToZod)(v) : undefined),
|
|
47
|
-
outputSchema: (0, schema_js_1.optionalize)((0, schema_js_1.inputOutputSchema)({ path })).transform((v) => v ? (0, json_schema_to_zod_1.jsonSchemaToZod)(v) : undefined),
|
|
48
|
-
process: zod_1.z.custom(),
|
|
49
|
-
}));
|
|
50
41
|
const { default: agent } = await (0, type_utils_js_1.tryOrThrow)(() => Promise.resolve(`${path}`).then(s => __importStar(require(s))), (error) => new Error(`Failed to load agent definition from ${path}: ${error.message}`));
|
|
51
42
|
if (agent instanceof agent_js_1.Agent)
|
|
52
43
|
return agent;
|
|
53
44
|
if (typeof agent !== "function") {
|
|
54
45
|
throw new Error(`Agent file ${path} must export a default function, but got ${typeof agent}`);
|
|
55
46
|
}
|
|
56
|
-
return (0, type_utils_js_1.tryOrThrow)(() =>
|
|
47
|
+
return (0, type_utils_js_1.tryOrThrow)(() => (0, agent_yaml_js_1.parseAgentFile)(path, {
|
|
57
48
|
...agent,
|
|
49
|
+
type: "function",
|
|
58
50
|
name: agent.agent_name || agent.agentName || agent.name,
|
|
59
51
|
process: agent,
|
|
60
52
|
}), (error) => new Error(`Failed to parse agent from ${path}: ${error.message}`));
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type ZodType } from "zod";
|
|
2
|
+
import type { FunctionAgentFn } from "../agents/agent.js";
|
|
2
3
|
import { AIAgentToolChoice } from "../agents/ai-agent.js";
|
|
3
4
|
import { ProcessMode } from "../agents/team-agent.js";
|
|
4
5
|
export interface HooksSchema {
|
|
@@ -15,7 +16,7 @@ export type NestAgentSchema = string | {
|
|
|
15
16
|
defaultInput?: Record<string, any>;
|
|
16
17
|
hooks?: HooksSchema | HooksSchema[];
|
|
17
18
|
} | AgentSchema;
|
|
18
|
-
interface BaseAgentSchema {
|
|
19
|
+
export interface BaseAgentSchema {
|
|
19
20
|
name?: string;
|
|
20
21
|
description?: string;
|
|
21
22
|
inputSchema?: ZodType<Record<string, any>>;
|
|
@@ -28,28 +29,32 @@ interface BaseAgentSchema {
|
|
|
28
29
|
subscribeTopic?: string[];
|
|
29
30
|
};
|
|
30
31
|
}
|
|
31
|
-
interface AIAgentSchema extends BaseAgentSchema {
|
|
32
|
+
export interface AIAgentSchema extends BaseAgentSchema {
|
|
32
33
|
type: "ai";
|
|
33
34
|
instructions?: string;
|
|
34
35
|
inputKey?: string;
|
|
35
36
|
outputKey?: string;
|
|
36
37
|
toolChoice?: AIAgentToolChoice;
|
|
37
38
|
}
|
|
38
|
-
interface MCPAgentSchema extends BaseAgentSchema {
|
|
39
|
+
export interface MCPAgentSchema extends BaseAgentSchema {
|
|
39
40
|
type: "mcp";
|
|
40
41
|
url?: string;
|
|
41
42
|
command?: string;
|
|
42
43
|
args?: string[];
|
|
43
44
|
}
|
|
44
|
-
interface TeamAgentSchema extends BaseAgentSchema {
|
|
45
|
+
export interface TeamAgentSchema extends BaseAgentSchema {
|
|
45
46
|
type: "team";
|
|
46
47
|
mode?: ProcessMode;
|
|
47
48
|
iterateOn?: string;
|
|
48
49
|
}
|
|
49
|
-
interface TransformAgentSchema extends BaseAgentSchema {
|
|
50
|
+
export interface TransformAgentSchema extends BaseAgentSchema {
|
|
50
51
|
type: "transform";
|
|
51
52
|
jsonata: string;
|
|
52
53
|
}
|
|
53
|
-
|
|
54
|
+
export interface FunctionAgentSchema extends BaseAgentSchema {
|
|
55
|
+
type: "function";
|
|
56
|
+
process: FunctionAgentFn;
|
|
57
|
+
}
|
|
58
|
+
export type AgentSchema = AIAgentSchema | MCPAgentSchema | TeamAgentSchema | TransformAgentSchema | FunctionAgentSchema;
|
|
59
|
+
export declare function parseAgentFile(path: string, data: object): Promise<AgentSchema>;
|
|
54
60
|
export declare function loadAgentFromYamlFile(path: string): Promise<AgentSchema>;
|
|
55
|
-
export {};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseAgentFile = parseAgentFile;
|
|
3
4
|
exports.loadAgentFromYamlFile = loadAgentFromYamlFile;
|
|
4
5
|
const json_schema_to_zod_1 = require("@aigne/json-schema-to-zod");
|
|
5
6
|
const index_js_1 = require("@aigne/platform-helpers/nodejs/index.js");
|
|
@@ -9,7 +10,7 @@ const ai_agent_js_1 = require("../agents/ai-agent.js");
|
|
|
9
10
|
const team_agent_js_1 = require("../agents/team-agent.js");
|
|
10
11
|
const type_utils_js_1 = require("../utils/type-utils.js");
|
|
11
12
|
const schema_js_1 = require("./schema.js");
|
|
12
|
-
async function
|
|
13
|
+
async function parseAgentFile(path, data) {
|
|
13
14
|
const agentSchema = zod_1.z.lazy(() => {
|
|
14
15
|
const nestAgentSchema = zod_1.z.lazy(() => zod_1.z.union([
|
|
15
16
|
agentSchema,
|
|
@@ -84,11 +85,20 @@ async function loadAgentFromYamlFile(path) {
|
|
|
84
85
|
jsonata: zod_1.z.string(),
|
|
85
86
|
})
|
|
86
87
|
.extend(baseAgentSchema.shape),
|
|
88
|
+
zod_1.z
|
|
89
|
+
.object({
|
|
90
|
+
type: zod_1.z.literal("function"),
|
|
91
|
+
process: zod_1.z.custom(),
|
|
92
|
+
})
|
|
93
|
+
.extend(baseAgentSchema.shape),
|
|
87
94
|
]));
|
|
88
95
|
});
|
|
96
|
+
return agentSchema.parseAsync(data);
|
|
97
|
+
}
|
|
98
|
+
async function loadAgentFromYamlFile(path) {
|
|
89
99
|
const raw = await (0, type_utils_js_1.tryOrThrow)(() => index_js_1.nodejs.fs.readFile(path, "utf8"), (error) => new Error(`Failed to load agent definition from ${path}: ${error.message}`));
|
|
90
100
|
const json = (0, type_utils_js_1.tryOrThrow)(() => (0, yaml_1.parse)(raw), (error) => new Error(`Failed to parse agent definition from ${path}: ${error.message}`));
|
|
91
|
-
const agent = await (0, type_utils_js_1.tryOrThrow)(async () => await
|
|
101
|
+
const agent = await (0, type_utils_js_1.tryOrThrow)(async () => await parseAgentFile(path, {
|
|
92
102
|
...json,
|
|
93
103
|
type: json.type ?? "ai",
|
|
94
104
|
skills: json.skills ?? json.tools,
|
package/lib/cjs/loader/index.js
CHANGED
|
@@ -44,7 +44,7 @@ async function loadAgent(path, options, agentOptions) {
|
|
|
44
44
|
const agent = await (0, agent_js_js_1.loadAgentFromJsFile)(path);
|
|
45
45
|
if (agent instanceof agent_js_1.Agent)
|
|
46
46
|
return agent;
|
|
47
|
-
return
|
|
47
|
+
return parseAgent(path, agent, options, agentOptions);
|
|
48
48
|
}
|
|
49
49
|
if ([".yml", ".yaml"].includes(index_js_1.nodejs.path.extname(path))) {
|
|
50
50
|
const agent = await (0, agent_yaml_js_1.loadAgentFromYamlFile)(path);
|
|
@@ -133,6 +133,12 @@ async function parseAgent(path, agent, options, agentOptions) {
|
|
|
133
133
|
jsonata: agent.jsonata,
|
|
134
134
|
});
|
|
135
135
|
}
|
|
136
|
+
case "function": {
|
|
137
|
+
return agent_js_1.FunctionAgent.from({
|
|
138
|
+
...baseOptions,
|
|
139
|
+
process: agent.process,
|
|
140
|
+
});
|
|
141
|
+
}
|
|
136
142
|
}
|
|
137
143
|
}
|
|
138
144
|
async function loadMemory(memories, provider, options) {
|
|
@@ -22,6 +22,73 @@ export declare enum ProcessMode {
|
|
|
22
22
|
*/
|
|
23
23
|
parallel = "parallel"
|
|
24
24
|
}
|
|
25
|
+
export declare const DEFAULT_REFLECTION_MAX_ITERATIONS = 3;
|
|
26
|
+
/**
|
|
27
|
+
* Configuration for reflection mode processing in TeamAgent.
|
|
28
|
+
*
|
|
29
|
+
* Reflection mode enables iterative refinement of agent outputs through a review process.
|
|
30
|
+
* The team agent will repeatedly process the input and have a reviewer agent evaluate
|
|
31
|
+
* the output until it meets approval criteria or reaches the maximum iteration limit.
|
|
32
|
+
*
|
|
33
|
+
* This is particularly useful for:
|
|
34
|
+
* - Quality assurance workflows where outputs need validation
|
|
35
|
+
* - Iterative improvement processes where initial results can be refined
|
|
36
|
+
* - Self-correcting agent systems that learn from feedback
|
|
37
|
+
*/
|
|
38
|
+
export interface ReflectionMode {
|
|
39
|
+
/**
|
|
40
|
+
* The agent responsible for reviewing and providing feedback on the team's output.
|
|
41
|
+
*
|
|
42
|
+
* The reviewer agent receives the combined output from the team's processing
|
|
43
|
+
* and should provide feedback or evaluation that can be used to determine
|
|
44
|
+
* whether the output meets the required standards.
|
|
45
|
+
*/
|
|
46
|
+
reviewer: Agent;
|
|
47
|
+
/**
|
|
48
|
+
* Function that determines whether the reviewer's output indicates approval.
|
|
49
|
+
*
|
|
50
|
+
* This function receives the reviewer agent's output message and should return:
|
|
51
|
+
* - `true` or truthy value: The output is approved and processing should stop
|
|
52
|
+
* - `false` or falsy value: The output needs improvement and another iteration should run
|
|
53
|
+
*
|
|
54
|
+
* The function can be synchronous or asynchronous, allowing for complex approval logic
|
|
55
|
+
* including external validation, scoring systems, or human-in-the-loop approval.
|
|
56
|
+
*
|
|
57
|
+
* @param output - The message output from the reviewer agent
|
|
58
|
+
* @returns A boolean or truthy/falsy value indicating approval status
|
|
59
|
+
*/
|
|
60
|
+
isApproved: (output: Message) => PromiseOrValue<boolean | unknown>;
|
|
61
|
+
/**
|
|
62
|
+
* Maximum number of reflection iterations before giving up.
|
|
63
|
+
*
|
|
64
|
+
* This prevents infinite loops when the approval criteria cannot be met.
|
|
65
|
+
* If the maximum iterations are reached without approval, the process will
|
|
66
|
+
* throw an error indicating the reflection failed to converge.
|
|
67
|
+
*
|
|
68
|
+
* @default 3
|
|
69
|
+
*/
|
|
70
|
+
maxIterations?: number;
|
|
71
|
+
/**
|
|
72
|
+
* Controls the behavior when maximum iterations are reached without approval.
|
|
73
|
+
*
|
|
74
|
+
* When set to `true`, the TeamAgent will return the last generated output
|
|
75
|
+
* instead of throwing an error when the maximum number of reflection iterations
|
|
76
|
+
* is reached without the reviewer's approval.
|
|
77
|
+
*
|
|
78
|
+
* When set to `false` or undefined, the TeamAgent will throw an error
|
|
79
|
+
* indicating that the reflection process failed to converge within the
|
|
80
|
+
* maximum iteration limit.
|
|
81
|
+
*
|
|
82
|
+
* This option is useful for scenarios where:
|
|
83
|
+
* - You want to get the best available result even if it's not perfect
|
|
84
|
+
* - The approval criteria might be too strict for the given context
|
|
85
|
+
* - You prefer graceful degradation over complete failure
|
|
86
|
+
* - You want to implement custom error handling based on the returned result
|
|
87
|
+
*
|
|
88
|
+
* @default false
|
|
89
|
+
*/
|
|
90
|
+
returnLastOnMaxIterations?: boolean;
|
|
91
|
+
}
|
|
25
92
|
/**
|
|
26
93
|
* Configuration options for creating a TeamAgent.
|
|
27
94
|
*
|
|
@@ -33,6 +100,21 @@ export interface TeamAgentOptions<I extends Message, O extends Message> extends
|
|
|
33
100
|
* @default {ProcessMode.sequential}
|
|
34
101
|
*/
|
|
35
102
|
mode?: ProcessMode;
|
|
103
|
+
/**
|
|
104
|
+
* Configuration for reflection mode processing.
|
|
105
|
+
*
|
|
106
|
+
* When enabled, the TeamAgent will use an iterative refinement process where:
|
|
107
|
+
* 1. The team processes the input normally
|
|
108
|
+
* 2. A reviewer agent evaluates the output
|
|
109
|
+
* 3. If not approved, the process repeats with the previous output as context
|
|
110
|
+
* 4. This continues until approval or maximum iterations are reached
|
|
111
|
+
*
|
|
112
|
+
* This enables self-improving agent workflows that can iteratively refine
|
|
113
|
+
* their outputs based on feedback from a specialized reviewer agent.
|
|
114
|
+
*
|
|
115
|
+
* @see ReflectionMode for detailed configuration options
|
|
116
|
+
*/
|
|
117
|
+
reflection?: ReflectionMode;
|
|
36
118
|
/**
|
|
37
119
|
* Specifies which input field should be treated as an array for iterative processing.
|
|
38
120
|
*
|
|
@@ -116,6 +198,14 @@ export declare class TeamAgent<I extends Message, O extends Message> extends Age
|
|
|
116
198
|
* This can be either sequential (one after another) or parallel (all at once).
|
|
117
199
|
*/
|
|
118
200
|
mode: ProcessMode;
|
|
201
|
+
/**
|
|
202
|
+
* The reflection mode configuration with guaranteed maxIterations value.
|
|
203
|
+
*
|
|
204
|
+
* This is the internal representation after processing the user-provided
|
|
205
|
+
* reflection configuration, ensuring that maxIterations always has a value
|
|
206
|
+
* (defaulting to DEFAULT_REFLECTION_MAX_ITERATIONS if not specified).
|
|
207
|
+
*/
|
|
208
|
+
reflection?: ReflectionMode & Required<Pick<ReflectionMode, "maxIterations">>;
|
|
119
209
|
/**
|
|
120
210
|
* The input field key to iterate over when processing array inputs.
|
|
121
211
|
*
|
|
@@ -148,8 +238,10 @@ export declare class TeamAgent<I extends Message, O extends Message> extends Age
|
|
|
148
238
|
* @returns A stream of message chunks that collectively form the response
|
|
149
239
|
*/
|
|
150
240
|
process(input: I, options: AgentInvokeOptions): PromiseOrValue<AgentProcessResult<O>>;
|
|
241
|
+
private _processNonReflection;
|
|
242
|
+
private _processReflection;
|
|
151
243
|
private _processIterator;
|
|
152
|
-
private
|
|
244
|
+
private _processNonIterator;
|
|
153
245
|
/**
|
|
154
246
|
* Process input sequentially through each agent in the team.
|
|
155
247
|
*
|
|
@@ -1,8 +1,2 @@
|
|
|
1
|
-
import { Agent
|
|
2
|
-
export declare function loadAgentFromJsFile(path: string): Promise<Agent<any, any> |
|
|
3
|
-
process: FunctionAgentFn;
|
|
4
|
-
name: string;
|
|
5
|
-
description?: string | undefined;
|
|
6
|
-
inputSchema?: any;
|
|
7
|
-
outputSchema?: any;
|
|
8
|
-
}>;
|
|
1
|
+
import { Agent } from "../agents/agent.js";
|
|
2
|
+
export declare function loadAgentFromJsFile(path: string): Promise<Agent<any, any> | import("./agent-yaml.js").AgentSchema>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type ZodType } from "zod";
|
|
2
|
+
import type { FunctionAgentFn } from "../agents/agent.js";
|
|
2
3
|
import { AIAgentToolChoice } from "../agents/ai-agent.js";
|
|
3
4
|
import { ProcessMode } from "../agents/team-agent.js";
|
|
4
5
|
export interface HooksSchema {
|
|
@@ -15,7 +16,7 @@ export type NestAgentSchema = string | {
|
|
|
15
16
|
defaultInput?: Record<string, any>;
|
|
16
17
|
hooks?: HooksSchema | HooksSchema[];
|
|
17
18
|
} | AgentSchema;
|
|
18
|
-
interface BaseAgentSchema {
|
|
19
|
+
export interface BaseAgentSchema {
|
|
19
20
|
name?: string;
|
|
20
21
|
description?: string;
|
|
21
22
|
inputSchema?: ZodType<Record<string, any>>;
|
|
@@ -28,28 +29,32 @@ interface BaseAgentSchema {
|
|
|
28
29
|
subscribeTopic?: string[];
|
|
29
30
|
};
|
|
30
31
|
}
|
|
31
|
-
interface AIAgentSchema extends BaseAgentSchema {
|
|
32
|
+
export interface AIAgentSchema extends BaseAgentSchema {
|
|
32
33
|
type: "ai";
|
|
33
34
|
instructions?: string;
|
|
34
35
|
inputKey?: string;
|
|
35
36
|
outputKey?: string;
|
|
36
37
|
toolChoice?: AIAgentToolChoice;
|
|
37
38
|
}
|
|
38
|
-
interface MCPAgentSchema extends BaseAgentSchema {
|
|
39
|
+
export interface MCPAgentSchema extends BaseAgentSchema {
|
|
39
40
|
type: "mcp";
|
|
40
41
|
url?: string;
|
|
41
42
|
command?: string;
|
|
42
43
|
args?: string[];
|
|
43
44
|
}
|
|
44
|
-
interface TeamAgentSchema extends BaseAgentSchema {
|
|
45
|
+
export interface TeamAgentSchema extends BaseAgentSchema {
|
|
45
46
|
type: "team";
|
|
46
47
|
mode?: ProcessMode;
|
|
47
48
|
iterateOn?: string;
|
|
48
49
|
}
|
|
49
|
-
interface TransformAgentSchema extends BaseAgentSchema {
|
|
50
|
+
export interface TransformAgentSchema extends BaseAgentSchema {
|
|
50
51
|
type: "transform";
|
|
51
52
|
jsonata: string;
|
|
52
53
|
}
|
|
53
|
-
|
|
54
|
+
export interface FunctionAgentSchema extends BaseAgentSchema {
|
|
55
|
+
type: "function";
|
|
56
|
+
process: FunctionAgentFn;
|
|
57
|
+
}
|
|
58
|
+
export type AgentSchema = AIAgentSchema | MCPAgentSchema | TeamAgentSchema | TransformAgentSchema | FunctionAgentSchema;
|
|
59
|
+
export declare function parseAgentFile(path: string, data: object): Promise<AgentSchema>;
|
|
54
60
|
export declare function loadAgentFromYamlFile(path: string): Promise<AgentSchema>;
|
|
55
|
-
export {};
|
|
@@ -22,6 +22,73 @@ export declare enum ProcessMode {
|
|
|
22
22
|
*/
|
|
23
23
|
parallel = "parallel"
|
|
24
24
|
}
|
|
25
|
+
export declare const DEFAULT_REFLECTION_MAX_ITERATIONS = 3;
|
|
26
|
+
/**
|
|
27
|
+
* Configuration for reflection mode processing in TeamAgent.
|
|
28
|
+
*
|
|
29
|
+
* Reflection mode enables iterative refinement of agent outputs through a review process.
|
|
30
|
+
* The team agent will repeatedly process the input and have a reviewer agent evaluate
|
|
31
|
+
* the output until it meets approval criteria or reaches the maximum iteration limit.
|
|
32
|
+
*
|
|
33
|
+
* This is particularly useful for:
|
|
34
|
+
* - Quality assurance workflows where outputs need validation
|
|
35
|
+
* - Iterative improvement processes where initial results can be refined
|
|
36
|
+
* - Self-correcting agent systems that learn from feedback
|
|
37
|
+
*/
|
|
38
|
+
export interface ReflectionMode {
|
|
39
|
+
/**
|
|
40
|
+
* The agent responsible for reviewing and providing feedback on the team's output.
|
|
41
|
+
*
|
|
42
|
+
* The reviewer agent receives the combined output from the team's processing
|
|
43
|
+
* and should provide feedback or evaluation that can be used to determine
|
|
44
|
+
* whether the output meets the required standards.
|
|
45
|
+
*/
|
|
46
|
+
reviewer: Agent;
|
|
47
|
+
/**
|
|
48
|
+
* Function that determines whether the reviewer's output indicates approval.
|
|
49
|
+
*
|
|
50
|
+
* This function receives the reviewer agent's output message and should return:
|
|
51
|
+
* - `true` or truthy value: The output is approved and processing should stop
|
|
52
|
+
* - `false` or falsy value: The output needs improvement and another iteration should run
|
|
53
|
+
*
|
|
54
|
+
* The function can be synchronous or asynchronous, allowing for complex approval logic
|
|
55
|
+
* including external validation, scoring systems, or human-in-the-loop approval.
|
|
56
|
+
*
|
|
57
|
+
* @param output - The message output from the reviewer agent
|
|
58
|
+
* @returns A boolean or truthy/falsy value indicating approval status
|
|
59
|
+
*/
|
|
60
|
+
isApproved: (output: Message) => PromiseOrValue<boolean | unknown>;
|
|
61
|
+
/**
|
|
62
|
+
* Maximum number of reflection iterations before giving up.
|
|
63
|
+
*
|
|
64
|
+
* This prevents infinite loops when the approval criteria cannot be met.
|
|
65
|
+
* If the maximum iterations are reached without approval, the process will
|
|
66
|
+
* throw an error indicating the reflection failed to converge.
|
|
67
|
+
*
|
|
68
|
+
* @default 3
|
|
69
|
+
*/
|
|
70
|
+
maxIterations?: number;
|
|
71
|
+
/**
|
|
72
|
+
* Controls the behavior when maximum iterations are reached without approval.
|
|
73
|
+
*
|
|
74
|
+
* When set to `true`, the TeamAgent will return the last generated output
|
|
75
|
+
* instead of throwing an error when the maximum number of reflection iterations
|
|
76
|
+
* is reached without the reviewer's approval.
|
|
77
|
+
*
|
|
78
|
+
* When set to `false` or undefined, the TeamAgent will throw an error
|
|
79
|
+
* indicating that the reflection process failed to converge within the
|
|
80
|
+
* maximum iteration limit.
|
|
81
|
+
*
|
|
82
|
+
* This option is useful for scenarios where:
|
|
83
|
+
* - You want to get the best available result even if it's not perfect
|
|
84
|
+
* - The approval criteria might be too strict for the given context
|
|
85
|
+
* - You prefer graceful degradation over complete failure
|
|
86
|
+
* - You want to implement custom error handling based on the returned result
|
|
87
|
+
*
|
|
88
|
+
* @default false
|
|
89
|
+
*/
|
|
90
|
+
returnLastOnMaxIterations?: boolean;
|
|
91
|
+
}
|
|
25
92
|
/**
|
|
26
93
|
* Configuration options for creating a TeamAgent.
|
|
27
94
|
*
|
|
@@ -33,6 +100,21 @@ export interface TeamAgentOptions<I extends Message, O extends Message> extends
|
|
|
33
100
|
* @default {ProcessMode.sequential}
|
|
34
101
|
*/
|
|
35
102
|
mode?: ProcessMode;
|
|
103
|
+
/**
|
|
104
|
+
* Configuration for reflection mode processing.
|
|
105
|
+
*
|
|
106
|
+
* When enabled, the TeamAgent will use an iterative refinement process where:
|
|
107
|
+
* 1. The team processes the input normally
|
|
108
|
+
* 2. A reviewer agent evaluates the output
|
|
109
|
+
* 3. If not approved, the process repeats with the previous output as context
|
|
110
|
+
* 4. This continues until approval or maximum iterations are reached
|
|
111
|
+
*
|
|
112
|
+
* This enables self-improving agent workflows that can iteratively refine
|
|
113
|
+
* their outputs based on feedback from a specialized reviewer agent.
|
|
114
|
+
*
|
|
115
|
+
* @see ReflectionMode for detailed configuration options
|
|
116
|
+
*/
|
|
117
|
+
reflection?: ReflectionMode;
|
|
36
118
|
/**
|
|
37
119
|
* Specifies which input field should be treated as an array for iterative processing.
|
|
38
120
|
*
|
|
@@ -116,6 +198,14 @@ export declare class TeamAgent<I extends Message, O extends Message> extends Age
|
|
|
116
198
|
* This can be either sequential (one after another) or parallel (all at once).
|
|
117
199
|
*/
|
|
118
200
|
mode: ProcessMode;
|
|
201
|
+
/**
|
|
202
|
+
* The reflection mode configuration with guaranteed maxIterations value.
|
|
203
|
+
*
|
|
204
|
+
* This is the internal representation after processing the user-provided
|
|
205
|
+
* reflection configuration, ensuring that maxIterations always has a value
|
|
206
|
+
* (defaulting to DEFAULT_REFLECTION_MAX_ITERATIONS if not specified).
|
|
207
|
+
*/
|
|
208
|
+
reflection?: ReflectionMode & Required<Pick<ReflectionMode, "maxIterations">>;
|
|
119
209
|
/**
|
|
120
210
|
* The input field key to iterate over when processing array inputs.
|
|
121
211
|
*
|
|
@@ -148,8 +238,10 @@ export declare class TeamAgent<I extends Message, O extends Message> extends Age
|
|
|
148
238
|
* @returns A stream of message chunks that collectively form the response
|
|
149
239
|
*/
|
|
150
240
|
process(input: I, options: AgentInvokeOptions): PromiseOrValue<AgentProcessResult<O>>;
|
|
241
|
+
private _processNonReflection;
|
|
242
|
+
private _processReflection;
|
|
151
243
|
private _processIterator;
|
|
152
|
-
private
|
|
244
|
+
private _processNonIterator;
|
|
153
245
|
/**
|
|
154
246
|
* Process input sequentially through each agent in the team.
|
|
155
247
|
*
|
|
@@ -26,6 +26,7 @@ export var ProcessMode;
|
|
|
26
26
|
*/
|
|
27
27
|
ProcessMode["parallel"] = "parallel";
|
|
28
28
|
})(ProcessMode || (ProcessMode = {}));
|
|
29
|
+
export const DEFAULT_REFLECTION_MAX_ITERATIONS = 3;
|
|
29
30
|
/**
|
|
30
31
|
* TeamAgent coordinates a group of agents working together to accomplish tasks.
|
|
31
32
|
*
|
|
@@ -70,6 +71,10 @@ export class TeamAgent extends Agent {
|
|
|
70
71
|
constructor(options) {
|
|
71
72
|
super(options);
|
|
72
73
|
this.mode = options.mode ?? ProcessMode.sequential;
|
|
74
|
+
this.reflection = options.reflection && {
|
|
75
|
+
...options.reflection,
|
|
76
|
+
maxIterations: options.reflection.maxIterations ?? DEFAULT_REFLECTION_MAX_ITERATIONS,
|
|
77
|
+
};
|
|
73
78
|
this.iterateOn = options.iterateOn;
|
|
74
79
|
this.iterateWithPreviousOutput = options.iterateWithPreviousOutput;
|
|
75
80
|
}
|
|
@@ -79,6 +84,14 @@ export class TeamAgent extends Agent {
|
|
|
79
84
|
* This can be either sequential (one after another) or parallel (all at once).
|
|
80
85
|
*/
|
|
81
86
|
mode;
|
|
87
|
+
/**
|
|
88
|
+
* The reflection mode configuration with guaranteed maxIterations value.
|
|
89
|
+
*
|
|
90
|
+
* This is the internal representation after processing the user-provided
|
|
91
|
+
* reflection configuration, ensuring that maxIterations always has a value
|
|
92
|
+
* (defaulting to DEFAULT_REFLECTION_MAX_ITERATIONS if not specified).
|
|
93
|
+
*/
|
|
94
|
+
reflection;
|
|
82
95
|
/**
|
|
83
96
|
* The input field key to iterate over when processing array inputs.
|
|
84
97
|
*
|
|
@@ -113,10 +126,35 @@ export class TeamAgent extends Agent {
|
|
|
113
126
|
process(input, options) {
|
|
114
127
|
if (!this.skills.length)
|
|
115
128
|
throw new Error("TeamAgent must have at least one skill defined.");
|
|
129
|
+
if (this.reflection)
|
|
130
|
+
return this._processReflection(input, options);
|
|
131
|
+
return this._processNonReflection(input, options);
|
|
132
|
+
}
|
|
133
|
+
_processNonReflection(input, options) {
|
|
116
134
|
if (this.iterateOn) {
|
|
117
135
|
return this._processIterator(this.iterateOn, input, options);
|
|
118
136
|
}
|
|
119
|
-
return this.
|
|
137
|
+
return this._processNonIterator(input, options);
|
|
138
|
+
}
|
|
139
|
+
async _processReflection(input, options) {
|
|
140
|
+
assert(this.reflection, "Reflection mode must be defined for reflection processing");
|
|
141
|
+
let iterations = 0;
|
|
142
|
+
const previousOutput = { ...input };
|
|
143
|
+
for (;;) {
|
|
144
|
+
const output = await agentProcessResultToObject(await this._processNonReflection(previousOutput, options));
|
|
145
|
+
Object.assign(previousOutput, output);
|
|
146
|
+
const reviewOutput = await options.context.invoke(this.reflection.reviewer, previousOutput);
|
|
147
|
+
Object.assign(previousOutput, reviewOutput);
|
|
148
|
+
const approved = await this.reflection.isApproved(reviewOutput);
|
|
149
|
+
if (approved)
|
|
150
|
+
return output;
|
|
151
|
+
if (++iterations >= this.reflection.maxIterations) {
|
|
152
|
+
if (this.reflection.returnLastOnMaxIterations)
|
|
153
|
+
return output;
|
|
154
|
+
break;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
throw new Error(`Reflection mode exceeded max iterations ${this.reflection.maxIterations}. Please review the feedback and try again.`);
|
|
120
158
|
}
|
|
121
159
|
async *_processIterator(key, input, options) {
|
|
122
160
|
assert(this.iterateOn, "iterateInputKey must be defined for iterator processing");
|
|
@@ -127,7 +165,7 @@ export class TeamAgent extends Agent {
|
|
|
127
165
|
const item = arr[i];
|
|
128
166
|
if (!isRecord(item))
|
|
129
167
|
throw new TypeError(`Expected ${String(key)} to be an object, got ${typeof item}`);
|
|
130
|
-
const res = await agentProcessResultToObject(await this.
|
|
168
|
+
const res = await agentProcessResultToObject(await this._processNonIterator({ ...input, [key]: arr, ...item }, { ...options, streaming: false }));
|
|
131
169
|
// Merge the item result with the original item used for next iteration
|
|
132
170
|
if (this.iterateWithPreviousOutput) {
|
|
133
171
|
arr = produce(arr, (draft) => {
|
|
@@ -140,7 +178,7 @@ export class TeamAgent extends Agent {
|
|
|
140
178
|
yield { delta: { json: { [key]: result } } };
|
|
141
179
|
}
|
|
142
180
|
}
|
|
143
|
-
|
|
181
|
+
_processNonIterator(input, options) {
|
|
144
182
|
switch (this.mode) {
|
|
145
183
|
case ProcessMode.sequential:
|
|
146
184
|
return this._processSequential(input, options);
|
|
@@ -1,8 +1,2 @@
|
|
|
1
|
-
import { Agent
|
|
2
|
-
export declare function loadAgentFromJsFile(path: string): Promise<Agent<any, any> |
|
|
3
|
-
process: FunctionAgentFn;
|
|
4
|
-
name: string;
|
|
5
|
-
description?: string | undefined;
|
|
6
|
-
inputSchema?: any;
|
|
7
|
-
outputSchema?: any;
|
|
8
|
-
}>;
|
|
1
|
+
import { Agent } from "../agents/agent.js";
|
|
2
|
+
export declare function loadAgentFromJsFile(path: string): Promise<Agent<any, any> | import("./agent-yaml.js").AgentSchema>;
|
|
@@ -1,24 +1,16 @@
|
|
|
1
|
-
import { jsonSchemaToZod } from "@aigne/json-schema-to-zod";
|
|
2
|
-
import { z } from "zod";
|
|
3
1
|
import { Agent } from "../agents/agent.js";
|
|
4
2
|
import { tryOrThrow } from "../utils/type-utils.js";
|
|
5
|
-
import {
|
|
3
|
+
import { parseAgentFile } from "./agent-yaml.js";
|
|
6
4
|
export async function loadAgentFromJsFile(path) {
|
|
7
|
-
const agentJsFileSchema = camelizeSchema(z.object({
|
|
8
|
-
name: z.string(),
|
|
9
|
-
description: optionalize(z.string()),
|
|
10
|
-
inputSchema: optionalize(inputOutputSchema({ path })).transform((v) => v ? jsonSchemaToZod(v) : undefined),
|
|
11
|
-
outputSchema: optionalize(inputOutputSchema({ path })).transform((v) => v ? jsonSchemaToZod(v) : undefined),
|
|
12
|
-
process: z.custom(),
|
|
13
|
-
}));
|
|
14
5
|
const { default: agent } = await tryOrThrow(() => import(/* @vite-ignore */ path), (error) => new Error(`Failed to load agent definition from ${path}: ${error.message}`));
|
|
15
6
|
if (agent instanceof Agent)
|
|
16
7
|
return agent;
|
|
17
8
|
if (typeof agent !== "function") {
|
|
18
9
|
throw new Error(`Agent file ${path} must export a default function, but got ${typeof agent}`);
|
|
19
10
|
}
|
|
20
|
-
return tryOrThrow(() =>
|
|
11
|
+
return tryOrThrow(() => parseAgentFile(path, {
|
|
21
12
|
...agent,
|
|
13
|
+
type: "function",
|
|
22
14
|
name: agent.agent_name || agent.agentName || agent.name,
|
|
23
15
|
process: agent,
|
|
24
16
|
}), (error) => new Error(`Failed to parse agent from ${path}: ${error.message}`));
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type ZodType } from "zod";
|
|
2
|
+
import type { FunctionAgentFn } from "../agents/agent.js";
|
|
2
3
|
import { AIAgentToolChoice } from "../agents/ai-agent.js";
|
|
3
4
|
import { ProcessMode } from "../agents/team-agent.js";
|
|
4
5
|
export interface HooksSchema {
|
|
@@ -15,7 +16,7 @@ export type NestAgentSchema = string | {
|
|
|
15
16
|
defaultInput?: Record<string, any>;
|
|
16
17
|
hooks?: HooksSchema | HooksSchema[];
|
|
17
18
|
} | AgentSchema;
|
|
18
|
-
interface BaseAgentSchema {
|
|
19
|
+
export interface BaseAgentSchema {
|
|
19
20
|
name?: string;
|
|
20
21
|
description?: string;
|
|
21
22
|
inputSchema?: ZodType<Record<string, any>>;
|
|
@@ -28,28 +29,32 @@ interface BaseAgentSchema {
|
|
|
28
29
|
subscribeTopic?: string[];
|
|
29
30
|
};
|
|
30
31
|
}
|
|
31
|
-
interface AIAgentSchema extends BaseAgentSchema {
|
|
32
|
+
export interface AIAgentSchema extends BaseAgentSchema {
|
|
32
33
|
type: "ai";
|
|
33
34
|
instructions?: string;
|
|
34
35
|
inputKey?: string;
|
|
35
36
|
outputKey?: string;
|
|
36
37
|
toolChoice?: AIAgentToolChoice;
|
|
37
38
|
}
|
|
38
|
-
interface MCPAgentSchema extends BaseAgentSchema {
|
|
39
|
+
export interface MCPAgentSchema extends BaseAgentSchema {
|
|
39
40
|
type: "mcp";
|
|
40
41
|
url?: string;
|
|
41
42
|
command?: string;
|
|
42
43
|
args?: string[];
|
|
43
44
|
}
|
|
44
|
-
interface TeamAgentSchema extends BaseAgentSchema {
|
|
45
|
+
export interface TeamAgentSchema extends BaseAgentSchema {
|
|
45
46
|
type: "team";
|
|
46
47
|
mode?: ProcessMode;
|
|
47
48
|
iterateOn?: string;
|
|
48
49
|
}
|
|
49
|
-
interface TransformAgentSchema extends BaseAgentSchema {
|
|
50
|
+
export interface TransformAgentSchema extends BaseAgentSchema {
|
|
50
51
|
type: "transform";
|
|
51
52
|
jsonata: string;
|
|
52
53
|
}
|
|
53
|
-
|
|
54
|
+
export interface FunctionAgentSchema extends BaseAgentSchema {
|
|
55
|
+
type: "function";
|
|
56
|
+
process: FunctionAgentFn;
|
|
57
|
+
}
|
|
58
|
+
export type AgentSchema = AIAgentSchema | MCPAgentSchema | TeamAgentSchema | TransformAgentSchema | FunctionAgentSchema;
|
|
59
|
+
export declare function parseAgentFile(path: string, data: object): Promise<AgentSchema>;
|
|
54
60
|
export declare function loadAgentFromYamlFile(path: string): Promise<AgentSchema>;
|
|
55
|
-
export {};
|
|
@@ -6,7 +6,7 @@ import { AIAgentToolChoice } from "../agents/ai-agent.js";
|
|
|
6
6
|
import { ProcessMode } from "../agents/team-agent.js";
|
|
7
7
|
import { tryOrThrow } from "../utils/type-utils.js";
|
|
8
8
|
import { camelizeSchema, defaultInputSchema, inputOutputSchema, optionalize } from "./schema.js";
|
|
9
|
-
export async function
|
|
9
|
+
export async function parseAgentFile(path, data) {
|
|
10
10
|
const agentSchema = z.lazy(() => {
|
|
11
11
|
const nestAgentSchema = z.lazy(() => z.union([
|
|
12
12
|
agentSchema,
|
|
@@ -81,11 +81,20 @@ export async function loadAgentFromYamlFile(path) {
|
|
|
81
81
|
jsonata: z.string(),
|
|
82
82
|
})
|
|
83
83
|
.extend(baseAgentSchema.shape),
|
|
84
|
+
z
|
|
85
|
+
.object({
|
|
86
|
+
type: z.literal("function"),
|
|
87
|
+
process: z.custom(),
|
|
88
|
+
})
|
|
89
|
+
.extend(baseAgentSchema.shape),
|
|
84
90
|
]));
|
|
85
91
|
});
|
|
92
|
+
return agentSchema.parseAsync(data);
|
|
93
|
+
}
|
|
94
|
+
export async function loadAgentFromYamlFile(path) {
|
|
86
95
|
const raw = await tryOrThrow(() => nodejs.fs.readFile(path, "utf8"), (error) => new Error(`Failed to load agent definition from ${path}: ${error.message}`));
|
|
87
96
|
const json = tryOrThrow(() => parse(raw), (error) => new Error(`Failed to parse agent definition from ${path}: ${error.message}`));
|
|
88
|
-
const agent = await tryOrThrow(async () => await
|
|
97
|
+
const agent = await tryOrThrow(async () => await parseAgentFile(path, {
|
|
89
98
|
...json,
|
|
90
99
|
type: json.type ?? "ai",
|
|
91
100
|
skills: json.skills ?? json.tools,
|
package/lib/esm/loader/index.js
CHANGED
|
@@ -35,7 +35,7 @@ export async function loadAgent(path, options, agentOptions) {
|
|
|
35
35
|
const agent = await loadAgentFromJsFile(path);
|
|
36
36
|
if (agent instanceof Agent)
|
|
37
37
|
return agent;
|
|
38
|
-
return
|
|
38
|
+
return parseAgent(path, agent, options, agentOptions);
|
|
39
39
|
}
|
|
40
40
|
if ([".yml", ".yaml"].includes(nodejs.path.extname(path))) {
|
|
41
41
|
const agent = await loadAgentFromYamlFile(path);
|
|
@@ -124,6 +124,12 @@ async function parseAgent(path, agent, options, agentOptions) {
|
|
|
124
124
|
jsonata: agent.jsonata,
|
|
125
125
|
});
|
|
126
126
|
}
|
|
127
|
+
case "function": {
|
|
128
|
+
return FunctionAgent.from({
|
|
129
|
+
...baseOptions,
|
|
130
|
+
process: agent.process,
|
|
131
|
+
});
|
|
132
|
+
}
|
|
127
133
|
}
|
|
128
134
|
}
|
|
129
135
|
async function loadMemory(memories, provider, options) {
|