foliko 1.0.75 → 1.0.76

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.
Files changed (88) hide show
  1. package/.claude/settings.local.json +159 -157
  2. package/cli/bin/foliko.js +12 -12
  3. package/cli/src/commands/chat.js +143 -143
  4. package/cli/src/commands/list.js +93 -93
  5. package/cli/src/index.js +75 -75
  6. package/cli/src/ui/chat-ui.js +201 -201
  7. package/cli/src/utils/ansi.js +40 -40
  8. package/cli/src/utils/markdown.js +292 -292
  9. package/examples/ambient-example.js +194 -194
  10. package/examples/basic.js +115 -115
  11. package/examples/bootstrap.js +121 -121
  12. package/examples/mcp-example.js +56 -56
  13. package/examples/skill-example.js +49 -49
  14. package/examples/test-chat.js +137 -137
  15. package/examples/test-mcp.js +85 -85
  16. package/examples/test-reload.js +59 -59
  17. package/examples/test-telegram.js +50 -50
  18. package/examples/test-tg-bot.js +45 -45
  19. package/examples/test-tg-simple.js +47 -47
  20. package/examples/test-tg.js +62 -62
  21. package/examples/test-think.js +43 -43
  22. package/examples/test-web-plugin.js +103 -103
  23. package/examples/test-weixin-feishu.js +103 -103
  24. package/examples/workflow.js +158 -158
  25. package/package.json +1 -1
  26. package/plugins/ai-plugin.js +102 -102
  27. package/plugins/ambient-agent/EventWatcher.js +113 -113
  28. package/plugins/ambient-agent/ExplorerLoop.js +640 -640
  29. package/plugins/ambient-agent/GoalManager.js +197 -197
  30. package/plugins/ambient-agent/Reflector.js +95 -95
  31. package/plugins/ambient-agent/StateStore.js +90 -90
  32. package/plugins/ambient-agent/constants.js +101 -101
  33. package/plugins/ambient-agent/index.js +579 -579
  34. package/plugins/audit-plugin.js +187 -187
  35. package/plugins/default-plugins.js +662 -662
  36. package/plugins/email/constants.js +64 -64
  37. package/plugins/email/handlers.js +461 -461
  38. package/plugins/email/index.js +278 -278
  39. package/plugins/email/monitor.js +269 -269
  40. package/plugins/email/parser.js +138 -138
  41. package/plugins/email/reply.js +151 -151
  42. package/plugins/email/utils.js +124 -124
  43. package/plugins/feishu-plugin.js +481 -481
  44. package/plugins/file-system-plugin.js +826 -826
  45. package/plugins/install-plugin.js +199 -199
  46. package/plugins/python-executor-plugin.js +367 -367
  47. package/plugins/python-plugin-loader.js +481 -481
  48. package/plugins/rules-plugin.js +294 -294
  49. package/plugins/scheduler-plugin.js +691 -691
  50. package/plugins/session-plugin.js +369 -369
  51. package/plugins/shell-executor-plugin.js +197 -197
  52. package/plugins/storage-plugin.js +240 -240
  53. package/plugins/subagent-plugin.js +845 -845
  54. package/plugins/telegram-plugin.js +482 -482
  55. package/plugins/think-plugin.js +345 -345
  56. package/plugins/tools-plugin.js +196 -196
  57. package/plugins/web-plugin.js +606 -606
  58. package/plugins/weixin-plugin.js +545 -545
  59. package/src/capabilities/index.js +11 -11
  60. package/src/capabilities/skill-manager.js +609 -609
  61. package/src/capabilities/workflow-engine.js +1109 -1109
  62. package/src/core/agent-chat.js +882 -882
  63. package/src/core/agent.js +892 -892
  64. package/src/core/framework.js +465 -465
  65. package/src/core/index.js +19 -19
  66. package/src/core/plugin-base.js +219 -219
  67. package/src/core/plugin-manager.js +863 -863
  68. package/src/core/provider.js +114 -114
  69. package/src/core/sub-agent-config.js +264 -264
  70. package/src/core/system-prompt-builder.js +120 -120
  71. package/src/core/tool-registry.js +517 -517
  72. package/src/core/tool-router.js +297 -297
  73. package/src/executors/executor-base.js +58 -58
  74. package/src/executors/mcp-executor.js +741 -741
  75. package/src/index.js +25 -25
  76. package/src/utils/circuit-breaker.js +301 -301
  77. package/src/utils/error-boundary.js +363 -363
  78. package/src/utils/error.js +374 -374
  79. package/src/utils/event-emitter.js +97 -97
  80. package/src/utils/id.js +133 -133
  81. package/src/utils/index.js +217 -217
  82. package/src/utils/logger.js +181 -181
  83. package/src/utils/plugin-helpers.js +90 -90
  84. package/src/utils/retry.js +122 -122
  85. package/src/utils/sandbox.js +292 -292
  86. package/test/tool-registry-validation.test.js +218 -218
  87. package/website/script.js +136 -136
  88. package/foliko-1.0.75.tgz +0 -0
