@aigne/agent-library 1.22.4 → 1.23.0-beta
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 +15 -0
- package/README.md +6 -94
- package/lib/cjs/orchestrator/index.d.ts +39 -71
- package/lib/cjs/orchestrator/index.js +174 -169
- package/lib/cjs/orchestrator/prompt.d.ts +3 -0
- package/lib/cjs/orchestrator/prompt.js +82 -0
- package/lib/cjs/orchestrator/type.d.ts +505 -0
- package/lib/cjs/orchestrator/type.js +83 -0
- package/lib/dts/orchestrator/index.d.ts +39 -71
- package/lib/dts/orchestrator/prompt.d.ts +3 -0
- package/lib/dts/orchestrator/type.d.ts +505 -0
- package/lib/esm/orchestrator/index.d.ts +39 -71
- package/lib/esm/orchestrator/index.js +176 -154
- package/lib/esm/orchestrator/prompt.d.ts +3 -0
- package/lib/esm/orchestrator/prompt.js +79 -0
- package/lib/esm/orchestrator/type.d.ts +505 -0
- package/lib/esm/orchestrator/type.js +77 -0
- package/package.json +11 -5
- package/lib/cjs/orchestrator/orchestrator-prompts.d.ts +0 -130
- package/lib/cjs/orchestrator/orchestrator-prompts.js +0 -135
- package/lib/dts/orchestrator/orchestrator-prompts.d.ts +0 -130
- package/lib/esm/orchestrator/orchestrator-prompts.d.ts +0 -130
- package/lib/esm/orchestrator/orchestrator-prompts.js +0 -131
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,21 @@
|
|
|
7
7
|
* @aigne/core bumped to 1.22.0
|
|
8
8
|
* @aigne/openai bumped to 0.3.4
|
|
9
9
|
|
|
10
|
+
## [1.23.0-beta](https://github.com/AIGNE-io/aigne-framework/compare/agent-library-v1.22.4...agent-library-v1.23.0-beta) (2025-12-07)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Features
|
|
14
|
+
|
|
15
|
+
* support define agent by third library & orchestrator agent refactor ([#799](https://github.com/AIGNE-io/aigne-framework/issues/799)) ([7264b11](https://github.com/AIGNE-io/aigne-framework/commit/7264b11ab6eed787e928367f09aa08d254968d40))
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Dependencies
|
|
19
|
+
|
|
20
|
+
* The following workspace dependencies were updated
|
|
21
|
+
* dependencies
|
|
22
|
+
* @aigne/core bumped to 1.71.0-beta
|
|
23
|
+
* @aigne/openai bumped to 0.16.15-beta
|
|
24
|
+
|
|
10
25
|
## [1.22.4](https://github.com/AIGNE-io/aigne-framework/compare/agent-library-v1.22.4-beta...agent-library-v1.22.4) (2025-12-06)
|
|
11
26
|
|
|
12
27
|
|
package/README.md
CHANGED
|
@@ -54,101 +54,13 @@ yarn add @aigne/agent-library @aigne/core
|
|
|
54
54
|
pnpm add @aigne/agent-library @aigne/core
|
|
55
55
|
```
|
|
56
56
|
|
|
57
|
-
##
|
|
58
|
-
|
|
59
|
-
```typescript
|
|
60
|
-
import { OrchestratorAgent } from "@aigne/agent-library/orchestrator";
|
|
61
|
-
import { AIGNE } from "@aigne/core";
|
|
62
|
-
import { OpenAIChatModel } from "@aigne/core/models/openai-chat-model.js";
|
|
63
|
-
|
|
64
|
-
// Create AI model instance
|
|
65
|
-
const model = new OpenAIChatModel({
|
|
66
|
-
apiKey: process.env.OPENAI_API_KEY,
|
|
67
|
-
model: "gpt-4-turbo",
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
// Create AIGNE
|
|
71
|
-
const aigne = new AIGNE({ model });
|
|
72
|
-
|
|
73
|
-
// Create orchestrator agent
|
|
74
|
-
const orchestrator = new OrchestratorAgent({
|
|
75
|
-
name: "MainOrchestrator",
|
|
76
|
-
instructions:
|
|
77
|
-
"You are a task orchestrator responsible for coordinating multiple specialized agents to complete complex tasks.",
|
|
78
|
-
// Configure sub-agents and tools...
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
// Execute orchestration task
|
|
82
|
-
const result = await aigne.invoke(
|
|
83
|
-
orchestrator,
|
|
84
|
-
"Analyze this article and generate a summary and keywords",
|
|
85
|
-
);
|
|
86
|
-
console.log(result);
|
|
87
|
-
```
|
|
57
|
+
## Components
|
|
88
58
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
* **Orchestrator Agent
|
|
94
|
-
|
|
95
|
-
## Advanced Usage
|
|
96
|
-
|
|
97
|
-
### Creating an Orchestration Workflow
|
|
98
|
-
|
|
99
|
-
```typescript
|
|
100
|
-
import { OrchestratorAgent } from "@aigne/agent-library/orchestrator";
|
|
101
|
-
import { AIAgent, AIGNE } from "@aigne/core";
|
|
102
|
-
import { OpenAIChatModel } from "@aigne/core/models/openai-chat-model.js";
|
|
103
|
-
|
|
104
|
-
const model = new OpenAIChatModel({
|
|
105
|
-
apiKey: process.env.OPENAI_API_KEY,
|
|
106
|
-
model: "gpt-4-turbo",
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
// Create specialized sub-agents
|
|
110
|
-
const researchAgent = AIAgent.from({
|
|
111
|
-
name: "Researcher",
|
|
112
|
-
instructions:
|
|
113
|
-
"You are a professional researcher responsible for collecting and analyzing information.",
|
|
114
|
-
outputKey: "research",
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
const writerAgent = AIAgent.from({
|
|
118
|
-
name: "Writer",
|
|
119
|
-
instructions:
|
|
120
|
-
"You are a professional writer responsible for creating high-quality content.",
|
|
121
|
-
outputKey: "content",
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
const editorAgent = AIAgent.from({
|
|
125
|
-
name: "Editor",
|
|
126
|
-
instructions:
|
|
127
|
-
"You are a strict editor responsible for checking content quality and formatting.",
|
|
128
|
-
outputKey: "edited",
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
// Create orchestrator agent
|
|
132
|
-
const orchestrator = new OrchestratorAgent({
|
|
133
|
-
name: "WorkflowOrchestrator",
|
|
134
|
-
instructions:
|
|
135
|
-
"You are responsible for coordinating research, writing, and editing processes.",
|
|
136
|
-
skills: [researchAgent, writerAgent, editorAgent],
|
|
137
|
-
// Optional configuration
|
|
138
|
-
maxIterations: 30, // Maximum number of iterations
|
|
139
|
-
tasksConcurrency: 5, // Task concurrency
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
// Use the orchestrator agent
|
|
143
|
-
const aigne = new AIGNE({ model });
|
|
144
|
-
|
|
145
|
-
const result = await aigne.invoke(
|
|
146
|
-
orchestrator,
|
|
147
|
-
"Applications of artificial intelligence in healthcare",
|
|
148
|
-
);
|
|
149
|
-
|
|
150
|
-
console.log(result);
|
|
151
|
-
```
|
|
59
|
+
The library provides the following components:
|
|
60
|
+
|
|
61
|
+
### Agent Types
|
|
62
|
+
|
|
63
|
+
* **[Orchestrator Agent](src/orchestrator/README.md)**: A sophisticated agent pattern that enables autonomous task planning and execution through a three-phase architecture: Planner → Worker → Completer. It breaks down complex objectives into manageable tasks, executes them iteratively, and synthesizes the final results. Perfect for coordinating complex workflows and multi-step tasks.
|
|
152
64
|
|
|
153
65
|
## License
|
|
154
66
|
|
|
@@ -1,50 +1,33 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { type
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
*/
|
|
6
|
-
export * from "./orchestrator-prompts.js";
|
|
7
|
-
/**
|
|
8
|
-
* Represents a complete plan with execution results
|
|
9
|
-
* @hidden
|
|
10
|
-
*/
|
|
11
|
-
export interface FullPlanWithResult {
|
|
12
|
-
/**
|
|
13
|
-
* The overall objective
|
|
14
|
-
*/
|
|
15
|
-
objective: string;
|
|
16
|
-
/**
|
|
17
|
-
* The generated complete plan
|
|
18
|
-
*/
|
|
19
|
-
plan?: FullPlanOutput;
|
|
20
|
-
/**
|
|
21
|
-
* List of executed steps with their results
|
|
22
|
-
*/
|
|
23
|
-
steps: StepWithResult[];
|
|
24
|
-
/**
|
|
25
|
-
* Final result
|
|
26
|
-
*/
|
|
27
|
-
result?: string;
|
|
28
|
-
/**
|
|
29
|
-
* Plan completion status
|
|
30
|
-
*/
|
|
31
|
-
status?: boolean;
|
|
32
|
-
}
|
|
1
|
+
import { type AgentInvokeOptions, type AgentOptions, AIAgent, type AIAgentOptions, type Message, type PromptBuilder } from "@aigne/core";
|
|
2
|
+
import { type Instructions, type NestAgentSchema } from "@aigne/core/loader/agent-yaml.js";
|
|
3
|
+
import { type LoadOptions } from "@aigne/core/loader/index.js";
|
|
4
|
+
import { type StateManagementOptions } from "./type.js";
|
|
33
5
|
/**
|
|
34
6
|
* Configuration options for the Orchestrator Agent
|
|
35
7
|
*/
|
|
36
|
-
export interface OrchestratorAgentOptions<I extends Message = Message, O extends Message = Message> extends
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
maxIterations?: number;
|
|
8
|
+
export interface OrchestratorAgentOptions<I extends Message = Message, O extends Message = Message> extends Omit<AIAgentOptions<I, O>, "instructions"> {
|
|
9
|
+
objective: PromptBuilder;
|
|
10
|
+
planner?: OrchestratorAgent<I, O>["planner"];
|
|
11
|
+
worker?: OrchestratorAgent<I, O>["worker"];
|
|
12
|
+
completer?: OrchestratorAgent<I, O>["completer"];
|
|
42
13
|
/**
|
|
43
|
-
*
|
|
44
|
-
*
|
|
14
|
+
* Configuration for managing execution state
|
|
15
|
+
* Prevents context overflow during long-running executions
|
|
45
16
|
*/
|
|
46
|
-
|
|
47
|
-
|
|
17
|
+
stateManagement?: StateManagementOptions;
|
|
18
|
+
}
|
|
19
|
+
export interface LoadOrchestratorAgentOptions<I extends Message = Message, O extends Message = Message> extends Omit<AIAgentOptions<I, O>, "instructions"> {
|
|
20
|
+
objective: string | PromptBuilder | Instructions;
|
|
21
|
+
planner?: NestAgentSchema | {
|
|
22
|
+
instructions?: string | PromptBuilder | Instructions;
|
|
23
|
+
};
|
|
24
|
+
worker?: NestAgentSchema | {
|
|
25
|
+
instructions?: string | PromptBuilder | Instructions;
|
|
26
|
+
};
|
|
27
|
+
completer?: NestAgentSchema | {
|
|
28
|
+
instructions?: string | PromptBuilder | Instructions;
|
|
29
|
+
};
|
|
30
|
+
stateManagement?: StateManagementOptions;
|
|
48
31
|
}
|
|
49
32
|
/**
|
|
50
33
|
* Orchestrator Agent Class
|
|
@@ -61,8 +44,13 @@ export interface OrchestratorAgentOptions<I extends Message = Message, O extends
|
|
|
61
44
|
* - Executes tasks and steps according to the plan
|
|
62
45
|
* - Synthesizes final result through completer
|
|
63
46
|
*/
|
|
64
|
-
export declare class OrchestratorAgent<I extends Message = Message, O extends Message = Message> extends
|
|
47
|
+
export declare class OrchestratorAgent<I extends Message = Message, O extends Message = Message> extends AIAgent<I, O> {
|
|
65
48
|
tag: string;
|
|
49
|
+
static load<I extends Message = Message, O extends Message = Message>({ filepath, parsed, options, }: {
|
|
50
|
+
filepath: string;
|
|
51
|
+
parsed: AgentOptions<I, O> & LoadOrchestratorAgentOptions<I, O>;
|
|
52
|
+
options?: LoadOptions;
|
|
53
|
+
}): Promise<OrchestratorAgent<I, O>>;
|
|
66
54
|
/**
|
|
67
55
|
* Factory method to create an OrchestratorAgent instance
|
|
68
56
|
* @param options - Configuration options for the Orchestrator Agent
|
|
@@ -74,36 +62,16 @@ export declare class OrchestratorAgent<I extends Message = Message, O extends Me
|
|
|
74
62
|
* @param options - Configuration options for the Orchestrator Agent
|
|
75
63
|
*/
|
|
76
64
|
constructor(options: OrchestratorAgentOptions<I, O>);
|
|
65
|
+
private objective;
|
|
77
66
|
private planner;
|
|
67
|
+
private worker;
|
|
78
68
|
private completer;
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Maximum number of iterations
|
|
82
|
-
* Prevents infinite execution loops
|
|
83
|
-
*/
|
|
84
|
-
maxIterations?: number;
|
|
85
|
-
/**
|
|
86
|
-
* Number of concurrent tasks
|
|
87
|
-
* Controls how many tasks can be executed simultaneously
|
|
88
|
-
*/
|
|
89
|
-
tasksConcurrency?: number;
|
|
69
|
+
private stateManagement?;
|
|
90
70
|
/**
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
* Workflow:
|
|
94
|
-
* 1. Extract the objective
|
|
95
|
-
* 2. Loop until plan completion or maximum iterations:
|
|
96
|
-
* a. Generate/update execution plan
|
|
97
|
-
* b. If plan is complete, synthesize result
|
|
98
|
-
* c. Otherwise, execute steps in the plan
|
|
99
|
-
*
|
|
100
|
-
* @param input - Input message containing the objective
|
|
101
|
-
* @param options - Agent invocation options
|
|
102
|
-
* @returns Processing result
|
|
71
|
+
* Compress execution state to prevent context overflow
|
|
72
|
+
* Uses reverse accumulation to efficiently find optimal task count
|
|
103
73
|
*/
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
private getFullPlan;
|
|
107
|
-
private synthesizePlanResult;
|
|
108
|
-
private executeStep;
|
|
74
|
+
private compressState;
|
|
75
|
+
process(input: I, options: AgentInvokeOptions): AsyncGenerator<import("@aigne/core").AgentResponseChunk<O>, void, unknown>;
|
|
109
76
|
}
|
|
77
|
+
export default OrchestratorAgent;
|
|
@@ -1,40 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
-
};
|
|
16
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
17
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
18
|
-
};
|
|
19
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
3
|
exports.OrchestratorAgent = void 0;
|
|
21
4
|
const core_1 = require("@aigne/core");
|
|
5
|
+
const agent_yaml_js_1 = require("@aigne/core/loader/agent-yaml.js");
|
|
6
|
+
const index_js_1 = require("@aigne/core/loader/index.js");
|
|
7
|
+
const schema_js_1 = require("@aigne/core/loader/schema.js");
|
|
8
|
+
const agent_utils_js_1 = require("@aigne/core/utils/agent-utils.js");
|
|
9
|
+
const token_estimator_js_1 = require("@aigne/core/utils/token-estimator.js");
|
|
22
10
|
const type_utils_js_1 = require("@aigne/core/utils/type-utils.js");
|
|
23
|
-
const fastq_1 = __importDefault(require("fastq"));
|
|
24
11
|
const zod_1 = require("zod");
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
* Default maximum number of iterations to prevent infinite loops
|
|
28
|
-
*/
|
|
29
|
-
const DEFAULT_MAX_ITERATIONS = 30;
|
|
30
|
-
/**
|
|
31
|
-
* Default number of concurrent tasks
|
|
32
|
-
*/
|
|
33
|
-
const DEFAULT_TASK_CONCURRENCY = 5;
|
|
34
|
-
/**
|
|
35
|
-
* Re-export orchestrator prompt templates and related types
|
|
36
|
-
*/
|
|
37
|
-
__exportStar(require("./orchestrator-prompts.js"), exports);
|
|
12
|
+
const prompt_js_1 = require("./prompt.js");
|
|
13
|
+
const type_js_1 = require("./type.js");
|
|
38
14
|
/**
|
|
39
15
|
* Orchestrator Agent Class
|
|
40
16
|
*
|
|
@@ -50,8 +26,46 @@ __exportStar(require("./orchestrator-prompts.js"), exports);
|
|
|
50
26
|
* - Executes tasks and steps according to the plan
|
|
51
27
|
* - Synthesizes final result through completer
|
|
52
28
|
*/
|
|
53
|
-
class OrchestratorAgent extends core_1.
|
|
29
|
+
class OrchestratorAgent extends core_1.AIAgent {
|
|
54
30
|
tag = "OrchestratorAgent";
|
|
31
|
+
static async load({ filepath, parsed, options, }) {
|
|
32
|
+
const schema = getOrchestratorAgentSchema({ filepath });
|
|
33
|
+
const valid = await schema.parseAsync(parsed);
|
|
34
|
+
return new OrchestratorAgent({
|
|
35
|
+
...parsed,
|
|
36
|
+
objective: (0, index_js_1.instructionsToPromptBuilder)(valid.objective),
|
|
37
|
+
planner: valid.planner
|
|
38
|
+
? (await (0, index_js_1.loadNestAgent)(filepath, valid.planner, options, {
|
|
39
|
+
name: "Planner",
|
|
40
|
+
instructions: prompt_js_1.TODO_PLANNER_PROMPT_TEMPLATE,
|
|
41
|
+
inputSchema: type_js_1.plannerInputSchema,
|
|
42
|
+
outputSchema: type_js_1.plannerOutputSchema,
|
|
43
|
+
afs: parsed.afs,
|
|
44
|
+
skills: parsed.skills,
|
|
45
|
+
}))
|
|
46
|
+
: undefined,
|
|
47
|
+
worker: valid.worker
|
|
48
|
+
? (await (0, index_js_1.loadNestAgent)(filepath, valid.worker, options, {
|
|
49
|
+
name: "Worker",
|
|
50
|
+
instructions: prompt_js_1.TODO_WORKER_PROMPT_TEMPLATE,
|
|
51
|
+
inputSchema: type_js_1.workerInputSchema,
|
|
52
|
+
outputSchema: type_js_1.workerOutputSchema,
|
|
53
|
+
afs: parsed.afs,
|
|
54
|
+
skills: parsed.skills,
|
|
55
|
+
}))
|
|
56
|
+
: undefined,
|
|
57
|
+
completer: valid.completer
|
|
58
|
+
? (await (0, index_js_1.loadNestAgent)(filepath, valid.completer, options, {
|
|
59
|
+
instructions: prompt_js_1.ORCHESTRATOR_COMPLETE_PROMPT,
|
|
60
|
+
inputSchema: type_js_1.completerInputSchema,
|
|
61
|
+
outputSchema: parsed.outputSchema,
|
|
62
|
+
afs: parsed.afs,
|
|
63
|
+
skills: parsed.skills,
|
|
64
|
+
}))
|
|
65
|
+
: undefined,
|
|
66
|
+
stateManagement: valid.stateManagement,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
55
69
|
/**
|
|
56
70
|
* Factory method to create an OrchestratorAgent instance
|
|
57
71
|
* @param options - Configuration options for the Orchestrator Agent
|
|
@@ -65,159 +79,150 @@ class OrchestratorAgent extends core_1.Agent {
|
|
|
65
79
|
* @param options - Configuration options for the Orchestrator Agent
|
|
66
80
|
*/
|
|
67
81
|
constructor(options) {
|
|
68
|
-
(0, type_utils_js_1.checkArguments)("OrchestratorAgent", orchestratorAgentOptionsSchema, options);
|
|
69
82
|
super({ ...options });
|
|
70
|
-
this.
|
|
71
|
-
this.
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
+
this.objective = options.objective;
|
|
84
|
+
this.planner = (0, agent_utils_js_1.isAgent)(options.planner)
|
|
85
|
+
? options.planner
|
|
86
|
+
: new core_1.AIAgent({
|
|
87
|
+
...options,
|
|
88
|
+
name: "Planner",
|
|
89
|
+
instructions: prompt_js_1.TODO_PLANNER_PROMPT_TEMPLATE,
|
|
90
|
+
inputSchema: type_js_1.plannerInputSchema,
|
|
91
|
+
outputSchema: type_js_1.plannerOutputSchema,
|
|
92
|
+
});
|
|
93
|
+
this.worker = (0, agent_utils_js_1.isAgent)(options.worker)
|
|
94
|
+
? options.worker
|
|
95
|
+
: new core_1.AIAgent({
|
|
96
|
+
...options,
|
|
97
|
+
name: "Worker",
|
|
98
|
+
instructions: prompt_js_1.TODO_WORKER_PROMPT_TEMPLATE,
|
|
99
|
+
inputSchema: type_js_1.workerInputSchema,
|
|
100
|
+
outputSchema: type_js_1.workerOutputSchema,
|
|
101
|
+
});
|
|
102
|
+
this.completer = (0, agent_utils_js_1.isAgent)(options.completer)
|
|
103
|
+
? options.completer
|
|
104
|
+
: new core_1.AIAgent({
|
|
105
|
+
...(0, type_utils_js_1.omit)(options, "inputSchema"),
|
|
106
|
+
name: "Completer",
|
|
107
|
+
instructions: prompt_js_1.ORCHESTRATOR_COMPLETE_PROMPT,
|
|
108
|
+
outputKey: options.outputKey,
|
|
109
|
+
inputSchema: type_js_1.completerInputSchema,
|
|
110
|
+
outputSchema: options.outputSchema,
|
|
111
|
+
});
|
|
112
|
+
// Initialize state management config
|
|
113
|
+
this.stateManagement = options.stateManagement;
|
|
83
114
|
}
|
|
115
|
+
objective;
|
|
84
116
|
planner;
|
|
117
|
+
worker;
|
|
85
118
|
completer;
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Maximum number of iterations
|
|
89
|
-
* Prevents infinite execution loops
|
|
90
|
-
*/
|
|
91
|
-
maxIterations;
|
|
119
|
+
stateManagement;
|
|
92
120
|
/**
|
|
93
|
-
*
|
|
94
|
-
*
|
|
121
|
+
* Compress execution state to prevent context overflow
|
|
122
|
+
* Uses reverse accumulation to efficiently find optimal task count
|
|
95
123
|
*/
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
};
|
|
122
|
-
let iterations = 0;
|
|
123
|
-
const maxIterations = this.maxIterations ?? DEFAULT_MAX_ITERATIONS;
|
|
124
|
-
while (iterations++ < maxIterations) {
|
|
125
|
-
const plan = await this.getFullPlan(result, options.context);
|
|
126
|
-
result.plan = plan;
|
|
127
|
-
if (plan.isComplete) {
|
|
128
|
-
return this.synthesizePlanResult(result, options.context);
|
|
124
|
+
compressState(state) {
|
|
125
|
+
const { maxTokens, keepRecent } = this.stateManagement ?? {};
|
|
126
|
+
if (!maxTokens && !keepRecent) {
|
|
127
|
+
return state;
|
|
128
|
+
}
|
|
129
|
+
const tasks = state.tasks;
|
|
130
|
+
let selectedTasks = tasks;
|
|
131
|
+
// Step 1: Apply keepRecent limit if configured
|
|
132
|
+
if (keepRecent && tasks.length > keepRecent) {
|
|
133
|
+
selectedTasks = tasks.slice(-keepRecent);
|
|
134
|
+
}
|
|
135
|
+
// Step 2: Apply maxTokens limit if configured
|
|
136
|
+
if (maxTokens && selectedTasks.length > 0) {
|
|
137
|
+
// Start from the most recent task and accumulate backwards
|
|
138
|
+
let accumulatedTokens = 0;
|
|
139
|
+
let taskCount = 0;
|
|
140
|
+
for (let i = selectedTasks.length - 1; i >= 0; i--) {
|
|
141
|
+
const taskJson = JSON.stringify(selectedTasks[i]);
|
|
142
|
+
const taskTokens = (0, token_estimator_js_1.estimateTokens)(taskJson);
|
|
143
|
+
if (accumulatedTokens + taskTokens > maxTokens && taskCount > 0) {
|
|
144
|
+
// Stop if adding this task would exceed limit
|
|
145
|
+
break;
|
|
146
|
+
}
|
|
147
|
+
accumulatedTokens += taskTokens;
|
|
148
|
+
taskCount++;
|
|
129
149
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
150
|
+
// Keep the most recent N tasks that fit within token limit
|
|
151
|
+
if (taskCount < selectedTasks.length) {
|
|
152
|
+
selectedTasks = selectedTasks.slice(-taskCount);
|
|
133
153
|
}
|
|
134
154
|
}
|
|
135
|
-
|
|
136
|
-
}
|
|
137
|
-
getFullPlanInput(planResult) {
|
|
138
|
-
return {
|
|
139
|
-
objective: planResult.objective,
|
|
140
|
-
steps: planResult.steps,
|
|
141
|
-
plan: {
|
|
142
|
-
status: planResult.status ? "Complete" : "In Progress",
|
|
143
|
-
result: planResult.result || "No results yet",
|
|
144
|
-
},
|
|
145
|
-
agents: this.skills.map((i) => ({
|
|
146
|
-
name: i.name,
|
|
147
|
-
description: i.description,
|
|
148
|
-
tools: i.skills.map((i) => ({ name: i.name, description: i.description })),
|
|
149
|
-
})),
|
|
150
|
-
};
|
|
151
|
-
}
|
|
152
|
-
async getFullPlan(planResult, context) {
|
|
153
|
-
return context.invoke(this.planner, this.getFullPlanInput(planResult));
|
|
155
|
+
return { tasks: selectedTasks };
|
|
154
156
|
}
|
|
155
|
-
async
|
|
156
|
-
|
|
157
|
-
...this.getFullPlanInput(planResult),
|
|
158
|
-
message: orchestrator_prompts_js_1.SYNTHESIZE_PLAN_USER_PROMPT_TEMPLATE,
|
|
159
|
-
});
|
|
160
|
-
}
|
|
161
|
-
async executeStep(planResult, step, context) {
|
|
162
|
-
const concurrency = this.tasksConcurrency ?? DEFAULT_TASK_CONCURRENCY;
|
|
163
|
-
const { model } = context;
|
|
157
|
+
async *process(input, options) {
|
|
158
|
+
const model = this.model || options.model || options.context.model;
|
|
164
159
|
if (!model)
|
|
165
160
|
throw new Error("model is required to run OrchestratorAgent");
|
|
166
|
-
const
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
161
|
+
const { tools: availableSkills = [] } = await this.objective.build({
|
|
162
|
+
...options,
|
|
163
|
+
input,
|
|
164
|
+
model,
|
|
165
|
+
agent: this,
|
|
166
|
+
});
|
|
167
|
+
const skills = availableSkills.map((i) => ({
|
|
168
|
+
name: i.function.name,
|
|
169
|
+
description: i.function.description,
|
|
170
|
+
}));
|
|
171
|
+
const { prompt: objective } = await this.objective.buildPrompt({
|
|
172
|
+
input,
|
|
173
|
+
context: options.context,
|
|
174
|
+
});
|
|
175
|
+
const executionState = { tasks: [] };
|
|
176
|
+
let iterationCount = 0;
|
|
177
|
+
const maxIterations = this.stateManagement?.maxIterations ?? type_js_1.DEFAULT_MAX_ITERATIONS;
|
|
178
|
+
while (true) {
|
|
179
|
+
// Check if maximum iterations reached
|
|
180
|
+
if (maxIterations && iterationCount >= maxIterations) {
|
|
181
|
+
console.warn(`Maximum iterations (${maxIterations}) reached. Stopping execution.`);
|
|
182
|
+
break;
|
|
179
183
|
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
result = getMessageOrJsonString(await context.invoke(executor, {}));
|
|
184
|
+
iterationCount++;
|
|
185
|
+
// Compress state for planner input if needed
|
|
186
|
+
const compressedState = this.compressState(executionState);
|
|
187
|
+
const plan = await this.invokeChildAgent(this.planner, { objective, skills, executionState: compressedState }, { ...options, model, streaming: false });
|
|
188
|
+
if (plan.finished || !plan.nextTask) {
|
|
189
|
+
break;
|
|
187
190
|
}
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
191
|
+
const task = plan.nextTask;
|
|
192
|
+
const createdAt = Date.now();
|
|
193
|
+
const taskResult = await this.invokeChildAgent(this.worker, { objective, executionState: compressedState, task }, { ...options, model, streaming: false })
|
|
194
|
+
.then((res) => {
|
|
195
|
+
if (res.error || res.success === false) {
|
|
196
|
+
return { status: "failed", result: res.result, error: res.error };
|
|
197
|
+
}
|
|
198
|
+
return { status: "completed", result: res.result };
|
|
199
|
+
})
|
|
200
|
+
.catch((error) => ({
|
|
201
|
+
status: "failed",
|
|
202
|
+
error: { message: error instanceof Error ? error.message : String(error) },
|
|
203
|
+
}));
|
|
204
|
+
executionState.tasks.push({
|
|
205
|
+
...taskResult,
|
|
206
|
+
task: task,
|
|
207
|
+
createdAt,
|
|
208
|
+
completedAt: Date.now(),
|
|
209
|
+
});
|
|
197
210
|
}
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
}), { objective: planResult.objective, step, tasks: results }));
|
|
202
|
-
if (!result)
|
|
203
|
-
throw new Error("unexpected empty result from synthesize step's tasks results");
|
|
204
|
-
return {
|
|
205
|
-
step,
|
|
206
|
-
tasks: results,
|
|
207
|
-
result,
|
|
208
|
-
};
|
|
211
|
+
// Compress state for completer input if needed
|
|
212
|
+
const compressedState = this.compressState(executionState);
|
|
213
|
+
yield* await this.invokeChildAgent(this.completer, { objective, executionState: compressedState }, { ...options, model, streaming: true });
|
|
209
214
|
}
|
|
210
215
|
}
|
|
211
216
|
exports.OrchestratorAgent = OrchestratorAgent;
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
const
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
217
|
+
exports.default = OrchestratorAgent;
|
|
218
|
+
function getOrchestratorAgentSchema({ filepath }) {
|
|
219
|
+
const nestAgentSchema = (0, agent_yaml_js_1.getNestAgentSchema)({ filepath });
|
|
220
|
+
const instructionsSchema = (0, agent_yaml_js_1.getInstructionsSchema)({ filepath });
|
|
221
|
+
return (0, schema_js_1.camelizeSchema)(zod_1.z.object({
|
|
222
|
+
objective: instructionsSchema,
|
|
223
|
+
planner: (0, schema_js_1.optionalize)(nestAgentSchema),
|
|
224
|
+
worker: (0, schema_js_1.optionalize)(nestAgentSchema),
|
|
225
|
+
completer: (0, schema_js_1.optionalize)(nestAgentSchema),
|
|
226
|
+
stateManagement: (0, schema_js_1.optionalize)((0, schema_js_1.camelizeSchema)(type_js_1.stateManagementOptionsSchema)),
|
|
227
|
+
}));
|
|
219
228
|
}
|
|
220
|
-
const orchestratorAgentOptionsSchema = zod_1.z.object({
|
|
221
|
-
maxIterations: zod_1.z.number().optional(),
|
|
222
|
-
tasksConcurrency: zod_1.z.number().optional(),
|
|
223
|
-
});
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export declare const ORCHESTRATOR_COMPLETE_PROMPT = "You are an intelligent assistant that synthesizes and presents the results of completed tasks.\n\n## User Objective\n{{ objective }}\n\n## Execution Results\n{{ executionState | yaml.stringify }}\n\n## Your Task\nBased on the execution results above, provide a comprehensive and helpful response to the user's objective.\n";
|
|
2
|
+
export declare const TODO_PLANNER_PROMPT_TEMPLATE = "You are an intelligent task planner that determines what needs to be done next to achieve the user's objective.\n\n## Your Role\nContinuously evaluate progress and decide the next task to execute. You work iteratively - planning one task at a time based on the current state and previous results.\n\n## Available Skills\n{{ skills | yaml.stringify }}\n\n## User Objective\n{{ objective }}\n\n## Current State\n{{ executionState | yaml.stringify }}\n\n## Understanding Task Status\nEach task in the execution state has a status:\n- **completed**: Task finished successfully, result is available\n- **failed**: Task encountered an error, check error field for details\n- **pending**: Task has not been executed yet\n\n## Your Task\nBased on the objective, current state, and any previous results, determine what should happen next:\n\n1. **If the objective is achieved or all work is complete:** Set finished: true and leave nextTask empty\n2. **If a previous task failed:** Decide whether to retry, skip, or use an alternative approach\n3. **If more work is needed:** Provide a clear, actionable nextTask description\n\n### Guidelines:\n- Focus on the immediate next step, not the entire plan\n- Review task history to avoid repeating work and build on previous results\n- Pay attention to task status - handle failures appropriately\n- Write self-contained task descriptions that the worker can execute independently\n- Set finished: true when the objective is satisfied\n- Consider retrying failed tasks with different approaches if appropriate\n";
|
|
3
|
+
export declare const TODO_WORKER_PROMPT_TEMPLATE = "You are a task execution agent. Your job is to execute the specific task assigned to you - nothing more, nothing less.\n\n## Overall Objective (For Context Only)\n{{ objective }}\n\n**CRITICAL CONSTRAINT**: The objective above is provided ONLY for context. You must NOT attempt to:\n- Solve the entire objective\n- Plan additional steps beyond your current task\n- Make decisions about what should happen next\n- Execute any tasks other than the one explicitly assigned to you below\n\nYour SOLE responsibility is to execute the specific task described below and return the result.\n\n## Current Execution State\n{{ executionState | yaml.stringify }}\n\n## Your Current Task\n{{ task }}\n\n## Important Instructions\n- Focus EXCLUSIVELY on completing the current task described above\n- The task is self-contained - execute it completely and accurately\n- Do NOT perform additional tasks beyond what is specified\n- Do NOT try to determine what should happen after this task\n- Use the available tools and skills to accomplish this specific task\n- Return a clear result that the planner can use to decide the next step\n\n## Output Format\nReturn your task execution result as a structured response. The output schema will guide you on the required fields.\n";
|