foliko 1.0.74 → 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 (238) hide show
  1. package/.agent/.shared/ui-ux-pro-max/data/charts.csv +26 -0
  2. package/.agent/.shared/ui-ux-pro-max/data/colors.csv +97 -0
  3. package/.agent/.shared/ui-ux-pro-max/data/icons.csv +101 -0
  4. package/.agent/.shared/ui-ux-pro-max/data/landing.csv +31 -0
  5. package/.agent/.shared/ui-ux-pro-max/data/products.csv +97 -0
  6. package/.agent/.shared/ui-ux-pro-max/data/prompts.csv +24 -0
  7. package/.agent/.shared/ui-ux-pro-max/data/react-performance.csv +45 -0
  8. package/.agent/.shared/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
  9. package/.agent/.shared/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
  10. package/.agent/.shared/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
  11. package/.agent/.shared/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
  12. package/.agent/.shared/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
  13. package/.agent/.shared/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
  14. package/.agent/.shared/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
  15. package/.agent/.shared/ui-ux-pro-max/data/stacks/react.csv +54 -0
  16. package/.agent/.shared/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
  17. package/.agent/.shared/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
  18. package/.agent/.shared/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
  19. package/.agent/.shared/ui-ux-pro-max/data/stacks/vue.csv +50 -0
  20. package/.agent/.shared/ui-ux-pro-max/data/styles.csv +59 -0
  21. package/.agent/.shared/ui-ux-pro-max/data/typography.csv +58 -0
  22. package/.agent/.shared/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
  23. package/.agent/.shared/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
  24. package/.agent/.shared/ui-ux-pro-max/data/web-interface.csv +31 -0
  25. package/.agent/.shared/ui-ux-pro-max/scripts/__pycache__/core.cpython-313.pyc +0 -0
  26. package/.agent/.shared/ui-ux-pro-max/scripts/__pycache__/design_system.cpython-313.pyc +0 -0
  27. package/.agent/.shared/ui-ux-pro-max/scripts/core.py +258 -0
  28. package/.agent/.shared/ui-ux-pro-max/scripts/design_system.py +1067 -0
  29. package/.agent/.shared/ui-ux-pro-max/scripts/search.py +106 -0
  30. package/.agent/ARCHITECTURE.md +288 -0
  31. package/.agent/agents/ambient-agent.md +57 -0
  32. package/.agent/agents/debugger.md +55 -0
  33. package/.agent/agents/email-assistant.md +49 -0
  34. package/.agent/agents/file-manager.md +42 -0
  35. package/.agent/agents/python-developer.md +60 -0
  36. package/.agent/agents/scheduler.md +59 -0
  37. package/.agent/agents/web-developer.md +45 -0
  38. package/.agent/data/default.json +29 -0
  39. package/.agent/data/plugins-state.json +255 -0
  40. package/.agent/mcp_config.json +4 -0
  41. package/.agent/mcp_config_updated.json +12 -0
  42. package/.agent/plugins.json +5 -0
  43. package/.agent/rules/GEMINI.md +273 -0
  44. package/.agent/rules/allow-rule.md +77 -0
  45. package/.agent/rules/log-rule.md +83 -0
  46. package/.agent/rules/security-rule.md +93 -0
  47. package/.agent/scripts/auto_preview.py +148 -0
  48. package/.agent/scripts/checklist.py +217 -0
  49. package/.agent/scripts/session_manager.py +120 -0
  50. package/.agent/scripts/verify_all.py +327 -0
  51. package/.agent/skills/api-patterns/SKILL.md +81 -0
  52. package/.agent/skills/api-patterns/api-style.md +42 -0
  53. package/.agent/skills/api-patterns/auth.md +24 -0
  54. package/.agent/skills/api-patterns/documentation.md +26 -0
  55. package/.agent/skills/api-patterns/graphql.md +41 -0
  56. package/.agent/skills/api-patterns/rate-limiting.md +31 -0
  57. package/.agent/skills/api-patterns/response.md +37 -0
  58. package/.agent/skills/api-patterns/rest.md +40 -0
  59. package/.agent/skills/api-patterns/scripts/api_validator.py +211 -0
  60. package/.agent/skills/api-patterns/security-testing.md +122 -0
  61. package/.agent/skills/api-patterns/trpc.md +41 -0
  62. package/.agent/skills/api-patterns/versioning.md +22 -0
  63. package/.agent/skills/app-builder/SKILL.md +75 -0
  64. package/.agent/skills/app-builder/agent-coordination.md +71 -0
  65. package/.agent/skills/app-builder/feature-building.md +53 -0
  66. package/.agent/skills/app-builder/project-detection.md +34 -0
  67. package/.agent/skills/app-builder/scaffolding.md +118 -0
  68. package/.agent/skills/app-builder/tech-stack.md +40 -0
  69. package/.agent/skills/app-builder/templates/SKILL.md +39 -0
  70. package/.agent/skills/app-builder/templates/astro-static/TEMPLATE.md +76 -0
  71. package/.agent/skills/app-builder/templates/chrome-extension/TEMPLATE.md +92 -0
  72. package/.agent/skills/app-builder/templates/cli-tool/TEMPLATE.md +88 -0
  73. package/.agent/skills/app-builder/templates/electron-desktop/TEMPLATE.md +88 -0
  74. package/.agent/skills/app-builder/templates/express-api/TEMPLATE.md +83 -0
  75. package/.agent/skills/app-builder/templates/flutter-app/TEMPLATE.md +90 -0
  76. package/.agent/skills/app-builder/templates/monorepo-turborepo/TEMPLATE.md +90 -0
  77. package/.agent/skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md +122 -0
  78. package/.agent/skills/app-builder/templates/nextjs-saas/TEMPLATE.md +122 -0
  79. package/.agent/skills/app-builder/templates/nextjs-static/TEMPLATE.md +169 -0
  80. package/.agent/skills/app-builder/templates/nuxt-app/TEMPLATE.md +134 -0
  81. package/.agent/skills/app-builder/templates/python-fastapi/TEMPLATE.md +83 -0
  82. package/.agent/skills/app-builder/templates/react-native-app/TEMPLATE.md +119 -0
  83. package/.agent/skills/architecture/SKILL.md +55 -0
  84. package/.agent/skills/architecture/context-discovery.md +43 -0
  85. package/.agent/skills/architecture/examples.md +94 -0
  86. package/.agent/skills/architecture/pattern-selection.md +68 -0
  87. package/.agent/skills/architecture/patterns-reference.md +50 -0
  88. package/.agent/skills/architecture/trade-off-analysis.md +77 -0
  89. package/.agent/skills/clean-code/SKILL.md +201 -0
  90. package/.agent/skills/doc.md +177 -0
  91. package/.agent/skills/frontend-design/SKILL.md +418 -0
  92. package/.agent/skills/frontend-design/animation-guide.md +331 -0
  93. package/.agent/skills/frontend-design/color-system.md +311 -0
  94. package/.agent/skills/frontend-design/decision-trees.md +418 -0
  95. package/.agent/skills/frontend-design/motion-graphics.md +306 -0
  96. package/.agent/skills/frontend-design/scripts/accessibility_checker.py +183 -0
  97. package/.agent/skills/frontend-design/scripts/ux_audit.py +722 -0
  98. package/.agent/skills/frontend-design/typography-system.md +345 -0
  99. package/.agent/skills/frontend-design/ux-psychology.md +1116 -0
  100. package/.agent/skills/frontend-design/visual-effects.md +383 -0
  101. package/.agent/skills/i18n-localization/SKILL.md +154 -0
  102. package/.agent/skills/i18n-localization/scripts/i18n_checker.py +241 -0
  103. package/.agent/skills/mcp-builder/SKILL.md +176 -0
  104. package/.agent/skills/web-design-guidelines/SKILL.md +57 -0
  105. package/.agent/workflows/brainstorm.md +113 -0
  106. package/.agent/workflows/create.md +59 -0
  107. package/.agent/workflows/debug.md +103 -0
  108. package/.agent/workflows/deploy.md +176 -0
  109. package/.agent/workflows/enhance.md +63 -0
  110. package/.agent/workflows/orchestrate.md +237 -0
  111. package/.agent/workflows/plan.md +89 -0
  112. package/.agent/workflows/preview.md +81 -0
  113. package/.agent/workflows/simple-test.md +42 -0
  114. package/.agent/workflows/status.md +86 -0
  115. package/.agent/workflows/structured-orchestrate.md +180 -0
  116. package/.agent/workflows/test.md +144 -0
  117. package/.agent/workflows/ui-ux-pro-max.md +296 -0
  118. package/.claude/settings.local.json +11 -1
  119. package/.editorconfig +56 -0
  120. package/.husky/pre-commit +4 -0
  121. package/.lintstagedrc +7 -0
  122. package/.prettierignore +29 -0
  123. package/.prettierrc +11 -0
  124. package/CLAUDE.md +2 -0
  125. package/README.md +64 -55
  126. package/SPEC.md +102 -61
  127. package/cli/bin/foliko.js +11 -11
  128. package/cli/src/commands/chat.js +143 -141
  129. package/cli/src/commands/list.js +93 -90
  130. package/cli/src/index.js +75 -75
  131. package/cli/src/ui/chat-ui.js +201 -199
  132. package/cli/src/utils/ansi.js +40 -40
  133. package/cli/src/utils/markdown.js +292 -296
  134. package/docker-compose.yml +1 -1
  135. package/docs/ai-sdk-optimization.md +655 -643
  136. package/docs/features.md +80 -80
  137. package/docs/quick-reference.md +49 -46
  138. package/docs/user-manual.md +411 -380
  139. package/examples/ambient-example.js +194 -196
  140. package/examples/basic.js +50 -45
  141. package/examples/bootstrap.js +121 -112
  142. package/examples/mcp-example.js +19 -16
  143. package/examples/skill-example.js +20 -20
  144. package/examples/test-chat.js +137 -135
  145. package/examples/test-mcp.js +85 -79
  146. package/examples/test-reload.js +59 -61
  147. package/examples/test-telegram.js +50 -50
  148. package/examples/test-tg-bot.js +45 -42
  149. package/examples/test-tg-simple.js +47 -46
  150. package/examples/test-tg.js +62 -62
  151. package/examples/test-think.js +43 -37
  152. package/examples/test-web-plugin.js +103 -98
  153. package/examples/test-weixin-feishu.js +103 -100
  154. package/examples/workflow.js +158 -158
  155. package/package.json +37 -3
  156. package/plugins/ai-plugin.js +102 -100
  157. package/plugins/ambient-agent/EventWatcher.js +113 -0
  158. package/plugins/ambient-agent/ExplorerLoop.js +640 -0
  159. package/plugins/ambient-agent/GoalManager.js +197 -0
  160. package/plugins/ambient-agent/Reflector.js +95 -0
  161. package/plugins/ambient-agent/StateStore.js +90 -0
  162. package/plugins/ambient-agent/constants.js +101 -0
  163. package/plugins/ambient-agent/index.js +579 -0
  164. package/plugins/audit-plugin.js +187 -187
  165. package/plugins/default-plugins.js +662 -649
  166. package/plugins/email/constants.js +64 -0
  167. package/plugins/email/handlers.js +461 -0
  168. package/plugins/email/index.js +278 -0
  169. package/plugins/email/monitor.js +269 -0
  170. package/plugins/email/parser.js +138 -0
  171. package/plugins/email/reply.js +151 -0
  172. package/plugins/email/utils.js +124 -0
  173. package/plugins/feishu-plugin.js +481 -477
  174. package/plugins/file-system-plugin.js +826 -476
  175. package/plugins/install-plugin.js +199 -197
  176. package/plugins/python-executor-plugin.js +367 -365
  177. package/plugins/python-plugin-loader.js +481 -479
  178. package/plugins/rules-plugin.js +294 -292
  179. package/plugins/scheduler-plugin.js +691 -689
  180. package/plugins/session-plugin.js +369 -367
  181. package/plugins/shell-executor-plugin.js +197 -197
  182. package/plugins/storage-plugin.js +240 -238
  183. package/plugins/subagent-plugin.js +845 -785
  184. package/plugins/telegram-plugin.js +482 -475
  185. package/plugins/think-plugin.js +345 -343
  186. package/plugins/tools-plugin.js +196 -194
  187. package/plugins/web-plugin.js +606 -604
  188. package/plugins/weixin-plugin.js +545 -538
  189. package/reports/system-health-report-20260401.md +79 -0
  190. package/skills/ambient-agent/SKILL.md +49 -39
  191. package/skills/foliko-dev/AGENTS.md +64 -61
  192. package/skills/foliko-dev/SKILL.md +125 -119
  193. package/skills/mcp-usage/SKILL.md +19 -17
  194. package/skills/python-plugin-dev/SKILL.md +16 -15
  195. package/skills/skill-guide/SKILL.md +12 -12
  196. package/skills/subagent-guide/SKILL.md +237 -0
  197. package/skills/workflow-guide/SKILL.md +90 -45
  198. package/skills/workflow-troubleshooting/DEBUGGING.md +36 -21
  199. package/skills/workflow-troubleshooting/SKILL.md +156 -79
  200. package/src/capabilities/index.js +11 -11
  201. package/src/capabilities/skill-manager.js +609 -595
  202. package/src/capabilities/workflow-engine.js +1109 -1195
  203. package/src/core/agent-chat.js +882 -735
  204. package/src/core/agent.js +892 -688
  205. package/src/core/framework.js +465 -431
  206. package/src/core/index.js +19 -19
  207. package/src/core/plugin-base.js +219 -219
  208. package/src/core/plugin-manager.js +863 -767
  209. package/src/core/provider.js +114 -111
  210. package/src/core/sub-agent-config.js +264 -0
  211. package/src/core/system-prompt-builder.js +120 -0
  212. package/src/core/tool-registry.js +517 -134
  213. package/src/core/tool-router.js +297 -216
  214. package/src/executors/executor-base.js +12 -12
  215. package/src/executors/mcp-executor.js +741 -729
  216. package/src/index.js +25 -37
  217. package/src/utils/circuit-breaker.js +301 -0
  218. package/src/utils/error-boundary.js +363 -0
  219. package/src/utils/error.js +374 -0
  220. package/src/utils/event-emitter.js +97 -97
  221. package/src/utils/id.js +133 -0
  222. package/src/utils/index.js +217 -3
  223. package/src/utils/logger.js +181 -0
  224. package/src/utils/plugin-helpers.js +90 -0
  225. package/src/utils/retry.js +122 -0
  226. package/src/utils/sandbox.js +292 -0
  227. package/test/tool-registry-validation.test.js +218 -0
  228. package/test_report.md +70 -0
  229. package/website/docs/api.html +169 -107
  230. package/website/docs/configuration.html +296 -144
  231. package/website/docs/plugin-development.html +154 -85
  232. package/website/docs/project-structure.html +110 -109
  233. package/website/docs/skill-development.html +117 -61
  234. package/website/index.html +209 -205
  235. package/website/script.js +136 -133
  236. package/website/styles.css +1 -1
  237. package/plugins/ambient-agent-plugin.js +0 -1565
  238. package/plugins/email.js +0 -1142
