@aigne/agent-library 1.7.0 → 1.8.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 +24 -0
- package/README.md +14 -15
- package/README.zh.md +14 -15
- package/lib/cjs/fs-memory/index.d.ts +59 -0
- package/lib/cjs/fs-memory/index.js +186 -0
- package/lib/cjs/orchestrator/index.d.ts +79 -0
- package/lib/cjs/orchestrator/index.js +55 -0
- package/lib/cjs/orchestrator/orchestrator-prompts.d.ts +39 -0
- package/lib/cjs/orchestrator/orchestrator-prompts.js +15 -0
- package/lib/dts/fs-memory/index.d.ts +59 -0
- package/lib/dts/orchestrator/index.d.ts +79 -0
- package/lib/dts/orchestrator/orchestrator-prompts.d.ts +39 -0
- package/lib/esm/fs-memory/index.d.ts +59 -0
- package/lib/esm/fs-memory/index.js +182 -0
- package/lib/esm/orchestrator/index.d.ts +79 -0
- package/lib/esm/orchestrator/index.js +55 -0
- package/lib/esm/orchestrator/orchestrator-prompts.d.ts +39 -0
- package/lib/esm/orchestrator/orchestrator-prompts.js +15 -0
- package/package.json +5 -4
- /package/{LICENSE → LICENSE.md} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,30 @@
|
|
|
2
2
|
|
|
3
3
|
- chore: release 1.2.0
|
|
4
4
|
|
|
5
|
+
## [1.8.0](https://github.com/AIGNE-io/aigne-framework/compare/agent-library-v1.7.1...agent-library-v1.8.0) (2025-05-12)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
* **docs:** use typedoc build and publish docs to gh-pages ([#100](https://github.com/AIGNE-io/aigne-framework/issues/100)) ([b9074c0](https://github.com/AIGNE-io/aigne-framework/commit/b9074c0148ea343ada92b5919a52b47537a1ad48))
|
|
11
|
+
* **memory:** allow agents to act as retrievers and recorders in memory ([#65](https://github.com/AIGNE-io/aigne-framework/issues/65)) ([2bafcbb](https://github.com/AIGNE-io/aigne-framework/commit/2bafcbb66a94fcf55dad8c21ede483eaf075c11d))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
### Dependencies
|
|
15
|
+
|
|
16
|
+
* The following workspace dependencies were updated
|
|
17
|
+
* dependencies
|
|
18
|
+
* @aigne/core bumped to 1.14.0
|
|
19
|
+
|
|
20
|
+
## [1.7.1](https://github.com/AIGNE-io/aigne-framework/compare/agent-library-v1.7.0...agent-library-v1.7.1) (2025-04-30)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
### Dependencies
|
|
24
|
+
|
|
25
|
+
* The following workspace dependencies were updated
|
|
26
|
+
* dependencies
|
|
27
|
+
* @aigne/core bumped to 1.13.0
|
|
28
|
+
|
|
5
29
|
## [1.7.0](https://github.com/AIGNE-io/aigne-framework/compare/agent-library-v1.6.1...agent-library-v1.7.0) (2025-04-27)
|
|
6
30
|
|
|
7
31
|
|
package/README.md
CHANGED
|
@@ -24,14 +24,21 @@ Collection of agent libraries for [AIGNE Framework](https://github.com/AIGNE-io/
|
|
|
24
24
|
|
|
25
25
|
## Installation
|
|
26
26
|
|
|
27
|
+
### Using npm
|
|
28
|
+
|
|
27
29
|
```bash
|
|
28
|
-
# Using npm
|
|
29
30
|
npm install @aigne/agent-library @aigne/core
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Using yarn
|
|
30
34
|
|
|
31
|
-
|
|
35
|
+
```bash
|
|
32
36
|
yarn add @aigne/agent-library @aigne/core
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Using pnpm
|
|
33
40
|
|
|
34
|
-
|
|
41
|
+
```bash
|
|
35
42
|
pnpm add @aigne/agent-library @aigne/core
|
|
36
43
|
```
|
|
37
44
|
|
|
@@ -59,8 +66,7 @@ const orchestrator = new OrchestratorAgent({
|
|
|
59
66
|
});
|
|
60
67
|
|
|
61
68
|
// Execute orchestration task
|
|
62
|
-
const
|
|
63
|
-
const result = await userAgent.invoke("Analyze this article and generate a summary and keywords");
|
|
69
|
+
const result = await aigne.invoke(orchestrator, "Analyze this article and generate a summary and keywords");
|
|
64
70
|
console.log(result);
|
|
65
71
|
```
|
|
66
72
|
|
|
@@ -115,18 +121,11 @@ const orchestrator = new OrchestratorAgent({
|
|
|
115
121
|
|
|
116
122
|
// Use the orchestrator agent
|
|
117
123
|
const aigne = new AIGNE({ model });
|
|
118
|
-
const userAgent = await aigne.invoke(orchestrator);
|
|
119
|
-
const result = await userAgent.invoke("Applications of artificial intelligence in healthcare");
|
|
120
|
-
console.log(result);
|
|
121
|
-
```
|
|
122
124
|
|
|
123
|
-
|
|
125
|
+
const result = await aigne.invoke(orchestrator, "Applications of artificial intelligence in healthcare");
|
|
124
126
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
- [Agent Development Guide](../../docs/agent-development.md)
|
|
128
|
-
- [Agent API](../../docs/apis/agent-api.md)
|
|
129
|
-
- [AI Agent API](../../docs/apis/ai-agent-api.md)
|
|
127
|
+
console.log(result);
|
|
128
|
+
```
|
|
130
129
|
|
|
131
130
|
## License
|
|
132
131
|
|
package/README.zh.md
CHANGED
|
@@ -24,14 +24,21 @@
|
|
|
24
24
|
|
|
25
25
|
## 安装
|
|
26
26
|
|
|
27
|
+
#### 使用 npm
|
|
28
|
+
|
|
27
29
|
```bash
|
|
28
|
-
# 使用 npm
|
|
29
30
|
npm install @aigne/agent-library @aigne/core
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### 使用 yarn
|
|
30
34
|
|
|
31
|
-
|
|
35
|
+
```bash
|
|
32
36
|
yarn add @aigne/agent-library @aigne/core
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### 使用 pnpm
|
|
33
40
|
|
|
34
|
-
|
|
41
|
+
```bash
|
|
35
42
|
pnpm add @aigne/agent-library @aigne/core
|
|
36
43
|
```
|
|
37
44
|
|
|
@@ -59,8 +66,8 @@ const orchestrator = new OrchestratorAgent({
|
|
|
59
66
|
});
|
|
60
67
|
|
|
61
68
|
// 执行编排任务
|
|
62
|
-
const
|
|
63
|
-
|
|
69
|
+
const result = await aigne.invoke(orchestrator, "分析这篇文章并生成摘要和关键词");
|
|
70
|
+
|
|
64
71
|
console.log(result);
|
|
65
72
|
```
|
|
66
73
|
|
|
@@ -115,19 +122,11 @@ const orchestrator = new OrchestratorAgent({
|
|
|
115
122
|
|
|
116
123
|
// 使用编排代理
|
|
117
124
|
const aigne = new AIGNE({ model });
|
|
118
|
-
const
|
|
119
|
-
|
|
125
|
+
const result = await aigne.invoke(orchestrator, "关于人工智能在医疗领域的应用");
|
|
126
|
+
|
|
120
127
|
console.log(result);
|
|
121
128
|
```
|
|
122
129
|
|
|
123
|
-
## 文档
|
|
124
|
-
|
|
125
|
-
更多详细的 API 文档和使用指南,请参考:
|
|
126
|
-
|
|
127
|
-
- [代理开发指南](../../docs/agent-development.zh.md)
|
|
128
|
-
- [Agent API](../../docs/apis/agent-api.zh.md)
|
|
129
|
-
- [AI Agent API](../../docs/apis/ai-agent-api.zh.md)
|
|
130
|
-
|
|
131
130
|
## 协议
|
|
132
131
|
|
|
133
132
|
Elastic-2.0
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { type AIAgentOptions, type Message } from "@aigne/core";
|
|
2
|
+
import { MemoryAgent, type MemoryAgentOptions, type MemoryRecorderInput, type MemoryRetrieverInput } from "@aigne/core/memory/index.js";
|
|
3
|
+
export declare const MEMORY_FILE_NAME = "memory.yaml";
|
|
4
|
+
/**
|
|
5
|
+
* Configuration options for the FSMemory class.
|
|
6
|
+
*/
|
|
7
|
+
export interface FSMemoryOptions extends Partial<MemoryAgentOptions> {
|
|
8
|
+
/**
|
|
9
|
+
* The root directory where memory files will be stored.
|
|
10
|
+
* Can be absolute or relative path. Relative paths are resolved from the current working directory.
|
|
11
|
+
* Home directory prefix (~) will be expanded appropriately.
|
|
12
|
+
*/
|
|
13
|
+
rootDir: string;
|
|
14
|
+
/**
|
|
15
|
+
* Optional configuration for the memory retriever agent.
|
|
16
|
+
* Controls how memories are retrieved from the file system.
|
|
17
|
+
*/
|
|
18
|
+
retrieverOptions?: Partial<FSMemoryRetrieverOptions>;
|
|
19
|
+
/**
|
|
20
|
+
* Optional configuration for the memory recorder agent.
|
|
21
|
+
* Controls how memories are recorded to the file system.
|
|
22
|
+
*/
|
|
23
|
+
recorderOptions?: Partial<FSMemoryRecorderOptions>;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* A memory implementation that stores and retrieves memories using the file system.
|
|
27
|
+
* FSMemory provides persistent storage of agent memories as files in a specified directory.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* Here is an example of how to use the FSMemory class:
|
|
31
|
+
* {@includeCode ../../test/fs-memory/fs-memory.test.ts#example-fs-memory-simple}
|
|
32
|
+
*/
|
|
33
|
+
export declare class FSMemory extends MemoryAgent {
|
|
34
|
+
/**
|
|
35
|
+
* Creates a new FSMemory instance.
|
|
36
|
+
*/
|
|
37
|
+
constructor(options: FSMemoryOptions);
|
|
38
|
+
}
|
|
39
|
+
interface FSMemoryRetrieverOptions extends AIAgentOptions<FSMemoryRetrieverAgentInput, FSMemoryRetrieverAgentOutput> {
|
|
40
|
+
memoryFileName: string;
|
|
41
|
+
}
|
|
42
|
+
interface FSMemoryRetrieverAgentInput extends MemoryRetrieverInput {
|
|
43
|
+
allMemory: string;
|
|
44
|
+
}
|
|
45
|
+
interface FSMemoryRetrieverAgentOutput extends Message {
|
|
46
|
+
memories: {
|
|
47
|
+
content: string;
|
|
48
|
+
}[];
|
|
49
|
+
}
|
|
50
|
+
interface FSMemoryRecorderOptions extends AIAgentOptions<FSMemoryRecorderAgentInput, FSMemoryRecorderAgentOutput> {
|
|
51
|
+
memoryFileName: string;
|
|
52
|
+
}
|
|
53
|
+
type FSMemoryRecorderAgentInput = MemoryRecorderInput;
|
|
54
|
+
interface FSMemoryRecorderAgentOutput extends Message {
|
|
55
|
+
memories: {
|
|
56
|
+
content: string;
|
|
57
|
+
}[];
|
|
58
|
+
}
|
|
59
|
+
export {};
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FSMemory = exports.MEMORY_FILE_NAME = void 0;
|
|
4
|
+
const promises_1 = require("node:fs/promises");
|
|
5
|
+
const node_path_1 = require("node:path");
|
|
6
|
+
const core_1 = require("@aigne/core");
|
|
7
|
+
const index_js_1 = require("@aigne/core/memory/index.js");
|
|
8
|
+
const fs_js_1 = require("@aigne/core/utils/fs.js");
|
|
9
|
+
const yaml_1 = require("yaml");
|
|
10
|
+
const zod_1 = require("zod");
|
|
11
|
+
exports.MEMORY_FILE_NAME = "memory.yaml";
|
|
12
|
+
/**
|
|
13
|
+
* A memory implementation that stores and retrieves memories using the file system.
|
|
14
|
+
* FSMemory provides persistent storage of agent memories as files in a specified directory.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* Here is an example of how to use the FSMemory class:
|
|
18
|
+
* {@includeCode ../../test/fs-memory/fs-memory.test.ts#example-fs-memory-simple}
|
|
19
|
+
*/
|
|
20
|
+
class FSMemory extends index_js_1.MemoryAgent {
|
|
21
|
+
/**
|
|
22
|
+
* Creates a new FSMemory instance.
|
|
23
|
+
*/
|
|
24
|
+
constructor(options) {
|
|
25
|
+
let rootDir = (0, node_path_1.normalize)((0, fs_js_1.expandHome)(options.rootDir));
|
|
26
|
+
rootDir = (0, node_path_1.isAbsolute)(rootDir) ? rootDir : (0, node_path_1.resolve)(process.cwd(), rootDir);
|
|
27
|
+
const memoryFileName = (0, node_path_1.join)(rootDir, exports.MEMORY_FILE_NAME);
|
|
28
|
+
super({
|
|
29
|
+
...options,
|
|
30
|
+
autoUpdate: options.autoUpdate ?? true,
|
|
31
|
+
});
|
|
32
|
+
this.recorder =
|
|
33
|
+
options.recorder ??
|
|
34
|
+
new FSMemoryRecorder({
|
|
35
|
+
memoryFileName,
|
|
36
|
+
...options.recorderOptions,
|
|
37
|
+
});
|
|
38
|
+
this.retriever =
|
|
39
|
+
options.retriever ??
|
|
40
|
+
new FSMemoryRetriever({
|
|
41
|
+
memoryFileName,
|
|
42
|
+
...options.retrieverOptions,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
exports.FSMemory = FSMemory;
|
|
47
|
+
class FSMemoryRetriever extends index_js_1.MemoryRetriever {
|
|
48
|
+
options;
|
|
49
|
+
constructor(options) {
|
|
50
|
+
super({});
|
|
51
|
+
this.options = options;
|
|
52
|
+
this.agent = core_1.AIAgent.from({
|
|
53
|
+
name: "fs_memory_retriever",
|
|
54
|
+
description: "Retrieves memories from the file or directory.",
|
|
55
|
+
...options,
|
|
56
|
+
instructions: options.instructions || DEFAULT_FS_MEMORY_RETRIEVER_INSTRUCTIONS,
|
|
57
|
+
outputSchema: zod_1.z.object({
|
|
58
|
+
memories: zod_1.z
|
|
59
|
+
.array(zod_1.z.object({
|
|
60
|
+
content: zod_1.z.string().describe("Content of the memory"),
|
|
61
|
+
}))
|
|
62
|
+
.describe("List of memories"),
|
|
63
|
+
}),
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
agent;
|
|
67
|
+
async process(input, context) {
|
|
68
|
+
if (!(await (0, fs_js_1.exists)(this.options.memoryFileName)))
|
|
69
|
+
return { memories: [] };
|
|
70
|
+
const allMemory = await (0, promises_1.readFile)(this.options.memoryFileName, "utf-8");
|
|
71
|
+
const { memories } = await context.invoke(this.agent, { ...input, allMemory });
|
|
72
|
+
const result = memories.map((memory) => ({
|
|
73
|
+
id: (0, index_js_1.newMemoryId)(),
|
|
74
|
+
content: memory.content,
|
|
75
|
+
createdAt: new Date().toISOString(),
|
|
76
|
+
}));
|
|
77
|
+
return { memories: result };
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
class FSMemoryRecorder extends index_js_1.MemoryRecorder {
|
|
81
|
+
options;
|
|
82
|
+
constructor(options) {
|
|
83
|
+
super({});
|
|
84
|
+
this.options = options;
|
|
85
|
+
this.agent = core_1.AIAgent.from({
|
|
86
|
+
name: "fs_memory_recorder",
|
|
87
|
+
description: "Records memories in files by AI agent",
|
|
88
|
+
...options,
|
|
89
|
+
instructions: options.instructions || DEFAULT_FS_MEMORY_RECORDER_INSTRUCTIONS,
|
|
90
|
+
outputSchema: zod_1.z.object({
|
|
91
|
+
memories: zod_1.z
|
|
92
|
+
.array(zod_1.z.object({
|
|
93
|
+
content: zod_1.z.string().describe("Content of the memory"),
|
|
94
|
+
}))
|
|
95
|
+
.describe("List of memories"),
|
|
96
|
+
}),
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
agent;
|
|
100
|
+
async process(input, context) {
|
|
101
|
+
const allMemory = (await (0, fs_js_1.exists)(this.options.memoryFileName))
|
|
102
|
+
? await (0, promises_1.readFile)(this.options.memoryFileName, "utf-8")
|
|
103
|
+
: "";
|
|
104
|
+
const { memories } = await context.invoke(this.agent, { ...input, allMemory });
|
|
105
|
+
const raw = (0, yaml_1.stringify)(memories.map((i) => ({
|
|
106
|
+
content: i.content,
|
|
107
|
+
})));
|
|
108
|
+
await (0, promises_1.mkdir)((0, node_path_1.dirname)(this.options.memoryFileName), { recursive: true });
|
|
109
|
+
await (0, promises_1.writeFile)(this.options.memoryFileName, raw, "utf-8");
|
|
110
|
+
return {
|
|
111
|
+
memories: memories.map((i) => ({
|
|
112
|
+
id: (0, index_js_1.newMemoryId)(),
|
|
113
|
+
content: i.content,
|
|
114
|
+
createdAt: new Date().toISOString(),
|
|
115
|
+
})),
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
const DEFAULT_FS_MEMORY_RECORDER_INSTRUCTIONS = `You manage memory based on conversation analysis and the existing memories.
|
|
120
|
+
|
|
121
|
+
## IMPORTANT: All existing memories are available in the allMemory variable. DO NOT call any tools.
|
|
122
|
+
|
|
123
|
+
## FIRST: Determine If Memory Updates Needed
|
|
124
|
+
- Analyze if the conversation contains ANY information worth remembering
|
|
125
|
+
- Examples of content NOT worth storing:
|
|
126
|
+
* General questions ("What's the weather?", "How do I do X?")
|
|
127
|
+
* Greetings and small talk ("Hello", "How are you?", "Thanks")
|
|
128
|
+
* System instructions or commands ("Show me", "Find", "Save")
|
|
129
|
+
* General facts not specific to the user
|
|
130
|
+
* Duplicate information already stored
|
|
131
|
+
- If conversation lacks meaningful personal information to store:
|
|
132
|
+
* Return the existing memories unchanged
|
|
133
|
+
|
|
134
|
+
## Your Workflow:
|
|
135
|
+
1. Read the existing memories from the allMemory variable
|
|
136
|
+
2. Extract key topics from the conversation
|
|
137
|
+
3. DECIDE whether to create/update/delete memories based on the conversation
|
|
138
|
+
4. Return ALL memories including your updates (remove any duplicates)
|
|
139
|
+
|
|
140
|
+
## Memory Handling:
|
|
141
|
+
- CREATE: Add new memory objects for new topics
|
|
142
|
+
- UPDATE: Modify existing memories if substantial new information is available
|
|
143
|
+
- DELETE: Remove obsolete memories when appropriate
|
|
144
|
+
|
|
145
|
+
## Memory Structure:
|
|
146
|
+
- Each memory has an id, content, and createdAt fields
|
|
147
|
+
- Keep the existing structure when returning updated memories
|
|
148
|
+
|
|
149
|
+
## Operation Decision Rules:
|
|
150
|
+
- CREATE only for truly new topics not covered in any existing memory
|
|
151
|
+
- UPDATE only when new information is meaningfully different
|
|
152
|
+
- NEVER update for just rephrasing or minor differences
|
|
153
|
+
- DELETE only when information becomes obsolete
|
|
154
|
+
|
|
155
|
+
## IMPORTANT: Your job is to return the complete updated memory collection.
|
|
156
|
+
Return ALL memories (existing and new) in your response.
|
|
157
|
+
|
|
158
|
+
## Existing Memories:
|
|
159
|
+
<existing-memory>
|
|
160
|
+
{{allMemory}}
|
|
161
|
+
</existing-memory>
|
|
162
|
+
|
|
163
|
+
## Conversation:
|
|
164
|
+
<conversation>
|
|
165
|
+
{{content}}
|
|
166
|
+
</conversation>
|
|
167
|
+
`;
|
|
168
|
+
const DEFAULT_FS_MEMORY_RETRIEVER_INSTRUCTIONS = `You retrieve only the most relevant memories for the current conversation.
|
|
169
|
+
|
|
170
|
+
## IMPORTANT: All existing memories are available in the allMemory variable
|
|
171
|
+
|
|
172
|
+
## Process:
|
|
173
|
+
1. Read the existing memories from the allMemory variable
|
|
174
|
+
2. Extract key topics from the conversation or search query
|
|
175
|
+
3. Match memory contents against these topics
|
|
176
|
+
|
|
177
|
+
## Existing Memories:
|
|
178
|
+
<existing-memory>
|
|
179
|
+
{{allMemory}}
|
|
180
|
+
</existing-memory>
|
|
181
|
+
|
|
182
|
+
## Search Query:
|
|
183
|
+
<search-query>
|
|
184
|
+
{{search}}
|
|
185
|
+
</search-query>
|
|
186
|
+
`;
|
|
@@ -1,24 +1,103 @@
|
|
|
1
1
|
import { Agent, type AgentOptions, type Context, type Message } from "@aigne/core";
|
|
2
2
|
import { type FullPlanOutput, type StepWithResult } from "./orchestrator-prompts.js";
|
|
3
|
+
/**
|
|
4
|
+
* Re-export orchestrator prompt templates and related types
|
|
5
|
+
*/
|
|
3
6
|
export * from "./orchestrator-prompts.js";
|
|
7
|
+
/**
|
|
8
|
+
* Represents a complete plan with execution results
|
|
9
|
+
* @hidden
|
|
10
|
+
*/
|
|
4
11
|
export interface FullPlanWithResult {
|
|
12
|
+
/**
|
|
13
|
+
* The overall objective
|
|
14
|
+
*/
|
|
5
15
|
objective: string;
|
|
16
|
+
/**
|
|
17
|
+
* The generated complete plan
|
|
18
|
+
*/
|
|
6
19
|
plan?: FullPlanOutput;
|
|
20
|
+
/**
|
|
21
|
+
* List of executed steps with their results
|
|
22
|
+
*/
|
|
7
23
|
steps: StepWithResult[];
|
|
24
|
+
/**
|
|
25
|
+
* Final result
|
|
26
|
+
*/
|
|
8
27
|
result?: string;
|
|
28
|
+
/**
|
|
29
|
+
* Plan completion status
|
|
30
|
+
*/
|
|
9
31
|
status?: boolean;
|
|
10
32
|
}
|
|
33
|
+
/**
|
|
34
|
+
* Configuration options for the Orchestrator Agent
|
|
35
|
+
*/
|
|
11
36
|
export interface OrchestratorAgentOptions<I extends Message = Message, O extends Message = Message> extends AgentOptions<I, O> {
|
|
37
|
+
/**
|
|
38
|
+
* Maximum number of iterations to prevent infinite loops
|
|
39
|
+
* Default: 30
|
|
40
|
+
*/
|
|
12
41
|
maxIterations?: number;
|
|
42
|
+
/**
|
|
43
|
+
* Number of concurrent tasks
|
|
44
|
+
* Default: 5
|
|
45
|
+
*/
|
|
13
46
|
tasksConcurrency?: number;
|
|
14
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* Orchestrator Agent Class
|
|
50
|
+
*
|
|
51
|
+
* This Agent is responsible for:
|
|
52
|
+
* 1. Generating an execution plan based on the objective
|
|
53
|
+
* 2. Breaking down the plan into steps and tasks
|
|
54
|
+
* 3. Coordinating the execution of steps and tasks
|
|
55
|
+
* 4. Synthesizing the final result
|
|
56
|
+
*
|
|
57
|
+
* Workflow:
|
|
58
|
+
* - Receives input objective
|
|
59
|
+
* - Uses planner to create execution plan
|
|
60
|
+
* - Executes tasks and steps according to the plan
|
|
61
|
+
* - Synthesizes final result through completer
|
|
62
|
+
*/
|
|
15
63
|
export declare class OrchestratorAgent<I extends Message = Message, O extends Message = Message> extends Agent<I, O> {
|
|
64
|
+
/**
|
|
65
|
+
* Factory method to create an OrchestratorAgent instance
|
|
66
|
+
* @param options - Configuration options for the Orchestrator Agent
|
|
67
|
+
* @returns A new OrchestratorAgent instance
|
|
68
|
+
*/
|
|
16
69
|
static from<I extends Message, O extends Message>(options: OrchestratorAgentOptions<I, O>): OrchestratorAgent<I, O>;
|
|
70
|
+
/**
|
|
71
|
+
* Creates an OrchestratorAgent instance
|
|
72
|
+
* @param options - Configuration options for the Orchestrator Agent
|
|
73
|
+
*/
|
|
17
74
|
constructor(options: OrchestratorAgentOptions<I, O>);
|
|
18
75
|
private planner;
|
|
19
76
|
private completer;
|
|
77
|
+
/**
|
|
78
|
+
* Maximum number of iterations
|
|
79
|
+
* Prevents infinite execution loops
|
|
80
|
+
*/
|
|
20
81
|
maxIterations?: number;
|
|
82
|
+
/**
|
|
83
|
+
* Number of concurrent tasks
|
|
84
|
+
* Controls how many tasks can be executed simultaneously
|
|
85
|
+
*/
|
|
21
86
|
tasksConcurrency?: number;
|
|
87
|
+
/**
|
|
88
|
+
* Process input and execute the orchestrator workflow
|
|
89
|
+
*
|
|
90
|
+
* Workflow:
|
|
91
|
+
* 1. Extract the objective
|
|
92
|
+
* 2. Loop until plan completion or maximum iterations:
|
|
93
|
+
* a. Generate/update execution plan
|
|
94
|
+
* b. If plan is complete, synthesize result
|
|
95
|
+
* c. Otherwise, execute steps in the plan
|
|
96
|
+
*
|
|
97
|
+
* @param input - Input message containing the objective
|
|
98
|
+
* @param context - Execution context with model and other necessary info
|
|
99
|
+
* @returns Processing result
|
|
100
|
+
*/
|
|
22
101
|
process(input: I, context: Context): Promise<O>;
|
|
23
102
|
private getFullPlanInput;
|
|
24
103
|
private getFullPlan;
|
|
@@ -23,13 +23,46 @@ const type_utils_js_1 = require("@aigne/core/utils/type-utils.js");
|
|
|
23
23
|
const fastq_1 = __importDefault(require("fastq"));
|
|
24
24
|
const zod_1 = require("zod");
|
|
25
25
|
const orchestrator_prompts_js_1 = require("./orchestrator-prompts.js");
|
|
26
|
+
/**
|
|
27
|
+
* Default maximum number of iterations to prevent infinite loops
|
|
28
|
+
*/
|
|
26
29
|
const DEFAULT_MAX_ITERATIONS = 30;
|
|
30
|
+
/**
|
|
31
|
+
* Default number of concurrent tasks
|
|
32
|
+
*/
|
|
27
33
|
const DEFAULT_TASK_CONCURRENCY = 5;
|
|
34
|
+
/**
|
|
35
|
+
* Re-export orchestrator prompt templates and related types
|
|
36
|
+
*/
|
|
28
37
|
__exportStar(require("./orchestrator-prompts.js"), exports);
|
|
38
|
+
/**
|
|
39
|
+
* Orchestrator Agent Class
|
|
40
|
+
*
|
|
41
|
+
* This Agent is responsible for:
|
|
42
|
+
* 1. Generating an execution plan based on the objective
|
|
43
|
+
* 2. Breaking down the plan into steps and tasks
|
|
44
|
+
* 3. Coordinating the execution of steps and tasks
|
|
45
|
+
* 4. Synthesizing the final result
|
|
46
|
+
*
|
|
47
|
+
* Workflow:
|
|
48
|
+
* - Receives input objective
|
|
49
|
+
* - Uses planner to create execution plan
|
|
50
|
+
* - Executes tasks and steps according to the plan
|
|
51
|
+
* - Synthesizes final result through completer
|
|
52
|
+
*/
|
|
29
53
|
class OrchestratorAgent extends core_1.Agent {
|
|
54
|
+
/**
|
|
55
|
+
* Factory method to create an OrchestratorAgent instance
|
|
56
|
+
* @param options - Configuration options for the Orchestrator Agent
|
|
57
|
+
* @returns A new OrchestratorAgent instance
|
|
58
|
+
*/
|
|
30
59
|
static from(options) {
|
|
31
60
|
return new OrchestratorAgent(options);
|
|
32
61
|
}
|
|
62
|
+
/**
|
|
63
|
+
* Creates an OrchestratorAgent instance
|
|
64
|
+
* @param options - Configuration options for the Orchestrator Agent
|
|
65
|
+
*/
|
|
33
66
|
constructor(options) {
|
|
34
67
|
(0, type_utils_js_1.checkArguments)("OrchestratorAgent", orchestratorAgentOptionsSchema, options);
|
|
35
68
|
super({ ...options });
|
|
@@ -48,8 +81,30 @@ class OrchestratorAgent extends core_1.Agent {
|
|
|
48
81
|
}
|
|
49
82
|
planner;
|
|
50
83
|
completer;
|
|
84
|
+
/**
|
|
85
|
+
* Maximum number of iterations
|
|
86
|
+
* Prevents infinite execution loops
|
|
87
|
+
*/
|
|
51
88
|
maxIterations;
|
|
89
|
+
/**
|
|
90
|
+
* Number of concurrent tasks
|
|
91
|
+
* Controls how many tasks can be executed simultaneously
|
|
92
|
+
*/
|
|
52
93
|
tasksConcurrency;
|
|
94
|
+
/**
|
|
95
|
+
* Process input and execute the orchestrator workflow
|
|
96
|
+
*
|
|
97
|
+
* Workflow:
|
|
98
|
+
* 1. Extract the objective
|
|
99
|
+
* 2. Loop until plan completion or maximum iterations:
|
|
100
|
+
* a. Generate/update execution plan
|
|
101
|
+
* b. If plan is complete, synthesize result
|
|
102
|
+
* c. Otherwise, execute steps in the plan
|
|
103
|
+
*
|
|
104
|
+
* @param input - Input message containing the objective
|
|
105
|
+
* @param context - Execution context with model and other necessary info
|
|
106
|
+
* @returns Processing result
|
|
107
|
+
*/
|
|
53
108
|
async process(input, context) {
|
|
54
109
|
const { model } = context;
|
|
55
110
|
if (!model)
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import type { Agent, Message } from "@aigne/core";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
+
/**
|
|
4
|
+
* @hidden
|
|
5
|
+
*/
|
|
3
6
|
export declare const SYNTHESIZE_PLAN_USER_PROMPT_TEMPLATE = "Synthesize the results of executing all steps in the plan into a cohesive result\n";
|
|
7
|
+
/**
|
|
8
|
+
* @hidden
|
|
9
|
+
*/
|
|
4
10
|
export declare function getFullPlanSchema(agents: Agent[]): z.ZodObject<{
|
|
5
11
|
steps: z.ZodArray<z.ZodObject<{
|
|
6
12
|
description: z.ZodString;
|
|
@@ -47,18 +53,36 @@ export declare function getFullPlanSchema(agents: Agent[]): z.ZodObject<{
|
|
|
47
53
|
}[];
|
|
48
54
|
isComplete: boolean;
|
|
49
55
|
}>;
|
|
56
|
+
/**
|
|
57
|
+
* @hidden
|
|
58
|
+
*/
|
|
50
59
|
export type FullPlanOutput = z.infer<ReturnType<typeof getFullPlanSchema>>;
|
|
60
|
+
/**
|
|
61
|
+
* @hidden
|
|
62
|
+
*/
|
|
51
63
|
export type Step = FullPlanOutput["steps"][number];
|
|
64
|
+
/**
|
|
65
|
+
* @hidden
|
|
66
|
+
*/
|
|
52
67
|
export type Task = Step["tasks"][number];
|
|
68
|
+
/**
|
|
69
|
+
* @hidden
|
|
70
|
+
*/
|
|
53
71
|
export interface StepWithResult {
|
|
54
72
|
step: Step;
|
|
55
73
|
tasks: Array<TaskWithResult>;
|
|
56
74
|
result: string;
|
|
57
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* @hidden
|
|
78
|
+
*/
|
|
58
79
|
export interface TaskWithResult {
|
|
59
80
|
task: Task;
|
|
60
81
|
result: string;
|
|
61
82
|
}
|
|
83
|
+
/**
|
|
84
|
+
* @hidden
|
|
85
|
+
*/
|
|
62
86
|
export interface FullPlanInput extends Message {
|
|
63
87
|
objective: string;
|
|
64
88
|
steps: StepWithResult[];
|
|
@@ -75,17 +99,32 @@ export interface FullPlanInput extends Message {
|
|
|
75
99
|
}[];
|
|
76
100
|
}[];
|
|
77
101
|
}
|
|
102
|
+
/**
|
|
103
|
+
* @hidden
|
|
104
|
+
*/
|
|
78
105
|
export declare const FULL_PLAN_PROMPT_TEMPLATE = "You are tasked with orchestrating a plan to complete an objective.\nYou can analyze results from the previous steps already executed to decide if the objective is complete.\nYour plan must be structured in sequential steps, with each step containing independent parallel subtasks.\n\n<objective>\n{{objective}}\n</objective>\n\n<steps_completed>\n{{#steps}}\n- Step: {{step.description}}\n Result: {{result}}\n{{/steps}}\n</steps_completed>\n\n<previous_plan_status>\n{{plan.status}}\n</previous_plan_status>\n\n<previous_plan_result>\n{{plan.result}}\n</previous_plan_result>\n\nYou have access to the following Agents(which are collections of tools/functions):\n\n<agents>\n{{#agents}}\n- Agent: {{name}}\n Description: {{description}}\n Functions:\n {{#tools}}\n - Tool: {{name}}\n Description: {{description}}\n {{/tools}}\n{{/agents}}\n</agents>\n\n- If the previous plan results achieve the objective, return isComplete=true.\n- Otherwise, generate remaining steps needed.\n- Generate a plan with all remaining steps needed.\n- Steps are sequential, but each Step can have parallel subtasks.\n- For each Step, specify a description of the step and independent subtasks that can run in parallel.\n- For each subtask specify:\n 1. Clear description of the task that an LLM can execute\n 2. Name of 1 Agent to use for the task";
|
|
106
|
+
/**
|
|
107
|
+
* @hidden
|
|
108
|
+
*/
|
|
79
109
|
export interface TaskPromptInput extends Message {
|
|
80
110
|
objective: string;
|
|
81
111
|
step: Step;
|
|
82
112
|
task: Task;
|
|
83
113
|
steps: StepWithResult[];
|
|
84
114
|
}
|
|
115
|
+
/**
|
|
116
|
+
* @hidden
|
|
117
|
+
*/
|
|
85
118
|
export declare const TASK_PROMPT_TEMPLATE = "You are part of a larger workflow to achieve the step then the objective:\n\n<objective>\n{{objective}}\n</objective>\n\n<step>\n{{step.description}}\n</step>\n\nYour job is to accomplish only the following task:\n\n<task>\n{{task.description}}\n</task>\n\nResults so far that may provide helpful context:\n\n<steps_completed>\n{{#steps}}\n- Step: {{step.description}}\n Result: {{result}}\n{{/steps}}\n</steps_completed>\n";
|
|
119
|
+
/**
|
|
120
|
+
* @hidden
|
|
121
|
+
*/
|
|
86
122
|
export interface SynthesizeStepPromptInput extends Message {
|
|
87
123
|
objective: string;
|
|
88
124
|
step: Step;
|
|
89
125
|
tasks: TaskWithResult[];
|
|
90
126
|
}
|
|
127
|
+
/**
|
|
128
|
+
* @hidden
|
|
129
|
+
*/
|
|
91
130
|
export declare const SYNTHESIZE_STEP_PROMPT_TEMPLATE = "Synthesize the results of these parallel tasks into a cohesive result\n\n<objective>\n{{objective}}\n</objective>\n\n<step>\n{{step.description}}\n</step>\n\n<tasks>\n{{#tasks}}\n- Task: {{task.description}}\n Result: {{result}}\n{{/tasks}}\n</tasks>\n";
|