foliko 1.1.4 → 1.1.6
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/.agent/agents/code-assistant.json +4 -1
- package/.agent/agents/file-assistant.json +4 -1
- package/.agent/agents/orchestrator-demo.md +53 -0
- package/.agent/agents/orchestrator.json +7 -0
- package/.agent/data/plugins-state.json +4 -0
- package/.agent/mcp_config.json +6 -0
- package/.agent/memory/feedback/mnrsiuoc-e1ru74.md +9 -0
- package/.agent/memory/feedback/mnrt2mmz-98az6n.md +9 -0
- package/.agent/memory/feedback/mnrtqrhm-kxsicz.md +9 -0
- package/.agent/memory/feedback/mnrts8vg-i0ngzp.md +15 -0
- package/.agent/memory/feedback/mnrtt7jt-c0trb2.md +9 -0
- package/.agent/memory/feedback/mnruc2f0-5s52la.md +16 -0
- package/.agent/memory/feedback/mnrumbmx-63sa0v.md +9 -0
- package/.agent/memory/project/mnrp7p5n-8enm2a.md +31 -0
- package/.agent/memory/project/mnrp9ifb-yynks0.md +40 -0
- package/.agent/memory/project/mnrpb3b8-f617s4.md +25 -0
- package/.agent/memory/project/mnrrmqgg-focprv.md +9 -0
- package/.agent/memory/project/mnrtykbh-6atsor.md +9 -0
- package/.agent/memory/project/mnru9jiu-kgau16.md +35 -0
- package/.agent/memory/reference/mnrnvpwo-rcqv9m.md +52 -0
- package/.agent/memory/reference/mnrovxvz-zy9xqm.md +25 -0
- package/.agent/memory/reference/mnroxabj-1b3930.md +68 -0
- package/.agent/memory/reference/mnrpjtlp-mnb9od.md +35 -0
- package/.agent/memory/reference/mnrps1x3-6b8xfm.md +28 -0
- package/.agent/memory/reference/mnrpt9ov-15er5w.md +22 -0
- package/.agent/memory/reference/mnrq82dn-y9tv9e.md +50 -0
- package/.agent/memory/reference/mnrqnr5v-v75drf.md +34 -0
- package/.agent/memory/reference/mnrrfzys-urudaf.md +31 -0
- package/.agent/memory/reference/mnrrocha-t0027n.md +21 -0
- package/.agent/memory/reference/mnrukklc-bxndsb.md +35 -0
- package/.agent/memory/user/mnrt39t8-8eosy0.md +9 -0
- package/.agent/plugins/marknative/fonts.zip +0 -0
- package/.agent/sessions/cli_default.json +4493 -1183
- package/.agent/test-agent.js +35 -0
- package/cli/src/commands/chat.js +69 -1
- package/cli/src/index.js +11 -2
- package/foliko-cloud-rising.png +0 -0
- package/foliko-dawn-of-ai.png +0 -0
- package/foliko-mindful-observation.png +0 -0
- package/foliko-stellar-dreams.png +0 -0
- package/foliko-zen-jing.png +0 -0
- package/foliko-zen-kong.png +0 -0
- package/foliko-zen-wu.png +0 -0
- package/package.json +2 -2
- package/plugins/coordinator-plugin.js +282 -0
- package/plugins/default-plugins.js +1 -1
- package/plugins/extension-executor-plugin.js +27 -1
- package/plugins/memory-plugin.js +228 -57
- package/src/core/agent-chat.js +206 -115
- package/src/core/agent.js +258 -71
- package/src/core/coordinator-manager.js +341 -0
- package/src/core/framework.js +50 -0
- package/src/core/plugin-base.js +30 -17
- package/src/core/sub-agent-config.js +8 -1
- package/src/core/worker-agent.js +176 -0
- package/src/executors/mcp-executor.js +4 -4
- package/zen_karesansui.png +0 -0
- package/.agent/plugins/marknative/update-readme.js +0 -134
- package/output/emoji-segoe-test-v2.png +0 -0
- package/output/emoji-segoe-test.png +0 -0
- package/output/emoji-test.png +0 -0
- package/output/emoji-windows-test.png +0 -0
- package/output/foliko-emoji-poster.png +0 -0
- package/output/foliko-muji-poster-final.png +0 -0
- package/output/foliko-muji-poster-v2.png +0 -0
- package/output/foliko-muji-poster.png +0 -0
- package/output/foliko-share.png +0 -0
- package/output/progress-circle-test.png +0 -0
- package/output/vb-agent-poster.png +0 -0
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CoordinatorManager - Coordinator模式管理器
|
|
3
|
+
* 管理Worker的创建、消息传递、生命周期
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const { EventEmitter } = require('../utils/event-emitter');
|
|
7
|
+
const { WorkerAgent } = require('./worker-agent');
|
|
8
|
+
const { logger } = require('../utils/logger');
|
|
9
|
+
|
|
10
|
+
const log = logger.child('CoordinatorManager');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Worker上下文
|
|
14
|
+
*/
|
|
15
|
+
class WorkerContext {
|
|
16
|
+
constructor(config) {
|
|
17
|
+
this.workerId = config.workerId;
|
|
18
|
+
this.name = config.name;
|
|
19
|
+
this.coordinatorId = config.coordinatorId;
|
|
20
|
+
this.task = config.task;
|
|
21
|
+
this.status = 'pending'; // pending, running, completed, error, stopped
|
|
22
|
+
this.agent = config.agent;
|
|
23
|
+
this.tools = config.tools || [];
|
|
24
|
+
this.createdAt = new Date();
|
|
25
|
+
this.updatedAt = new Date();
|
|
26
|
+
this.result = null;
|
|
27
|
+
this.error = null;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
update(status, result = null, error = null) {
|
|
31
|
+
this.status = status;
|
|
32
|
+
this.result = result;
|
|
33
|
+
this.error = error;
|
|
34
|
+
this.updatedAt = new Date();
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* CoordinatorManager - 管理所有Worker
|
|
40
|
+
*/
|
|
41
|
+
class CoordinatorManager extends EventEmitter {
|
|
42
|
+
/**
|
|
43
|
+
* @param {Framework} framework - 框架实例
|
|
44
|
+
*/
|
|
45
|
+
constructor(framework) {
|
|
46
|
+
super();
|
|
47
|
+
this.framework = framework;
|
|
48
|
+
this._workers = new Map(); // workerId -> WorkerContext
|
|
49
|
+
this._nameIndex = new Map(); // name -> workerId
|
|
50
|
+
this._coordinatorAgent = null; // Coordinator Agent实例
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* 设置Coordinator Agent
|
|
55
|
+
* @param {Agent} agent - Coordinator Agent实例
|
|
56
|
+
*/
|
|
57
|
+
setCoordinatorAgent(agent) {
|
|
58
|
+
this._coordinatorAgent = agent;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* 获取Coordinator Agent
|
|
63
|
+
*/
|
|
64
|
+
getCoordinatorAgent() {
|
|
65
|
+
return this._coordinatorAgent;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* 创建Worker
|
|
70
|
+
* @param {Object} config - Worker配置
|
|
71
|
+
* @param {string} config.name - Worker名称(唯一)
|
|
72
|
+
* @param {string} config.task - 初始任务
|
|
73
|
+
* @param {string} [config.systemPrompt] - 可选系统提示
|
|
74
|
+
* @param {string[]} [config.tools] - 可用工具列表
|
|
75
|
+
* @returns {Promise<{workerId: string, status: string}>}
|
|
76
|
+
*/
|
|
77
|
+
async createWorker(config) {
|
|
78
|
+
const { name, task, systemPrompt, tools } = config;
|
|
79
|
+
|
|
80
|
+
// 检查名称唯一性
|
|
81
|
+
if (this._nameIndex.has(name)) {
|
|
82
|
+
throw new Error(`Worker with name '${name}' already exists`);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// 生成workerId
|
|
86
|
+
const workerId = `worker_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
87
|
+
|
|
88
|
+
// 获取AI配置
|
|
89
|
+
const aiPlugin = this.framework.pluginManager.get('ai');
|
|
90
|
+
const aiConfig = aiPlugin ? aiPlugin.getConfig() : {};
|
|
91
|
+
|
|
92
|
+
// 构建系统提示
|
|
93
|
+
let finalSystemPrompt = systemPrompt;
|
|
94
|
+
if (!finalSystemPrompt) {
|
|
95
|
+
finalSystemPrompt = WorkerAgent.defaultPrompt();
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// 创建WorkerAgent
|
|
99
|
+
const agentConfig = {
|
|
100
|
+
workerId,
|
|
101
|
+
coordinatorId: this._coordinatorAgent?.name || 'unknown',
|
|
102
|
+
name: `worker_${name}`,
|
|
103
|
+
task,
|
|
104
|
+
systemPrompt: finalSystemPrompt,
|
|
105
|
+
tools: tools || [],
|
|
106
|
+
model: aiConfig.model,
|
|
107
|
+
provider: aiConfig.provider,
|
|
108
|
+
apiKey: aiConfig.apiKey,
|
|
109
|
+
baseURL: aiConfig.baseURL,
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
const workerAgent = new WorkerAgent(this.framework, agentConfig);
|
|
113
|
+
|
|
114
|
+
// 创建WorkerContext
|
|
115
|
+
const context = new WorkerContext({
|
|
116
|
+
workerId,
|
|
117
|
+
name,
|
|
118
|
+
coordinatorId: this._coordinatorAgent?.name || 'unknown',
|
|
119
|
+
task,
|
|
120
|
+
agent: workerAgent,
|
|
121
|
+
tools: tools || [],
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
// 保存
|
|
125
|
+
this._workers.set(workerId, context);
|
|
126
|
+
this._nameIndex.set(name, workerId);
|
|
127
|
+
|
|
128
|
+
// 监听Worker事件
|
|
129
|
+
workerAgent.on('message', (msg) => {
|
|
130
|
+
this._handleWorkerMessage(workerId, msg);
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
workerAgent.on('stopped', () => {
|
|
134
|
+
this._handleWorkerStopped(workerId);
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
// 发送初始任务
|
|
138
|
+
context.status = 'running';
|
|
139
|
+
this.emit('worker:created', { workerId, name, status: 'running' });
|
|
140
|
+
this.emit('worker:started', { workerId, name, task });
|
|
141
|
+
|
|
142
|
+
// 异步执行任务(不等待完成)
|
|
143
|
+
this._runWorkerTask(workerId, task);
|
|
144
|
+
|
|
145
|
+
return { workerId, status: 'running' };
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* 异步执行Worker任务
|
|
150
|
+
* @private
|
|
151
|
+
*/
|
|
152
|
+
async _runWorkerTask(workerId, task) {
|
|
153
|
+
const context = this._workers.get(workerId);
|
|
154
|
+
if (!context) return;
|
|
155
|
+
|
|
156
|
+
try {
|
|
157
|
+
const result = await context.agent.runTask(task);
|
|
158
|
+
context.update('completed', result);
|
|
159
|
+
|
|
160
|
+
// 生成通知
|
|
161
|
+
const notification = this._generateCompletionNotification(workerId, 'completed', result);
|
|
162
|
+
this.emit('worker:completed', { workerId, name: context.name, result, notification });
|
|
163
|
+
} catch (err) {
|
|
164
|
+
context.update('error', null, err.message);
|
|
165
|
+
const notification = this._generateCompletionNotification(
|
|
166
|
+
workerId,
|
|
167
|
+
'error',
|
|
168
|
+
null,
|
|
169
|
+
err.message
|
|
170
|
+
);
|
|
171
|
+
this.emit('worker:error', { workerId, name: context.name, error: err.message, notification });
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* 处理Worker消息
|
|
177
|
+
* @private
|
|
178
|
+
*/
|
|
179
|
+
_handleWorkerMessage(workerId, msg) {
|
|
180
|
+
const context = this._workers.get(workerId);
|
|
181
|
+
if (!context) return;
|
|
182
|
+
|
|
183
|
+
this.emit('worker:message', { workerId, name: context.name, message: msg });
|
|
184
|
+
|
|
185
|
+
// 转发给Coordinator(如果有)
|
|
186
|
+
if (this._coordinatorAgent) {
|
|
187
|
+
this._coordinatorAgent.emit('worker:message', { workerId, name: context.name, message: msg });
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* 处理Worker停止
|
|
193
|
+
* @private
|
|
194
|
+
*/
|
|
195
|
+
_handleWorkerStopped(workerId) {
|
|
196
|
+
const context = this._workers.get(workerId);
|
|
197
|
+
if (!context) return;
|
|
198
|
+
|
|
199
|
+
context.update('stopped');
|
|
200
|
+
this.emit('worker:stopped', { workerId, name: context.name });
|
|
201
|
+
|
|
202
|
+
// 清理索引
|
|
203
|
+
this._nameIndex.delete(context.name);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* 发送消息给Worker(继续执行)
|
|
208
|
+
* @param {string} workerName - Worker名称
|
|
209
|
+
* @param {string} message - 消息内容
|
|
210
|
+
* @returns {Promise<Object>} 处理结果
|
|
211
|
+
*/
|
|
212
|
+
async sendToWorker(workerName, message) {
|
|
213
|
+
const workerId = this._nameIndex.get(workerName);
|
|
214
|
+
if (!workerId) {
|
|
215
|
+
throw new Error(`Worker '${workerName}' not found`);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
const context = this._workers.get(workerId);
|
|
219
|
+
if (!context) {
|
|
220
|
+
throw new Error(`Worker context not found for '${workerName}'`);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
if (context.status === 'stopped') {
|
|
224
|
+
throw new Error(`Worker '${workerName}' has been stopped`);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
this.emit('worker:resumed', { workerId, name: workerName, message });
|
|
228
|
+
|
|
229
|
+
try {
|
|
230
|
+
const result = await context.agent.sendMessage(message);
|
|
231
|
+
return result;
|
|
232
|
+
} catch (err) {
|
|
233
|
+
context.update('error', null, err.message);
|
|
234
|
+
throw err;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* 停止Worker
|
|
240
|
+
* @param {string} workerName - Worker名称
|
|
241
|
+
* @param {string} [reason] - 停止原因
|
|
242
|
+
* @returns {Object} 停止结果
|
|
243
|
+
*/
|
|
244
|
+
stopWorker(workerName, reason = null) {
|
|
245
|
+
const workerId = this._nameIndex.get(workerName);
|
|
246
|
+
if (!workerId) {
|
|
247
|
+
throw new Error(`Worker '${workerName}' not found`);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
const context = this._workers.get(workerId);
|
|
251
|
+
if (!context) {
|
|
252
|
+
throw new Error(`Worker context not found for '${workerName}'`);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
context.agent.stop();
|
|
256
|
+
context.update('stopped');
|
|
257
|
+
|
|
258
|
+
const notification = this._generateCompletionNotification(workerId, 'stopped', null, reason);
|
|
259
|
+
this.emit('worker:stopped', {
|
|
260
|
+
workerId,
|
|
261
|
+
name: workerName,
|
|
262
|
+
reason,
|
|
263
|
+
notification,
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
// 清理索引
|
|
267
|
+
this._nameIndex.delete(workerName);
|
|
268
|
+
|
|
269
|
+
return { workerId, name: workerName, status: 'stopped', reason };
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* 获取Worker状态
|
|
274
|
+
* @param {string} workerName - Worker名称
|
|
275
|
+
* @returns {Object|null} Worker信息
|
|
276
|
+
*/
|
|
277
|
+
getWorker(workerName) {
|
|
278
|
+
const workerId = this._nameIndex.get(workerName);
|
|
279
|
+
if (!workerId) return null;
|
|
280
|
+
|
|
281
|
+
const context = this._workers.get(workerId);
|
|
282
|
+
if (!context) return null;
|
|
283
|
+
|
|
284
|
+
return {
|
|
285
|
+
workerId: context.workerId,
|
|
286
|
+
name: context.name,
|
|
287
|
+
status: context.status,
|
|
288
|
+
task: context.task,
|
|
289
|
+
result: context.result,
|
|
290
|
+
error: context.error,
|
|
291
|
+
createdAt: context.createdAt,
|
|
292
|
+
updatedAt: context.updatedAt,
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* 列出所有Worker
|
|
298
|
+
* @returns {Array} Worker列表
|
|
299
|
+
*/
|
|
300
|
+
listWorkers() {
|
|
301
|
+
const workers = [];
|
|
302
|
+
for (const [workerId, context] of this._workers) {
|
|
303
|
+
// 跳过已停止的
|
|
304
|
+
if (context.status === 'stopped') continue;
|
|
305
|
+
|
|
306
|
+
workers.push({
|
|
307
|
+
workerId: context.workerId,
|
|
308
|
+
name: context.name,
|
|
309
|
+
status: context.status,
|
|
310
|
+
task: context.task,
|
|
311
|
+
createdAt: context.createdAt,
|
|
312
|
+
updatedAt: context.updatedAt,
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
return workers;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* 生成完成通知XML
|
|
320
|
+
* @private
|
|
321
|
+
*/
|
|
322
|
+
_generateCompletionNotification(workerId, status, result, error = null) {
|
|
323
|
+
return WorkerAgent.formatNotification(workerId, status, result, error);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* 销毁所有Worker
|
|
328
|
+
*/
|
|
329
|
+
destroy() {
|
|
330
|
+
for (const [workerId, context] of this._workers) {
|
|
331
|
+
if (context.status !== 'stopped') {
|
|
332
|
+
context.agent.stop();
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
this._workers.clear();
|
|
336
|
+
this._nameIndex.clear();
|
|
337
|
+
this._coordinatorAgent = null;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
module.exports = { CoordinatorManager, WorkerContext };
|
package/src/core/framework.js
CHANGED
|
@@ -13,6 +13,7 @@ const { SubAgentConfigManager } = require('./sub-agent-config');
|
|
|
13
13
|
const { ContextManager } = require('./context-manager');
|
|
14
14
|
const { SessionContext } = require('./session-context');
|
|
15
15
|
const { SessionStorageAdapter, getDefaultAdapter } = require('./session-storage');
|
|
16
|
+
const { CoordinatorManager } = require('./coordinator-manager');
|
|
16
17
|
|
|
17
18
|
// 添加框架目录的 node_modules 到全局搜索路径
|
|
18
19
|
// 让项目插件能 require 框架内置的包(如 zod)
|
|
@@ -70,6 +71,9 @@ class Framework extends EventEmitter {
|
|
|
70
71
|
baseDir: '.agent/sessions',
|
|
71
72
|
};
|
|
72
73
|
|
|
74
|
+
// Coordinator管理器(用于Coordinator模式)
|
|
75
|
+
this._coordinatorManager = null;
|
|
76
|
+
|
|
73
77
|
// 事件转发 - ToolRegistry 事件
|
|
74
78
|
this.toolRegistry.on('tool:registered', (tool) => {
|
|
75
79
|
this.emit('tool:registered', tool);
|
|
@@ -738,10 +742,56 @@ class Framework extends EventEmitter {
|
|
|
738
742
|
// 内置工具会在 Agent 创建时添加)
|
|
739
743
|
}
|
|
740
744
|
|
|
745
|
+
// ============================================================================
|
|
746
|
+
// Coordinator 模式管理
|
|
747
|
+
// ============================================================================
|
|
748
|
+
|
|
749
|
+
/**
|
|
750
|
+
* 初始化Coordinator管理器
|
|
751
|
+
* @param {Agent} coordinatorAgent - Coordinator Agent实例
|
|
752
|
+
*/
|
|
753
|
+
initCoordinatorManager(coordinatorAgent) {
|
|
754
|
+
if (!this._coordinatorManager) {
|
|
755
|
+
this._coordinatorManager = new CoordinatorManager(this);
|
|
756
|
+
}
|
|
757
|
+
this._coordinatorManager.setCoordinatorAgent(coordinatorAgent);
|
|
758
|
+
return this._coordinatorManager;
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
/**
|
|
762
|
+
* 获取Coordinator管理器
|
|
763
|
+
* @returns {CoordinatorManager|null}
|
|
764
|
+
*/
|
|
765
|
+
getCoordinatorManager() {
|
|
766
|
+
return this._coordinatorManager;
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
/**
|
|
770
|
+
* 创建Worker(由coordinator-plugin调用)
|
|
771
|
+
* @param {Object} config - Worker配置
|
|
772
|
+
* @param {string} config.name - Worker名称
|
|
773
|
+
* @param {string} config.task - 初始任务
|
|
774
|
+
* @param {string} [config.systemPrompt] - 可选系统提示
|
|
775
|
+
* @param {string[]} [config.tools] - 可用工具列表
|
|
776
|
+
* @returns {Promise<{workerId: string, status: string}>}
|
|
777
|
+
*/
|
|
778
|
+
async createWorker(config) {
|
|
779
|
+
if (!this._coordinatorManager) {
|
|
780
|
+
throw new Error('CoordinatorManager not initialized. Call initCoordinatorManager first.');
|
|
781
|
+
}
|
|
782
|
+
return this._coordinatorManager.createWorker(config);
|
|
783
|
+
}
|
|
784
|
+
|
|
741
785
|
/**
|
|
742
786
|
* 销毁框架
|
|
743
787
|
*/
|
|
744
788
|
async destroy() {
|
|
789
|
+
// 销毁Coordinator管理器
|
|
790
|
+
if (this._coordinatorManager) {
|
|
791
|
+
this._coordinatorManager.destroy();
|
|
792
|
+
this._coordinatorManager = null;
|
|
793
|
+
}
|
|
794
|
+
|
|
745
795
|
// 刷新所有 Session 存储
|
|
746
796
|
if (this._sessionStorage) {
|
|
747
797
|
await this._sessionStorage.flush();
|
package/src/core/plugin-base.js
CHANGED
|
@@ -176,34 +176,47 @@ class Plugin {
|
|
|
176
176
|
* @param {string} [config.description] - 子Agent描述
|
|
177
177
|
* @param {Object} [config.tools] - 自定义工具 { name: toolDef }
|
|
178
178
|
* @param {string[]} [config.parentTools] - 从父Agent继承的工具名称
|
|
179
|
-
* @returns {
|
|
179
|
+
* @returns {Object} 注册的子Agent信息
|
|
180
180
|
*/
|
|
181
181
|
registerSubAgent(config) {
|
|
182
182
|
if (!this._framework) {
|
|
183
183
|
throw new Error('Plugin not installed, call install(framework) first');
|
|
184
184
|
}
|
|
185
185
|
|
|
186
|
-
//
|
|
187
|
-
const
|
|
186
|
+
// 获取 subagent-manager 插件
|
|
187
|
+
const subAgentManager = this._framework.pluginManager.get('subagent-manager');
|
|
188
188
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
189
|
+
if (!subAgentManager) {
|
|
190
|
+
throw new Error('subagent-manager plugin not found');
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// 创建子Agent实例
|
|
194
|
+
const agent = this._framework.createSubAgent({
|
|
195
|
+
name: config.name,
|
|
196
|
+
role: config.role,
|
|
197
|
+
goal: config.description || config.role,
|
|
198
|
+
tools: config.tools || {},
|
|
199
|
+
parentTools: config.parentTools || [],
|
|
200
200
|
});
|
|
201
201
|
|
|
202
|
-
|
|
203
|
-
|
|
202
|
+
// 注册到 subagent-manager
|
|
203
|
+
subAgentManager.registerPlugin({
|
|
204
|
+
name: config.name,
|
|
205
|
+
role: config.role,
|
|
206
|
+
goal: config.description || config.role,
|
|
207
|
+
agent,
|
|
208
|
+
tools: config.tools || {},
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
// 保存引用以便后续清理
|
|
212
|
+
this._subAgents.push({
|
|
213
|
+
name: config.name,
|
|
214
|
+
agent,
|
|
215
|
+
plugin: null, // 兼容旧代码
|
|
216
|
+
});
|
|
204
217
|
|
|
205
218
|
log.debug(` Registered subagent: ${config.name}`);
|
|
206
|
-
return
|
|
219
|
+
return { name: config.name, agent };
|
|
207
220
|
}
|
|
208
221
|
|
|
209
222
|
/**
|
|
@@ -239,12 +239,19 @@ class SubAgentConfigManager {
|
|
|
239
239
|
}
|
|
240
240
|
|
|
241
241
|
/**
|
|
242
|
-
*
|
|
242
|
+
* 获取所有配置(Map 格式)
|
|
243
243
|
*/
|
|
244
244
|
getAll() {
|
|
245
245
|
return Array.from(this._configs.values());
|
|
246
246
|
}
|
|
247
247
|
|
|
248
|
+
/**
|
|
249
|
+
* 获取所有配置(Map 格式,用于兼容性)
|
|
250
|
+
*/
|
|
251
|
+
getAllConfigs() {
|
|
252
|
+
return this._configs;
|
|
253
|
+
}
|
|
254
|
+
|
|
248
255
|
/**
|
|
249
256
|
* 获取所有有效配置
|
|
250
257
|
*/
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WorkerAgent - 独立子Agent
|
|
3
|
+
* 用于Coordinator模式下的Worker,具有独立工具集
|
|
4
|
+
* 任务完成后通过事件通知Coordinator
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const { Agent } = require('./agent');
|
|
8
|
+
const { EventEmitter } = require('../utils/event-emitter');
|
|
9
|
+
|
|
10
|
+
class WorkerAgent extends Agent {
|
|
11
|
+
/**
|
|
12
|
+
* @param {Framework} framework - 框架实例
|
|
13
|
+
* @param {Object} config - 配置
|
|
14
|
+
* @param {string} config.workerId - Worker唯一ID
|
|
15
|
+
* @param {string} config.coordinatorId - Coordinator的agentId
|
|
16
|
+
* @param {string} [config.name] - Worker名称
|
|
17
|
+
* @param {string} [config.systemPrompt] - 系统提示
|
|
18
|
+
* @param {string[]} [config.tools] - 可用工具名称列表(为空则无工具)
|
|
19
|
+
*/
|
|
20
|
+
constructor(framework, config) {
|
|
21
|
+
super(framework, {
|
|
22
|
+
name: config.name || `worker_${config.workerId}`,
|
|
23
|
+
systemPrompt: config.systemPrompt || WorkerAgent.defaultPrompt(),
|
|
24
|
+
model: config.model,
|
|
25
|
+
provider: config.provider,
|
|
26
|
+
apiKey: config.apiKey,
|
|
27
|
+
baseURL: config.baseURL,
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
this.workerId = config.workerId;
|
|
31
|
+
this.coordinatorId = config.coordinatorId;
|
|
32
|
+
this._status = 'idle'; // idle, running, completed, error, stopped
|
|
33
|
+
this._task = config.task || '';
|
|
34
|
+
this._availableTools = config.tools || [];
|
|
35
|
+
|
|
36
|
+
// 不从framework同步工具(Worker有独立工具集)
|
|
37
|
+
// 但如果指定了工具列表,只注册那些工具
|
|
38
|
+
if (this._availableTools.length > 0) {
|
|
39
|
+
this._applyToolFilter();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// 监听完成事件
|
|
43
|
+
this.on('message', (msg) => {
|
|
44
|
+
// 检查是否是最终响应(无更多工具调用)
|
|
45
|
+
if (msg.role === 'assistant' && !msg.toolCalls) {
|
|
46
|
+
this._status = 'completed';
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* 应用工具过滤(如果指定了tools列表)
|
|
53
|
+
* @private
|
|
54
|
+
*/
|
|
55
|
+
_applyToolFilter() {
|
|
56
|
+
const allTools = Array.from(this._tools.values());
|
|
57
|
+
const allowedTools = new Set(this._availableTools);
|
|
58
|
+
|
|
59
|
+
// 移除不在允许列表中的工具
|
|
60
|
+
for (const [name, tool] of this._tools) {
|
|
61
|
+
if (!allowedTools.has(name)) {
|
|
62
|
+
this._tools.delete(name);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// 同步到chatHandler
|
|
67
|
+
if (this._chatHandler) {
|
|
68
|
+
this._chatHandler._tools = this._tools;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* 获取Worker状态
|
|
74
|
+
*/
|
|
75
|
+
getStatus() {
|
|
76
|
+
return this._status;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* 设置状态
|
|
81
|
+
*/
|
|
82
|
+
setStatus(status) {
|
|
83
|
+
this._status = status;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* 执行初始任务
|
|
88
|
+
* @param {string} task - 任务描述
|
|
89
|
+
* @returns {Promise<Object>} 任务结果
|
|
90
|
+
*/
|
|
91
|
+
async runTask(task) {
|
|
92
|
+
this._task = task;
|
|
93
|
+
this._status = 'running';
|
|
94
|
+
|
|
95
|
+
try {
|
|
96
|
+
const result = await this.chat(task);
|
|
97
|
+
this._status = 'completed';
|
|
98
|
+
return result;
|
|
99
|
+
} catch (err) {
|
|
100
|
+
this._status = 'error';
|
|
101
|
+
throw err;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* 发送消息继续Worker
|
|
107
|
+
* @param {string} message - 继续消息
|
|
108
|
+
* @returns {Promise<Object>} 处理结果
|
|
109
|
+
*/
|
|
110
|
+
async sendMessage(message) {
|
|
111
|
+
if (this._status === 'stopped') {
|
|
112
|
+
throw new Error(`Worker ${this.workerId} has been stopped`);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
this._status = 'running';
|
|
116
|
+
try {
|
|
117
|
+
const result = await this.chat(message);
|
|
118
|
+
return result;
|
|
119
|
+
} catch (err) {
|
|
120
|
+
this._status = 'error';
|
|
121
|
+
throw err;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* 停止Worker
|
|
127
|
+
*/
|
|
128
|
+
stop() {
|
|
129
|
+
this._status = 'stopped';
|
|
130
|
+
if (this._chatHandler) {
|
|
131
|
+
this._chatHandler.destroy();
|
|
132
|
+
}
|
|
133
|
+
this.emit('stopped', { workerId: this.workerId });
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* 生成<task-notification> JSON
|
|
138
|
+
* @param {string} status - completed, error, stopped
|
|
139
|
+
* @param {string} result - 任务结果
|
|
140
|
+
* @param {string} [error] - 错误信息
|
|
141
|
+
* @returns {string} JSON字符串
|
|
142
|
+
*/
|
|
143
|
+
static formatNotification(workerId, status, result, error = null) {
|
|
144
|
+
const notification = {
|
|
145
|
+
worker_id: workerId,
|
|
146
|
+
status: status,
|
|
147
|
+
timestamp: new Date().toISOString(),
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
if (error) {
|
|
151
|
+
notification.error = error;
|
|
152
|
+
} else if (result) {
|
|
153
|
+
notification.result = result;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return JSON.stringify(notification);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* 默认系统提示
|
|
161
|
+
*/
|
|
162
|
+
static defaultPrompt() {
|
|
163
|
+
return `你是一个独立的Worker Agent。
|
|
164
|
+
你的职责:
|
|
165
|
+
1. 接收并理解Coordinator分配的任务
|
|
166
|
+
2. 使用你的工具集完成任务
|
|
167
|
+
3. 返回完整的任务结果
|
|
168
|
+
|
|
169
|
+
重要规则:
|
|
170
|
+
- 任务完成或出错时,在响应末尾添加JSON格式的<task-notification>说明状态
|
|
171
|
+
- 不要主动联系Coordinator,由Coordinator主动查询结果
|
|
172
|
+
- 如果需要更多信息,等待Coordinator发送continue消息`;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
module.exports = { WorkerAgent };
|