@@ -1,431 +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
-
13
- // 添加框架目录的 node_modules 到全局搜索路径
14
- // 让项目插件能 require 框架内置的包(如 zod)
15
- const frameworkNodeModules = path.join(__dirname, '..', '..', 'node_modules')
16
- if (!module.paths.includes(frameworkNodeModules)) {
17
- module.paths.unshift(frameworkNodeModules)
18
- }
19
-
20
- // AsyncLocalStorage 实现真正的上下文隔离(支持并行处理)
21
- const asyncLocalStorage = new AsyncLocalStorage()
22
-
23
- class Framework extends EventEmitter {
24
- /**
25
- * @param {Object} config - 配置
26
- * @param {boolean} [config.debug=false] - 调试模式
27
- */
28
- constructor(config = {}) {
29
- super()
30
-
31
- this._debug = config.debug || false
32
- this._ready = false
33
- this._readyPromise = null
34
- this._resolveReady = null
35
-
36
- // 初始化子系统
37
- this.toolRegistry = new ToolRegistry()
38
- this.pluginManager = new PluginManager(this)
39
-
40
- // Agent 管理
41
- this._agents = [] // 所有创建的 agent
42
- this._mainAgent = null // agent
43
-
44
- // 执行上下文(工具调用时可用)
45
- this._executionContext = null
46
-
47
- // 事件转发
48
- this.toolRegistry.on('tool:registered', (tool) => {
49
- this.emit('tool:registered', tool)
50
- })
51
-
52
- this._registerBuiltinTools()
53
- }
54
-
55
- /**
56
- * 注册插件(不加载)
57
- * @param {Plugin|Object} plugin - 插件
58
- */
59
- registerPlugin(plugin) {
60
- this.pluginManager.register(plugin)
61
- return this
62
- }
63
-
64
- /**
65
- * 加载并启动插件
66
- * @param {Plugin|Object} plugin - 插件
67
- */
68
- async loadPlugin(plugin) {
69
- await this.pluginManager.load(plugin)
70
- return this
71
- }
72
-
73
- /**
74
- * 卸载插件
75
- * @param {string} name - 插件名称
76
- */
77
- async unloadPlugin(name) {
78
- await this.pluginManager.unload(name)
79
- return this
80
- }
81
-
82
- /**
83
- * 重载单个插件
84
- * @param {string} name - 插件名称
85
- */
86
- async reloadPlugin(name) {
87
- await this.pluginManager.reload(name)
88
- return this
89
- }
90
-
91
- /**
92
- * 重载所有插件
93
- */
94
- async reloadAllPlugins() {
95
- await this.pluginManager.reloadAll()
96
- return this
97
- }
98
-
99
- /**
100
- * 启用插件
101
- * @param {string} name - 插件名称
102
- */
103
- async enablePlugin(name) {
104
- await this.pluginManager.enable(name)
105
- return this
106
- }
107
-
108
- /**
109
- * 禁用插件
110
- * @param {string} name - 插件名称
111
- */
112
- async disablePlugin(name) {
113
- await this.pluginManager.disable(name)
114
- return this
115
- }
116
-
117
- /**
118
- * 更新插件配置
119
- * @param {string} name - 插件名称
120
- * @param {Object} config - 新配置
121
- */
122
- updatePluginConfig(name, config) {
123
- return this.pluginManager.updatePluginConfig(name, config)
124
- }
125
-
126
- /**
127
- * 注册工具
128
- * @param {Object} tool - 工具定义
129
- */
130
- registerTool(tool) {
131
- this.toolRegistry.register(tool)
132
- return this
133
- }
134
-
135
- /**
136
- * 获取所有工具
137
- * @returns {Array<Object>}
138
- */
139
- getTools() {
140
- return this.toolRegistry.getAll()
141
- }
142
-
143
- /**
144
- * 执行工具
145
- * @param {string} name - 工具名称
146
- * @param {Object} args - 参数
147
- */
148
- async executeTool(name, args) {
149
- return this.toolRegistry.execute(name, args, this)
150
- }
151
-
152
- /**
153
- * 在上下文中执行函数(支持并行处理,自动隔离 session)
154
- * @param {Object} context - 执行上下文 { sessionId, ... }
155
- * @param {Function} fn - 要执行的异步函数
156
- * @returns {Promise}
157
- */
158
- runWithContext(context, fn) {
159
- return asyncLocalStorage.run(context, fn)
160
- }
161
-
162
- /**
163
- * 获取当前执行上下文(在 runWithContext 内部调用)
164
- * @returns {Object|null}
165
- */
166
- getExecutionContext() {
167
- return asyncLocalStorage.getStore() || null
168
- }
169
-
170
- /**
171
- * @deprecated 使用 runWithContext 代替
172
- */
173
- setExecutionContext() {}
174
-
175
- /**
176
- * @deprecated 使用 runWithContext 代替
177
- */
178
- clearExecutionContext() {}
179
-
180
- /**
181
- * 创建 Agent
182
- * @param {Object} config - Agent 配置
183
- */
184
- createAgent(config) {
185
- // 如果配置了 AI 相关参数但没有 apiKey,尝试从 AI 插件获取
186
- if (!config.apiKey) {
187
- const aiPlugin = this.pluginManager.get('ai')
188
- if (aiPlugin) {
189
- config.apiKey = aiPlugin.config.apiKey
190
- config.provider = config.provider || aiPlugin.config.provider
191
- config.model = config.model || aiPlugin.config.model
192
- config.baseURL = config.baseURL || aiPlugin.config.baseURL
193
- }
194
- }
195
-
196
- const agent = new Agent(this, config)
197
-
198
- // 跟踪 agent
199
- this._agents.push(agent)
200
- if (!this._mainAgent) {
201
- this._mainAgent = agent
202
- }
203
-
204
- this.emit('agent:created', agent)
205
- return agent
206
- }
207
-
208
- /**
209
- * 为指定 session 创建独立的 Agent 实例
210
- * @param {string} sessionId - session ID
211
- * @param {Object} config - Agent 配置
212
- */
213
- createSessionAgent(sessionId, config = {}) {
214
- const agentConfig = {
215
- name: `session_${sessionId}`,
216
- ...config
217
- }
218
-
219
- // 如果没有提供 AI 相关参数,从 AI 插件获取
220
- if (!agentConfig.apiKey) {
221
- const aiPlugin = this.pluginManager.get('ai')
222
- if (aiPlugin) {
223
- agentConfig.apiKey = aiPlugin.config.apiKey
224
- agentConfig.provider = agentConfig.provider || aiPlugin.config.provider
225
- agentConfig.model = agentConfig.model || aiPlugin.config.model
226
- agentConfig.baseURL = agentConfig.baseURL || aiPlugin.config.baseURL,
227
- agentConfig.providerOptions||aiPlugin.config.providerOptions||{}
228
- }
229
- }
230
- const agent = new Agent(this, agentConfig)
231
- this._agents.push(agent)
232
-
233
- // 如果提供了 systemPrompt,需要更新 AgentChatHandler
234
- if (agentConfig.systemPrompt) {
235
- agent.setSystemPrompt(agentConfig.systemPrompt)
236
- }
237
-
238
- this.emit('agent:created', agent)
239
- return agent
240
- }
241
-
242
- /**
243
- * 创建子Agent(具有独立工具集的轻量级Agent)
244
- * @param {Object} config - 子Agent配置
245
- * @param {string} config.name - 子Agent名称
246
- * @param {string} config.role - 角色描述(用于智能选择)
247
- * @param {string} [config.description] - 供主Agent理解的描述
248
- * @param {Object} [config.tools] - 自定义工具 { name: toolDef }
249
- * @param {string[]} [config.parentTools] - 从父Agent继承的工具名称列表
250
- * @param {Object} [config.llmConfig] - 独立LLM配置
251
- * @returns {Agent} 创建的子Agent
252
- */
253
- createSubAgent(config) {
254
- const {
255
- name,
256
- role,
257
- description = '',
258
- tools = {},
259
- parentTools, // 如果不传,默认继承主agent所有工具
260
- llmConfig = null
261
- } = config
262
-
263
- // 构建子Agent配置
264
- const agentConfig = {
265
- name: `subagent_${name}`,
266
- role: role,
267
- systemPrompt: role, // 使用 role 作为 systemPrompt
268
- ...(llmConfig || {}) // 如果提供了独立LLM配置,合并
269
- }
270
-
271
- // 如果没有提供 AI 相关参数,从 AI 插件获取
272
- if (!agentConfig.apiKey) {
273
- const aiPlugin = this.pluginManager.get('ai')
274
- if (aiPlugin) {
275
- agentConfig.apiKey = aiPlugin.config.apiKey
276
- agentConfig.provider = agentConfig.provider || aiPlugin.config.provider
277
- agentConfig.model = agentConfig.model || aiPlugin.config.model
278
- agentConfig.baseURL = agentConfig.baseURL || aiPlugin.config.baseURL
279
- agentConfig.providerOptions = agentConfig.providerOptions || aiPlugin.config.providerOptions || {}
280
- }
281
- }
282
-
283
- // 创建 Agent
284
- const agent = new Agent(this, agentConfig)
285
-
286
- // 注册自定义工具
287
- for (const [toolName, toolDef] of Object.entries(tools)) {
288
- if (toolDef && typeof toolDef === 'object') {
289
- agent.registerTool({
290
- name: toolName,
291
- description: toolDef.description || '',
292
- inputSchema: toolDef.inputSchema,
293
- execute: toolDef.execute
294
- })
295
- }
296
- }
297
-
298
- // 从父Agent继承工具
299
- if (this._mainAgent) {
300
- const parentToolsDefs = this._mainAgent.getTools()
301
- if (parentTools === undefined) {
302
- // 如果没有指定 parentTools,默认继承所有工具
303
- for (const toolDef of parentToolsDefs) {
304
- agent.registerTool(toolDef)
305
- }
306
- } else if (Array.isArray(parentTools) && parentTools.length > 0) {
307
- // 指定了要继承的工具列表
308
- for (const toolName of parentTools) {
309
- const toolDef = parentToolsDefs.find(t => t.name === toolName)
310
- if (toolDef) {
311
- agent.registerTool(toolDef)
312
- }
313
- }
314
- }
315
- }
316
-
317
- this._agents.push(agent)
318
- this.emit('agent:created', agent)
319
- return agent
320
- }
321
-
322
- /**
323
- * 获取 AI 插件
324
- * @returns {Object|undefined}
325
- */
326
- getAIPlugin() {
327
- return this.pluginManager.get('ai')
328
- }
329
-
330
- /**
331
- * Bootstrap - 使用默认配置启动框架
332
- * 自动加载 .agent/ 目录下的配置和所有默认插件
333
- * @param {Object} config - 配置
334
- * @param {string} [config.agentDir='.agent'] - Agent 配置目录
335
- * @param {Object} [config.aiConfig] - AI 配置(可选,覆盖文件配置)
336
- * @returns {Promise<Framework>}
337
- */
338
- async bootstrap(config = {}) {
339
- const { bootstrapDefaults, DefaultPlugins, loadAgentConfig } = require('../../plugins/default-plugins')
340
-
341
- // 先加载默认插件配置
342
- const defaultsPlugin = new DefaultPlugins({
343
- agentDir: config.agentDir || '.agent'
344
- })
345
-
346
- await this.loadPlugin(defaultsPlugin)
347
-
348
- // 获取配置
349
- const agentConfig = defaultsPlugin.getConfig()
350
-
351
- // 如果提供了 AI 配置,覆盖文件配置
352
- if (config.aiConfig) {
353
- agentConfig.ai = { ...agentConfig.ai, ...config.aiConfig }
354
- }
355
-
356
- // 加载所有默认插件(传入已加载的配置避免重复加载)
357
- await bootstrapDefaults(this, { _config: agentConfig, _skipConfigLoad: true })
358
-
359
- this._setReady()
360
- return this
361
- }
362
-
363
- /**
364
- * 等待框架就绪
365
- */
366
- async ready() {
367
- if (this._ready) {
368
- return this
369
- }
370
-
371
- if (!this._readyPromise) {
372
- this._readyPromise = new Promise((resolve) => {
373
- this._resolveReady = resolve
374
- })
375
- }
376
-
377
- await this._readyPromise
378
- return this
379
- }
380
-
381
- /**
382
- * 标记框架就绪
383
- * @private
384
- */
385
- _setReady() {
386
- this._ready = true
387
- if (this._resolveReady) {
388
- this._resolveReady(this)
389
- }
390
- this.emit('framework:ready', this)
391
- }
392
-
393
- /**
394
- * 调试日志
395
- * @private
396
- */
397
- _log(...args) {
398
- if (this._debug) {
399
- console.log('[Framework]', ...args)
400
- }
401
- }
402
-
403
- /**
404
- * 注册内置工具
405
- * @private
406
- */
407
- _registerBuiltinTools() {
408
- // 内置工具会在 Agent 创建时添加
409
- }
410
-
411
- /**
412
- * 销毁框架
413
- */
414
- async destroy() {
415
- // 卸载所有插件
416
- const plugins = this.pluginManager.getAll()
417
- for (const { name } of plugins) {
418
- await this.pluginManager.unload(name)
419
- }
420
-
421
- // 清空工具
422
- this.toolRegistry.clear()
423
-
424
- // 清空事件
425
- this.removeAllListeners()
426
-
427
- this.emit('framework:destroyed')
428
- }
429
- }
430
-
431
- 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 };