@@ -1,465 +1,465 @@
1
- /**
2
- * Framework 核心容器
3
- * 管理所有子系统,提供统一入口
4
- */
5
-
6
- const path = require('path');
7
- const { AsyncLocalStorage } = require('async_hooks');
8
- const { EventEmitter } = require('../utils/event-emitter');
9
- const { PluginManager } = require('./plugin-manager');
10
- const { ToolRegistry } = require('./tool-registry');
11
- const { Agent } = require('./agent');
12
- const { SubAgentConfigManager } = require('./sub-agent-config');
13
-
14
- // 添加框架目录的 node_modules 到全局搜索路径
15
- // 让项目插件能 require 框架内置的包(如 zod)
16
- const frameworkNodeModules = path.join(__dirname, '..', '..', 'node_modules');
17
- if (!module.paths.includes(frameworkNodeModules)) {
18
- module.paths.unshift(frameworkNodeModules);
19
- }
20
-
21
- // AsyncLocalStorage 实现真正的上下文隔离(支持并行处理)
22
- const asyncLocalStorage = new AsyncLocalStorage();
23
-
24
- class Framework extends EventEmitter {
25
- /**
26
- * @param {Object} config - 配置
27
- * @param {boolean} [config.debug=false] - 调试模式
28
- */
29
- constructor(config = {}) {
30
- super();
31
-
32
- this._debug = config.debug || false;
33
- this._ready = false;
34
- this._readyPromise = null;
35
- this._resolveReady = null;
36
-
37
- // 初始化子系统
38
- this.toolRegistry = new ToolRegistry();
39
- this.pluginManager = new PluginManager(this);
40
-
41
- // Agent 管理
42
- this._agents = []; // 所有创建的 agent
43
- this._mainAgent = null; // 主 agent
44
-
45
- // 子代理配置管理器
46
- this._subAgentConfigManager = null;
47
-
48
- // 执行上下文(工具调用时可用)
49
- this._executionContext = null;
50
-
51
- // 事件转发
52
- this.toolRegistry.on('tool:registered', (tool) => {
53
- this.emit('tool:registered', tool);
54
- });
55
-
56
- this._registerBuiltinTools();
57
- }
58
-
59
- /**
60
- * 从 AI 插件合并配置到目标配置对象
61
- * @param {Object} target - 目标配置对象
62
- * @private
63
- */
64
- _mergeAIConfig(target) {
65
- if (target.apiKey) return target; // 已有 apiKey 不需要合并
66
-
67
- const aiPlugin = this.pluginManager.get('ai');
68
- if (!aiPlugin) return target;
69
-
70
- const defaults = {
71
- apiKey: aiPlugin.config.apiKey,
72
- provider: aiPlugin.config.provider,
73
- model: aiPlugin.config.model,
74
- baseURL: aiPlugin.config.baseURL,
75
- providerOptions: aiPlugin.config.providerOptions || {},
76
- };
77
-
78
- return {
79
- ...target,
80
- apiKey: target.apiKey || defaults.apiKey,
81
- provider: target.provider || defaults.provider,
82
- model: target.model || defaults.model,
83
- baseURL: target.baseURL || defaults.baseURL,
84
- providerOptions: target.providerOptions || defaults.providerOptions,
85
- };
86
- }
87
-
88
- /**
89
- * 注册插件(不加载)
90
- * @param {Plugin|Object} plugin - 插件
91
- */
92
- registerPlugin(plugin) {
93
- this.pluginManager.register(plugin);
94
- return this;
95
- }
96
-
97
- /**
98
- * 加载并启动插件)
99
- * @param {Plugin|Object} plugin - 插件
100
- */
101
- async loadPlugin(plugin) {
102
- await this.pluginManager.load(plugin);
103
- return this;
104
- }
105
-
106
- /**
107
- * 卸载插件
108
- * @param {string} name - 插件名称
109
- */
110
- async unloadPlugin(name) {
111
- await this.pluginManager.unload(name);
112
- return this;
113
- }
114
-
115
- /**
116
- * 重载单个插件
117
- * @param {string} name - 插件名称
118
- */
119
- async reloadPlugin(name) {
120
- await this.pluginManager.reload(name);
121
- return this;
122
- }
123
-
124
- /**
125
- * 重载所有插件)
126
- */
127
- async reloadAllPlugins() {
128
- await this.pluginManager.reloadAll();
129
- return this;
130
- }
131
-
132
- /**
133
- * 启用插件
134
- * @param {string} name - 插件名称
135
- */
136
- async enablePlugin(name) {
137
- await this.pluginManager.enable(name);
138
- return this;
139
- }
140
-
141
- /**
142
- * 禁用插件
143
- * @param {string} name - 插件名称
144
- */
145
- async disablePlugin(name) {
146
- await this.pluginManager.disable(name);
147
- return this;
148
- }
149
-
150
- /**
151
- * 更新插件配置
152
- * @param {string} name - 插件名称
153
- * @param {Object} config - 新配置
154
- */
155
- updatePluginConfig(name, config) {
156
- return this.pluginManager.updatePluginConfig(name, config);
157
- }
158
-
159
- /**
160
- * 注册工具
161
- * @param {Object} tool - 工具定义
162
- */
163
- registerTool(tool) {
164
- this.toolRegistry.register(tool);
165
- return this;
166
- }
167
-
168
- /**
169
- * 获取所有工具)
170
- * @returns {Array<Object>}
171
- */
172
- getTools() {
173
- return this.toolRegistry.getAll();
174
- }
175
-
176
- // ============================================================================
177
- // 事件描述注册(供 Ambient Agent 使用)
178
- // ============================================================================
179
-
180
- /**
181
- * 注册事件描述
182
- * @param {string} eventType - 事件类型,如 'tool:result'
183
- * @param {string} description - 事件描述
184
- * @param {Object} schema - 事件参数 Schema(可选)
185
- */
186
- registerEventDescription(eventType, description, schema = null) {
187
- this.pluginManager.registerEventDescription(eventType, description, schema);
188
- return this;
189
- }
190
-
191
- /**
192
- * 获取所有已注册的事件描述
193
- * @returns {Map<string, Object>} 事件描述 Map
194
- */
195
- getEventDescriptions() {
196
- return this.pluginManager.getEventDescriptions();
197
- }
198
-
199
- /**
200
- * 获取单个事件描述
201
- * @param {string} eventType - 事件类型
202
- * @returns {Object|null} 事件描述
203
- */
204
- getEventDescription(eventType) {
205
- return this.pluginManager.getEventDescription(eventType);
206
- }
207
-
208
- /**
209
- * 执行工具
210
- * @param {string} name - 工具名称
211
- * @param {Object} args - 参数
212
- */
213
- async executeTool(name, args) {
214
- return this.toolRegistry.execute(name, args, this);
215
- }
216
-
217
- /**
218
- * 在上下文中执行函数(支持并行处理,自动隔离 session)
219
- * @param {Object} context - 执行上下文 { sessionId, ... }
220
- * @param {Function} fn - 要执行的异步函数
221
- * @returns {Promise}
222
- */
223
- runWithContext(context, fn) {
224
- return asyncLocalStorage.run(context, fn);
225
- }
226
-
227
- /**
228
- * 获取当前执行上下文(在 runWithContext 内部调用)
229
- * @returns {Object|null}
230
- */
231
- getExecutionContext() {
232
- return asyncLocalStorage.getStore() || null;
233
- }
234
-
235
- /**
236
- * @deprecated 使用 runWithContext 代替
237
- */
238
- setExecutionContext() {}
239
-
240
- /**
241
- * @deprecated 使用 runWithContext 代替
242
- */
243
- clearExecutionContext() {}
244
-
245
- /**
246
- * 创建 Agent
247
- * @param {Object} config - Agent 配置
248
- */
249
- createAgent(config) {
250
- // 合并 AI 插件配置
251
- config = this._mergeAIConfig(config);
252
-
253
- const agent = new Agent(this, config);
254
-
255
- // 跟踪 agent
256
- this._agents.push(agent);
257
- if (!this._mainAgent) {
258
- this._mainAgent = agent;
259
- }
260
-
261
- this.emit('agent:created', agent);
262
- return agent;
263
- }
264
-
265
- /**
266
- * 为指定 session 创建独立 Agent 实例
267
- * @param {string} sessionId - session ID
268
- * @param {Object} config - Agent 配置
269
- */
270
- createSessionAgent(sessionId, config = {}) {
271
- const agentConfig = {
272
- name: `session_${sessionId}`,
273
- ...config,
274
- };
275
-
276
- // 合并 AI 插件配置
277
- const merged = this._mergeAIConfig(agentConfig);
278
-
279
- const agent = new Agent(this, merged);
280
- this._agents.push(agent);
281
-
282
- // 如果提供了 systemPrompt,需要替换 AgentChatHandler
283
- if (merged.systemPrompt) {
284
- agent.setSystemPrompt(merged.systemPrompt);
285
- }
286
-
287
- this.emit('agent:created', agent);
288
- return agent;
289
- }
290
-
291
- /**
292
- * 创建子Agent(具有独立工具集的轻量级Agent)
293
- * @param {Object} config - 子Agent配置
294
- * @param {string} config.name - 子Agent名称
295
- * @param {string} config.role - 角色描述(用于智能选择)
296
- * @param {string} [config.description] - 供主Agent理解的描述)
297
- * @param {Object} [config.tools] - 自定义工具 { name: toolDef }
298
- * @param {string[]} [config.parentTools] - 从父Agent继承的工具名称列表)
299
- * @param {Object} [config.llmConfig] - 独立LLM配置
300
- * @returns {Agent} 创建的子Agent
301
- */
302
- createSubAgent(config) {
303
- const {
304
- name,
305
- role,
306
- description = '',
307
- tools = {},
308
- parentTools, // 如果不传,默认继承主agent所有工具
309
- llmConfig = null,
310
- } = config;
311
-
312
- // 构建子Agent配置
313
- const agentConfig = {
314
- name: `subagent_${name}`,
315
- role: role,
316
- systemPrompt: role, // 使用 role 作为 systemPrompt
317
- ...(llmConfig || {}), // 如果提供了独立LLM配置,合并
318
- };
319
-
320
- // 合并 AI 插件配置
321
- const merged = this._mergeAIConfig(agentConfig);
322
-
323
- // 创建 Agent
324
- const agent = new Agent(this, merged);
325
-
326
- // 注册自定义工具
327
- for (const [toolName, toolDef] of Object.entries(tools)) {
328
- if (toolDef && typeof toolDef === 'object') {
329
- agent.registerTool({
330
- name: toolName,
331
- description: toolDef.description || '',
332
- inputSchema: toolDef.inputSchema,
333
- execute: toolDef.execute,
334
- });
335
- }
336
- }
337
-
338
- // 从父Agent继承工具
339
- if (this._mainAgent) {
340
- const parentToolsDefs = this._mainAgent.getTools();
341
- if (parentTools === undefined) {
342
- // 如果没有指定 parentTools,默认继承所有工具
343
- for (const toolDef of parentToolsDefs) {
344
- agent.registerTool(toolDef);
345
- }
346
- } else if (Array.isArray(parentTools) && parentTools.length > 0) {
347
- // 指定了要继承的工具列表
348
- for (const toolName of parentTools) {
349
- const toolDef = parentToolsDefs.find((t) => t.name === toolName);
350
- if (toolDef) {
351
- agent.registerTool(toolDef);
352
- }
353
- }
354
- }
355
- }
356
-
357
- this._agents.push(agent);
358
- this.emit('agent:created', agent);
359
- return agent;
360
- }
361
-
362
- /**
363
- * 获取 AI 插件
364
- * @returns {Object|undefined}
365
- */
366
- getAIPlugin() {
367
- return this.pluginManager.get('ai');
368
- }
369
-
370
- /**
371
- * Bootstrap - 使用默认配置启动框架
372
- * 自动加载 .agent/ 目录下的配置和所有默认插件)
373
- * @param {Object} config - 配置
374
- * @param {string} [config.agentDir='.agent'] - Agent 配置目录
375
- * @param {Object} [config.aiConfig] - AI 配置(可选,覆盖文件配置)
376
- * @returns {Promise<Framework>}
377
- */
378
- async bootstrap(config = {}) {
379
- const {
380
- bootstrapDefaults,
381
- DefaultPlugins,
382
- loadAgentConfig,
383
- } = require('../../plugins/default-plugins');
384
-
385
- // 先加载默认插件配置
386
- const defaultsPlugin = new DefaultPlugins({
387
- agentDir: config.agentDir || '.agent',
388
- });
389
-
390
- await this.loadPlugin(defaultsPlugin);
391
-
392
- // 获取配置
393
- const agentConfig = defaultsPlugin.getConfig();
394
-
395
- // 如果提供了 AI 配置,覆盖文件配置
396
- if (config.aiConfig) {
397
- agentConfig.ai = { ...agentConfig.ai, ...config.aiConfig };
398
- }
399
-
400
- // 加载所有默认插件(传入已加载的配置避免重复加载)
401
- await bootstrapDefaults(this, { _config: agentConfig, _skipConfigLoad: true });
402
-
403
- this._setReady();
404
- return this;
405
- }
406
-
407
- /**
408
- * 等待框架就绪
409
- */
410
- async ready() {
411
- if (this._ready) {
412
- return this;
413
- }
414
-
415
- if (!this._readyPromise) {
416
- this._readyPromise = new Promise((resolve) => {
417
- this._resolveReady = resolve;
418
- });
419
- }
420
-
421
- await this._readyPromise;
422
- return this;
423
- }
424
-
425
- /**
426
- * 标记框架就绪
427
- * @private
428
- */
429
- _setReady() {
430
- this._ready = true;
431
- if (this._resolveReady) {
432
- this._resolveReady(this);
433
- }
434
- this.emit('framework:ready', this);
435
- }
436
-
437
- /**
438
- * 注册内置工具
439
- * @private
440
- */
441
- _registerBuiltinTools() {
442
- // 内置工具会在 Agent 创建时添加)
443
- }
444
-
445
- /**
446
- * 销毁框架)
447
- */
448
- async destroy() {
449
- // 卸载所有插件)
450
- const plugins = this.pluginManager.getAll();
451
- for (const { name } of plugins) {
452
- await this.pluginManager.unload(name);
453
- }
454
-
455
- // 清空工具
456
- this.toolRegistry.clear();
457
-
458
- // 清空事件
459
- this.removeAllListeners();
460
-
461
- this.emit('framework:destroyed');
462
- }
463
- }
464
-
465
- module.exports = { Framework };
1
+ /**
2
+ * Framework 核心容器
3
+ * 管理所有子系统,提供统一入口
4
+ */
5
+
6
+ const path = require('path');
7
+ const { AsyncLocalStorage } = require('async_hooks');
8
+ const { EventEmitter } = require('../utils/event-emitter');
9
+ const { PluginManager } = require('./plugin-manager');
10
+ const { ToolRegistry } = require('./tool-registry');
11
+ const { Agent } = require('./agent');
12
+ const { SubAgentConfigManager } = require('./sub-agent-config');
13
+
14
+ // 添加框架目录的 node_modules 到全局搜索路径
15
+ // 让项目插件能 require 框架内置的包(如 zod)
16
+ const frameworkNodeModules = path.join(__dirname, '..', '..', 'node_modules');
17
+ if (!module.paths.includes(frameworkNodeModules)) {
18
+ module.paths.unshift(frameworkNodeModules);
19
+ }
20
+
21
+ // AsyncLocalStorage 实现真正的上下文隔离(支持并行处理)
22
+ const asyncLocalStorage = new AsyncLocalStorage();
23
+
24
+ class Framework extends EventEmitter {
25
+ /**
26
+ * @param {Object} config - 配置
27
+ * @param {boolean} [config.debug=false] - 调试模式
28
+ */
29
+ constructor(config = {}) {
30
+ super();
31
+
32
+ this._debug = config.debug || false;
33
+ this._ready = false;
34
+ this._readyPromise = null;
35
+ this._resolveReady = null;
36
+
37
+ // 初始化子系统
38
+ this.toolRegistry = new ToolRegistry();
39
+ this.pluginManager = new PluginManager(this);
40
+
41
+ // Agent 管理
42
+ this._agents = []; // 所有创建的 agent
43
+ this._mainAgent = null; // 主 agent
44
+
45
+ // 子代理配置管理器
46
+ this._subAgentConfigManager = null;
47
+
48
+ // 执行上下文(工具调用时可用)
49
+ this._executionContext = null;
50
+
51
+ // 事件转发
52
+ this.toolRegistry.on('tool:registered', (tool) => {
53
+ this.emit('tool:registered', tool);
54
+ });
55
+
56
+ this._registerBuiltinTools();
57
+ }
58
+
59
+ /**
60
+ * 从 AI 插件合并配置到目标配置对象
61
+ * @param {Object} target - 目标配置对象
62
+ * @private
63
+ */
64
+ _mergeAIConfig(target) {
65
+ if (target.apiKey) return target; // 已有 apiKey 不需要合并
66
+
67
+ const aiPlugin = this.pluginManager.get('ai');
68
+ if (!aiPlugin) return target;
69
+
70
+ const defaults = {
71
+ apiKey: aiPlugin.config.apiKey,
72
+ provider: aiPlugin.config.provider,
73
+ model: aiPlugin.config.model,
74
+ baseURL: aiPlugin.config.baseURL,
75
+ providerOptions: aiPlugin.config.providerOptions || {},
76
+ };
77
+
78
+ return {
79
+ ...target,
80
+ apiKey: target.apiKey || defaults.apiKey,
81
+ provider: target.provider || defaults.provider,
82
+ model: target.model || defaults.model,
83
+ baseURL: target.baseURL || defaults.baseURL,
84
+ providerOptions: target.providerOptions || defaults.providerOptions,
85
+ };
86
+ }
87
+
88
+ /**
89
+ * 注册插件(不加载)
90
+ * @param {Plugin|Object} plugin - 插件
91
+ */
92
+ registerPlugin(plugin) {
93
+ this.pluginManager.register(plugin);
94
+ return this;
95
+ }
96
+
97
+ /**
98
+ * 加载并启动插件)
99
+ * @param {Plugin|Object} plugin - 插件
100
+ */
101
+ async loadPlugin(plugin) {
102
+ await this.pluginManager.load(plugin);
103
+ return this;
104
+ }
105
+
106
+ /**
107
+ * 卸载插件
108
+ * @param {string} name - 插件名称
109
+ */
110
+ async unloadPlugin(name) {
111
+ await this.pluginManager.unload(name);
112
+ return this;
113
+ }
114
+
115
+ /**
116
+ * 重载单个插件
117
+ * @param {string} name - 插件名称
118
+ */
119
+ async reloadPlugin(name) {
120
+ await this.pluginManager.reload(name);
121
+ return this;
122
+ }
123
+
124
+ /**
125
+ * 重载所有插件)
126
+ */
127
+ async reloadAllPlugins() {
128
+ await this.pluginManager.reloadAll();
129
+ return this;
130
+ }
131
+
132
+ /**
133
+ * 启用插件
134
+ * @param {string} name - 插件名称
135
+ */
136
+ async enablePlugin(name) {
137
+ await this.pluginManager.enable(name);
138
+ return this;
139
+ }
140
+
141
+ /**
142
+ * 禁用插件
143
+ * @param {string} name - 插件名称
144
+ */
145
+ async disablePlugin(name) {
146
+ await this.pluginManager.disable(name);
147
+ return this;
148
+ }
149
+
150
+ /**
151
+ * 更新插件配置
152
+ * @param {string} name - 插件名称
153
+ * @param {Object} config - 新配置
154
+ */
155
+ updatePluginConfig(name, config) {
156
+ return this.pluginManager.updatePluginConfig(name, config);
157
+ }
158
+
159
+ /**
160
+ * 注册工具
161
+ * @param {Object} tool - 工具定义
162
+ */
163
+ registerTool(tool) {
164
+ this.toolRegistry.register(tool);
165
+ return this;
166
+ }
167
+
168
+ /**
169
+ * 获取所有工具)
170
+ * @returns {Array<Object>}
171
+ */
172
+ getTools() {
173
+ return this.toolRegistry.getAll();
174
+ }
175
+
176
+ // ============================================================================
177
+ // 事件描述注册(供 Ambient Agent 使用)
178
+ // ============================================================================
179
+
180
+ /**
181
+ * 注册事件描述
182
+ * @param {string} eventType - 事件类型,如 'tool:result'
183
+ * @param {string} description - 事件描述
184
+ * @param {Object} schema - 事件参数 Schema(可选)
185
+ */
186
+ registerEventDescription(eventType, description, schema = null) {
187
+ this.pluginManager.registerEventDescription(eventType, description, schema);
188
+ return this;
189
+ }
190
+
191
+ /**
192
+ * 获取所有已注册的事件描述
193
+ * @returns {Map<string, Object>} 事件描述 Map
194
+ */
195
+ getEventDescriptions() {
196
+ return this.pluginManager.getEventDescriptions();
197
+ }
198
+
199
+ /**
200
+ * 获取单个事件描述
201
+ * @param {string} eventType - 事件类型
202
+ * @returns {Object|null} 事件描述
203
+ */
204
+ getEventDescription(eventType) {
205
+ return this.pluginManager.getEventDescription(eventType);
206
+ }
207
+
208
+ /**
209
+ * 执行工具
210
+ * @param {string} name - 工具名称
211
+ * @param {Object} args - 参数
212
+ */
213
+ async executeTool(name, args) {
214
+ return this.toolRegistry.execute(name, args, this);
215
+ }
216
+
217
+ /**
218
+ * 在上下文中执行函数(支持并行处理,自动隔离 session)
219
+ * @param {Object} context - 执行上下文 { sessionId, ... }
220
+ * @param {Function} fn - 要执行的异步函数
221
+ * @returns {Promise}
222
+ */
223
+ runWithContext(context, fn) {
224
+ return asyncLocalStorage.run(context, fn);
225
+ }
226
+
227
+ /**
228
+ * 获取当前执行上下文(在 runWithContext 内部调用)
229
+ * @returns {Object|null}
230
+ */
231
+ getExecutionContext() {
232
+ return asyncLocalStorage.getStore() || null;
233
+ }
234
+
235
+ /**
236
+ * @deprecated 使用 runWithContext 代替
237
+ */
238
+ setExecutionContext() {}
239
+
240
+ /**
241
+ * @deprecated 使用 runWithContext 代替
242
+ */
243
+ clearExecutionContext() {}
244
+
245
+ /**
246
+ * 创建 Agent
247
+ * @param {Object} config - Agent 配置
248
+ */
249
+ createAgent(config) {
250
+ // 合并 AI 插件配置
251
+ config = this._mergeAIConfig(config);
252
+
253
+ const agent = new Agent(this, config);
254
+
255
+ // 跟踪 agent
256
+ this._agents.push(agent);
257
+ if (!this._mainAgent) {
258
+ this._mainAgent = agent;
259
+ }
260
+
261
+ this.emit('agent:created', agent);
262
+ return agent;
263
+ }
264
+
265
+ /**
266
+ * 为指定 session 创建独立 Agent 实例
267
+ * @param {string} sessionId - session ID
268
+ * @param {Object} config - Agent 配置
269
+ */
270
+ createSessionAgent(sessionId, config = {}) {
271
+ const agentConfig = {
272
+ name: `session_${sessionId}`,
273
+ ...config,
274
+ };
275
+
276
+ // 合并 AI 插件配置
277
+ const merged = this._mergeAIConfig(agentConfig);
278
+
279
+ const agent = new Agent(this, merged);
280
+ this._agents.push(agent);
281
+
282
+ // 如果提供了 systemPrompt,需要替换 AgentChatHandler
283
+ if (merged.systemPrompt) {
284
+ agent.setSystemPrompt(merged.systemPrompt);
285
+ }
286
+
287
+ this.emit('agent:created', agent);
288
+ return agent;
289
+ }
290
+
291
+ /**
292
+ * 创建子Agent(具有独立工具集的轻量级Agent)
293
+ * @param {Object} config - 子Agent配置
294
+ * @param {string} config.name - 子Agent名称
295
+ * @param {string} config.role - 角色描述(用于智能选择)
296
+ * @param {string} [config.description] - 供主Agent理解的描述)
297
+ * @param {Object} [config.tools] - 自定义工具 { name: toolDef }
298
+ * @param {string[]} [config.parentTools] - 从父Agent继承的工具名称列表)
299
+ * @param {Object} [config.llmConfig] - 独立LLM配置
300
+ * @returns {Agent} 创建的子Agent
301
+ */
302
+ createSubAgent(config) {
303
+ const {
304
+ name,
305
+ role,
306
+ description = '',
307
+ tools = {},
308
+ parentTools, // 如果不传,默认继承主agent所有工具
309
+ llmConfig = null,
310
+ } = config;
311
+
312
+ // 构建子Agent配置
313
+ const agentConfig = {
314
+ name: `subagent_${name}`,
315
+ role: role,
316
+ systemPrompt: role, // 使用 role 作为 systemPrompt
317
+ ...(llmConfig || {}), // 如果提供了独立LLM配置,合并
318
+ };
319
+
320
+ // 合并 AI 插件配置
321
+ const merged = this._mergeAIConfig(agentConfig);
322
+
323
+ // 创建 Agent
324
+ const agent = new Agent(this, merged);
325
+
326
+ // 注册自定义工具
327
+ for (const [toolName, toolDef] of Object.entries(tools)) {
328
+ if (toolDef && typeof toolDef === 'object') {
329
+ agent.registerTool({
330
+ name: toolName,
331
+ description: toolDef.description || '',
332
+ inputSchema: toolDef.inputSchema,
333
+ execute: toolDef.execute,
334
+ });
335
+ }
336
+ }
337
+
338
+ // 从父Agent继承工具
339
+ if (this._mainAgent) {
340
+ const parentToolsDefs = this._mainAgent.getTools();
341
+ if (parentTools === undefined) {
342
+ // 如果没有指定 parentTools,默认继承所有工具
343
+ for (const toolDef of parentToolsDefs) {
344
+ agent.registerTool(toolDef);
345
+ }
346
+ } else if (Array.isArray(parentTools) && parentTools.length > 0) {
347
+ // 指定了要继承的工具列表
348
+ for (const toolName of parentTools) {
349
+ const toolDef = parentToolsDefs.find((t) => t.name === toolName);
350
+ if (toolDef) {
351
+ agent.registerTool(toolDef);
352
+ }
353
+ }
354
+ }
355
+ }
356
+
357
+ this._agents.push(agent);
358
+ this.emit('agent:created', agent);
359
+ return agent;
360
+ }
361
+
362
+ /**
363
+ * 获取 AI 插件
364
+ * @returns {Object|undefined}
365
+ */
366
+ getAIPlugin() {
367
+ return this.pluginManager.get('ai');
368
+ }
369
+
370
+ /**
371
+ * Bootstrap - 使用默认配置启动框架
372
+ * 自动加载 .agent/ 目录下的配置和所有默认插件)
373
+ * @param {Object} config - 配置
374
+ * @param {string} [config.agentDir='.agent'] - Agent 配置目录
375
+ * @param {Object} [config.aiConfig] - AI 配置(可选,覆盖文件配置)
376
+ * @returns {Promise<Framework>}
377
+ */
378
+ async bootstrap(config = {}) {
379
+ const {
380
+ bootstrapDefaults,
381
+ DefaultPlugins,
382
+ loadAgentConfig,
383
+ } = require('../../plugins/default-plugins');
384
+
385
+ // 先加载默认插件配置
386
+ const defaultsPlugin = new DefaultPlugins({
387
+ agentDir: config.agentDir || '.agent',
388
+ });
389
+
390
+ await this.loadPlugin(defaultsPlugin);
391
+
392
+ // 获取配置
393
+ const agentConfig = defaultsPlugin.getConfig();
394
+
395
+ // 如果提供了 AI 配置,覆盖文件配置
396
+ if (config.aiConfig) {
397
+ agentConfig.ai = { ...agentConfig.ai, ...config.aiConfig };
398
+ }
399
+
400
+ // 加载所有默认插件(传入已加载的配置避免重复加载)
401
+ await bootstrapDefaults(this, { _config: agentConfig, _skipConfigLoad: true });
402
+
403
+ this._setReady();
404
+ return this;
405
+ }
406
+
407
+ /**
408
+ * 等待框架就绪
409
+ */
410
+ async ready() {
411
+ if (this._ready) {
412
+ return this;
413
+ }
414
+
415
+ if (!this._readyPromise) {
416
+ this._readyPromise = new Promise((resolve) => {
417
+ this._resolveReady = resolve;
418
+ });
419
+ }
420
+
421
+ await this._readyPromise;
422
+ return this;
423
+ }
424
+
425
+ /**
426
+ * 标记框架就绪
427
+ * @private
428
+ */
429
+ _setReady() {
430
+ this._ready = true;
431
+ if (this._resolveReady) {
432
+ this._resolveReady(this);
433
+ }
434
+ this.emit('framework:ready', this);
435
+ }
436
+
437
+ /**
438
+ * 注册内置工具
439
+ * @private
440
+ */
441
+ _registerBuiltinTools() {
442
+ // 内置工具会在 Agent 创建时添加)
443
+ }
444
+
445
+ /**
446
+ * 销毁框架)
447
+ */
448
+ async destroy() {
449
+ // 卸载所有插件)
450
+ const plugins = this.pluginManager.getAll();
451
+ for (const { name } of plugins) {
452
+ await this.pluginManager.unload(name);
453
+ }
454
+
455
+ // 清空工具
456
+ this.toolRegistry.clear();
457
+
458
+ // 清空事件
459
+ this.removeAllListeners();
460
+
461
+ this.emit('framework:destroyed');
462
+ }
463
+ }
464
+
465
+ module.exports = { Framework };