foliko 1.1.93 → 2.0.1
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/.claude/settings.local.json +2 -1
- package/CLAUDE.md +56 -30
- package/REFACTORING_PLAN.md +645 -0
- package/docs/architecture.md +131 -0
- package/docs/migration.md +57 -0
- package/docs/public-api.md +138 -0
- package/docs/usage.md +385 -0
- package/examples/ambient-example.js +20 -137
- package/examples/basic.js +21 -48
- package/examples/bootstrap.js +16 -74
- package/examples/mcp-example.js +6 -29
- package/examples/skill-example.js +6 -19
- package/examples/workflow.js +8 -56
- package/package.json +8 -4
- package/plugins/README.md +49 -0
- package/plugins/{ambient-agent → ambient}/EventWatcher.js +1 -1
- package/plugins/{ambient-agent → ambient}/ExplorerLoop.js +3 -3
- package/plugins/{ambient-agent → ambient}/GoalManager.js +2 -2
- package/plugins/ambient/README.md +14 -0
- package/plugins/{ambient-agent → ambient}/Reflector.js +1 -1
- package/plugins/{ambient-agent → ambient}/StateStore.js +1 -1
- package/plugins/{ambient-agent → ambient}/index.js +2 -2
- package/plugins/{ai-plugin.js → core/ai/index.js} +14 -30
- package/plugins/{audit-plugin.js → core/audit/index.js} +3 -30
- package/plugins/{coordinator-plugin.js → core/coordinator/index.js} +3 -35
- package/plugins/core/default/bootstrap.js +224 -0
- package/plugins/core/default/config.js +222 -0
- package/plugins/core/default/index.js +58 -0
- package/plugins/core/mcp/index.js +1 -0
- package/plugins/{python-plugin-loader.js → core/python-loader/index.js} +7 -187
- package/plugins/{rules-plugin.js → core/rules/index.js} +121 -64
- package/plugins/{scheduler-plugin.js → core/scheduler/index.js} +12 -114
- package/plugins/{session-plugin.js → core/session/index.js} +9 -73
- package/{src/capabilities/skill-manager.js → plugins/core/skill-manager/index.js} +64 -18
- package/plugins/{storage-plugin.js → core/storage/index.js} +5 -29
- package/plugins/{subagent-plugin.js → core/sub-agent/index.js} +10 -171
- package/plugins/{think-plugin.js → core/think/index.js} +24 -91
- package/{src/capabilities/workflow-engine.js → plugins/core/workflow/index.js} +87 -85
- package/plugins/default-plugins.js +6 -720
- package/plugins/{data-splitter-plugin.js → executors/data-splitter/index.js} +9 -83
- package/plugins/{extension-executor-plugin.js → executors/extension/index.js} +13 -97
- package/plugins/{python-executor-plugin.js → executors/python/index.js} +6 -31
- package/plugins/{shell-executor-plugin.js → executors/shell/index.js} +2 -5
- package/plugins/install/README.md +9 -0
- package/plugins/{install-plugin.js → install/index.js} +3 -3
- package/plugins/{file-system-plugin.js → io/file-system/index.js} +34 -236
- package/plugins/{web-plugin.js → io/web/index.js} +11 -113
- package/plugins/memory/README.md +13 -0
- package/plugins/{memory-plugin.js → memory/index.js} +4 -18
- package/plugins/messaging/email/README.md +19 -0
- package/plugins/{email → messaging/email}/index.js +3 -3
- package/plugins/{feishu-plugin.js → messaging/feishu/index.js} +4 -4
- package/plugins/{qq-plugin.js → messaging/qq/index.js} +6 -17
- package/plugins/{telegram-plugin.js → messaging/telegram/index.js} +4 -4
- package/plugins/{weixin-plugin.js → messaging/weixin/index.js} +16 -16
- package/plugins/{plugin-manager-plugin.js → plugin-manager/index.js} +36 -180
- package/plugins/{tools-plugin.js → tools/index.js} +68 -116
- package/plugins/trading/README.md +15 -0
- package/plugins/{gate-trading.js → trading/index.js} +8 -8
- package/{examples → sandbox}/test-concurrent-chat.js +2 -2
- package/{examples → sandbox}/test-long-chat.js +2 -2
- package/{examples → sandbox}/test-session-chat.js +2 -2
- package/{examples → sandbox}/test-web-plugin.js +1 -1
- package/{examples → sandbox}/test-weixin-feishu.js +2 -2
- package/src/agent/base.js +56 -0
- package/src/{core/agent-chat.js → agent/chat.js} +11 -11
- package/src/{core/coordinator-manager.js → agent/coordinator.js} +3 -3
- package/src/agent/index.js +111 -0
- package/src/agent/main.js +337 -0
- package/src/agent/prompt.js +78 -0
- package/src/agent/sub.js +198 -0
- package/src/agent/worker.js +104 -0
- package/{cli/bin/foliko.js → src/cli/bin.js} +1 -1
- package/{cli/src → src/cli}/commands/chat.js +25 -21
- package/{cli/src → src/cli}/index.js +1 -0
- package/{cli/src → src/cli}/ui/chat-ui-old.js +40 -178
- package/{cli/src → src/cli}/ui/chat-ui.js +3 -3
- package/{cli/src → src/cli}/ui/components/footer-bar.js +1 -1
- package/src/common/errors.js +402 -0
- package/src/{utils → common}/logger.js +33 -0
- package/src/{utils/chat-queue.js → common/queue.js} +2 -2
- package/src/config/plugin-config.js +50 -0
- package/src/context/agent.js +32 -0
- package/src/context/compaction-prompts.js +170 -0
- package/src/context/compaction-utils.js +191 -0
- package/src/context/compressor.js +413 -0
- package/src/context/index.js +9 -0
- package/src/{core/context-manager.js → context/manager.js} +1 -1
- package/src/context/request.js +50 -0
- package/src/context/session.js +33 -0
- package/src/context/storage.js +30 -0
- package/src/executors/mcp-client.js +153 -0
- package/src/executors/mcp-desc.js +236 -0
- package/src/executors/mcp-executor.js +91 -956
- package/src/{core → framework}/command-registry.js +1 -1
- package/src/framework/framework.js +300 -0
- package/src/framework/index.js +18 -0
- package/src/framework/lifecycle.js +203 -0
- package/src/framework/loader.js +78 -0
- package/src/framework/registry.js +86 -0
- package/src/{core/ui-extension-context.js → framework/ui-extension.js} +1 -1
- package/src/index.js +130 -15
- package/src/llm/index.js +26 -0
- package/src/llm/provider.js +212 -0
- package/src/llm/registry.js +11 -0
- package/src/{core/token-counter.js → llm/tokens.js} +4 -37
- package/src/{core/plugin-base.js → plugin/base.js} +10 -136
- package/src/plugin/index.js +14 -0
- package/src/plugin/loader.js +101 -0
- package/src/plugin/manager.js +484 -0
- package/src/{core → session}/branch-summary-auto.js +2 -2
- package/src/{core/chat-session.js → session/chat.js} +2 -2
- package/src/session/index.js +7 -0
- package/src/{core/session-manager.js → session/session.js} +2 -2
- package/src/session/ttl.js +92 -0
- package/src/{core/jsonl-storage.js → storage/jsonl.js} +1 -1
- package/src/tool/executor.js +85 -0
- package/src/tool/index.js +15 -0
- package/src/tool/registry.js +143 -0
- package/src/{core/tool-router.js → tool/router.js} +17 -124
- package/src/tool/schema.js +108 -0
- package/src/utils/data-splitter.js +1 -1
- package/src/utils/download.js +1 -1
- package/src/utils/index.js +6 -6
- package/src/utils/message-validator.js +1 -1
- package/tests/core/context-storage.test.js +46 -0
- package/tests/core/llm.test.js +54 -0
- package/tests/core/plugin.test.js +42 -0
- package/tests/core/tool.test.js +60 -0
- package/tests/setup.js +10 -0
- package/tests/smoke.test.js +58 -0
- package/vitest.config.js +9 -0
- package/cli/src/daemon.js +0 -149
- package/docs/CONTEXT_DESIGN.md +0 -1596
- package/docs/ai-sdk-optimization.md +0 -655
- package/docs/features.md +0 -120
- package/docs/qq-bot.md +0 -976
- package/docs/quick-reference.md +0 -160
- package/docs/user-manual.md +0 -1391
- package/images/geometric_shapes.jpg +0 -0
- package/images/sunset_mountain_lake.jpg +0 -0
- package/skills/poster-guide/SKILL.md +0 -792
- package/src/capabilities/index.js +0 -11
- package/src/core/agent.js +0 -808
- package/src/core/context-compressor.js +0 -959
- package/src/core/enhanced-context-compressor.js +0 -210
- package/src/core/framework.js +0 -1422
- package/src/core/index.js +0 -30
- package/src/core/plugin-manager.js +0 -961
- package/src/core/provider-registry.js +0 -159
- package/src/core/provider.js +0 -156
- package/src/core/request-context.js +0 -98
- package/src/core/subagent.js +0 -442
- package/src/core/system-prompt-builder.js +0 -120
- package/src/core/tool-executor.js +0 -202
- package/src/core/tool-registry.js +0 -517
- package/src/core/worker-agent.js +0 -192
- package/src/executors/executor-base.js +0 -58
- package/src/utils/error-boundary.js +0 -363
- package/src/utils/error.js +0 -374
- package/system.md +0 -1645
- package/website_v2/README.md +0 -57
- package/website_v2/SPEC.md +0 -1
- package/website_v2/docs/api.html +0 -128
- package/website_v2/docs/configuration.html +0 -147
- package/website_v2/docs/plugin-development.html +0 -129
- package/website_v2/docs/project-structure.html +0 -89
- package/website_v2/docs/skill-development.html +0 -85
- package/website_v2/index.html +0 -489
- package/website_v2/scripts/main.js +0 -93
- package/website_v2/styles/animations.css +0 -8
- package/website_v2/styles/docs.css +0 -83
- package/website_v2/styles/main.css +0 -417
- package/xhs_auth.json +0 -268
- package//346/265/267/346/212/245/346/217/222/344/273/266.md +0 -621
- /package/plugins/{ambient-agent → ambient}/constants.js +0 -0
- /package/plugins/{email → messaging/email}/constants.js +0 -0
- /package/plugins/{email → messaging/email}/handlers.js +0 -0
- /package/plugins/{email → messaging/email}/monitor.js +0 -0
- /package/plugins/{email → messaging/email}/parser.js +0 -0
- /package/plugins/{email → messaging/email}/reply.js +0 -0
- /package/plugins/{email → messaging/email}/utils.js +0 -0
- /package/{examples → sandbox}/test-chat.js +0 -0
- /package/{examples → sandbox}/test-mcp.js +0 -0
- /package/{examples → sandbox}/test-reload.js +0 -0
- /package/{examples → sandbox}/test-telegram.js +0 -0
- /package/{examples → sandbox}/test-tg-bot.js +0 -0
- /package/{examples → sandbox}/test-tg-simple.js +0 -0
- /package/{examples → sandbox}/test-tg.js +0 -0
- /package/{examples → sandbox}/test-think.js +0 -0
- /package/src/{core/sub-agent-config.js → agent/sub-config.js} +0 -0
- /package/{cli/src → src/cli}/commands/daemon.js +0 -0
- /package/{cli/src → src/cli}/commands/list.js +0 -0
- /package/{cli/src → src/cli}/commands/plugin.js +0 -0
- /package/{cli/src → src/cli}/ui/components/agent-mention-provider.js +0 -0
- /package/{cli/src → src/cli}/ui/components/chained-autocomplete-provider.js +0 -0
- /package/{cli/src → src/cli}/ui/components/message-bubble.js +0 -0
- /package/{cli/src → src/cli}/ui/components/status-bar.js +0 -0
- /package/{cli/src → src/cli}/utils/ansi.js +0 -0
- /package/{cli/src → src/cli}/utils/config.js +0 -0
- /package/{cli/src → src/cli}/utils/markdown.js +0 -0
- /package/{cli/src → src/cli}/utils/plugin-config.js +0 -0
- /package/{cli/src → src/cli}/utils/render-diff.js +0 -0
- /package/src/{utils/circuit-breaker.js → common/circuit.js} +0 -0
- /package/src/{core → common}/constants.js +0 -0
- /package/src/{utils/edit-diff.js → common/diff.js} +0 -0
- /package/src/{utils/event-emitter.js → common/events.js} +0 -0
- /package/src/{utils → common}/id.js +0 -0
- /package/src/{utils → common}/retry.js +0 -0
- /package/src/{core/notification-manager.js → notification/manager.js} +0 -0
- /package/src/{core/session-entry.js → session/entry.js} +0 -0
- /package/src/{core/storage-manager.js → storage/manager.js} +0 -0
|
@@ -5,11 +5,10 @@
|
|
|
5
5
|
|
|
6
6
|
const fs = require('fs')
|
|
7
7
|
const path = require('path')
|
|
8
|
-
const { Plugin } = require('
|
|
9
|
-
const { logger } = require('
|
|
8
|
+
const { Plugin } = require('../../../src/plugin/base')
|
|
9
|
+
const { logger } = require('../../../src/common/logger')
|
|
10
10
|
const log = logger.child('SubAgent')
|
|
11
11
|
const { z } = require('zod')
|
|
12
|
-
const { Agent } = require('../src/core/agent')
|
|
13
12
|
|
|
14
13
|
class SubAgentPlugin extends Plugin {
|
|
15
14
|
constructor(config = {}) {
|
|
@@ -19,16 +18,13 @@ class SubAgentPlugin extends Plugin {
|
|
|
19
18
|
this.description = config.description || `子Agent: ${config.name}`
|
|
20
19
|
this.priority = 10
|
|
21
20
|
|
|
22
|
-
this.system = true
|
|
21
|
+
this.system = true
|
|
23
22
|
|
|
24
23
|
this.role= config.role || config.name
|
|
25
24
|
this.tools = config.tools || {}
|
|
26
25
|
this.parentTools = config.parentTools || []
|
|
27
26
|
this.llmConfig = config.llmConfig || null
|
|
28
27
|
|
|
29
|
-
// 子Agent配置
|
|
30
|
-
// tools: { toolName: toolFn } 自定义工具(只属于此子Agent)
|
|
31
|
-
// parentTools: ['read_file'] 从父Agent继承的工具名称列表
|
|
32
28
|
this.config = {}
|
|
33
29
|
|
|
34
30
|
this._framework = null
|
|
@@ -42,31 +38,19 @@ class SubAgentPlugin extends Plugin {
|
|
|
42
38
|
}
|
|
43
39
|
|
|
44
40
|
start(framework) {
|
|
45
|
-
// 创建子Agent(可能需要等待父agent准备好)
|
|
46
41
|
this._createSubAgent()
|
|
47
|
-
|
|
48
|
-
// 注册委托工具到主Agent(通过framework获取父agent)
|
|
49
42
|
this._registerDelegateTool()
|
|
50
|
-
|
|
51
43
|
return this
|
|
52
44
|
}
|
|
53
45
|
|
|
54
|
-
/**
|
|
55
|
-
* 创建子Agent
|
|
56
|
-
*/
|
|
57
46
|
_createSubAgent() {
|
|
58
|
-
// 获取父Agent(主Agent)
|
|
59
47
|
const parentAgent = this._getParentAgent()
|
|
60
48
|
if (!parentAgent) {
|
|
61
|
-
// 父agent还没创建,监听事件等其创建
|
|
62
49
|
if (this._framework) {
|
|
63
50
|
this._framework.on('agent:created', (agent) => {
|
|
64
51
|
if (this._framework._mainAgent && agent === this._framework._mainAgent) {
|
|
65
|
-
// 父agent已创建,更新父agent引用
|
|
66
52
|
this._parentAgent = agent
|
|
67
|
-
// 重新尝试创建子agent
|
|
68
53
|
this._doCreateSubAgent(agent)
|
|
69
|
-
// 注册委托工具
|
|
70
54
|
this._registerDelegateTool()
|
|
71
55
|
}
|
|
72
56
|
})
|
|
@@ -77,19 +61,11 @@ class SubAgentPlugin extends Plugin {
|
|
|
77
61
|
this._doCreateSubAgent(parentAgent)
|
|
78
62
|
}
|
|
79
63
|
|
|
80
|
-
/**
|
|
81
|
-
* 实际执行创建子Agent
|
|
82
|
-
*/
|
|
83
64
|
_doCreateSubAgent(parentAgent) {
|
|
84
|
-
// 避免重复创建
|
|
85
65
|
if (this._agent) {
|
|
86
66
|
return
|
|
87
67
|
}
|
|
88
68
|
|
|
89
|
-
// 获取从父Agent继承的工具
|
|
90
|
-
// const parentTools = this._getParentTools(parentAgent)
|
|
91
|
-
|
|
92
|
-
// 确定LLM配置
|
|
93
69
|
const aiPlugin = this._framework.pluginManager.get('ai')
|
|
94
70
|
const llmConfig = this.llmConfig || (aiPlugin ? aiPlugin.getConfig() : {})
|
|
95
71
|
const all_tools=['ext_call']
|
|
@@ -99,7 +75,6 @@ class SubAgentPlugin extends Plugin {
|
|
|
99
75
|
const list=this.tools.split(',').map(a=>a.trim())
|
|
100
76
|
all_tools.push(...list)
|
|
101
77
|
}
|
|
102
|
-
// 创建子Agent,使用完整的 md 文件内容作为系统提示词
|
|
103
78
|
this._agent = this._framework.createSubAgent({
|
|
104
79
|
name: this.name,
|
|
105
80
|
systemPrompt: this._getFullSystemPrompt(),
|
|
@@ -107,46 +82,29 @@ class SubAgentPlugin extends Plugin {
|
|
|
107
82
|
provider: llmConfig.provider,
|
|
108
83
|
apiKey: llmConfig.apiKey,
|
|
109
84
|
baseURL: llmConfig.baseURL,
|
|
110
|
-
tools:{},
|
|
85
|
+
tools:{},
|
|
111
86
|
parentTools: all_tools
|
|
112
87
|
})
|
|
113
88
|
|
|
114
|
-
|
|
115
|
-
// 注册从父Agent继承的工具
|
|
116
|
-
// for (const tool of parentTools) {
|
|
117
|
-
// this._framework.registerTool(tool)
|
|
118
|
-
// }
|
|
119
|
-
|
|
120
|
-
// Register custom tools (only for this subAgent, won't pollute global)
|
|
121
|
-
// tools format: { toolName: toolDef }
|
|
122
|
-
|
|
123
89
|
this._parentAgent = parentAgent
|
|
124
90
|
|
|
125
|
-
// 注册子Agent到父Agent
|
|
126
91
|
parentAgent.registerSubAgent(this.name, this._agent, this.role, this.description)
|
|
127
92
|
|
|
128
|
-
// 监听子Agent的chunk事件并转发给父Agent
|
|
129
93
|
this._agent.on('chunk', (chunk) => {
|
|
130
94
|
chunk.fromSubAgent = this.name
|
|
131
95
|
parentAgent.emit('chunk', chunk)
|
|
132
96
|
})
|
|
133
97
|
}
|
|
134
98
|
|
|
135
|
-
/**
|
|
136
|
-
* 获取父Agent
|
|
137
|
-
*/
|
|
138
99
|
_getParentAgent() {
|
|
139
|
-
// 优先使用外部传入的获取器
|
|
140
100
|
if (this.config._parentAgentGetter) {
|
|
141
101
|
return this.config._parentAgentGetter()
|
|
142
102
|
}
|
|
143
103
|
|
|
144
|
-
// 尝试从framework获取主agent
|
|
145
104
|
if (this._framework._mainAgent) {
|
|
146
105
|
return this._framework._mainAgent
|
|
147
106
|
}
|
|
148
107
|
|
|
149
|
-
// 查找最后一个创建的agent作为父agent
|
|
150
108
|
const agents = this._framework._agents || []
|
|
151
109
|
if (agents.length > 0) {
|
|
152
110
|
return agents[agents.length - 1]
|
|
@@ -155,22 +113,16 @@ class SubAgentPlugin extends Plugin {
|
|
|
155
113
|
return null
|
|
156
114
|
}
|
|
157
115
|
|
|
158
|
-
/**
|
|
159
|
-
* 获取从父Agent继承的工具
|
|
160
|
-
*/
|
|
161
116
|
_getParentTools(parentAgent) {
|
|
162
117
|
const allTools = parentAgent.getTools ? parentAgent.getTools() : []
|
|
163
118
|
const toolMap = new Map(allTools.map(t => [t.name, t]))
|
|
164
119
|
|
|
165
|
-
// 如果没有指定 parentTools,返回全部
|
|
166
120
|
if (this.parentTools === undefined) {
|
|
167
121
|
return allTools
|
|
168
122
|
}
|
|
169
|
-
// 如果是空数组,明确返回空(不要任何工具)
|
|
170
123
|
if (this.parentTools.length === 0) {
|
|
171
124
|
return []
|
|
172
125
|
}
|
|
173
|
-
// 过滤指定工具
|
|
174
126
|
const filtered = []
|
|
175
127
|
for (const toolName of this.parentTools) {
|
|
176
128
|
const tool = toolMap.get(toolName)
|
|
@@ -182,9 +134,6 @@ class SubAgentPlugin extends Plugin {
|
|
|
182
134
|
return filtered
|
|
183
135
|
}
|
|
184
136
|
|
|
185
|
-
/**
|
|
186
|
-
* 构建系统提示
|
|
187
|
-
*/
|
|
188
137
|
_buildSystemPrompt() {
|
|
189
138
|
return `你是 ${this.role}。
|
|
190
139
|
|
|
@@ -209,9 +158,6 @@ class SubAgentPlugin extends Plugin {
|
|
|
209
158
|
- 不先调用 ext_skill/loadSkill 就直接使用 ext_call`
|
|
210
159
|
}
|
|
211
160
|
|
|
212
|
-
/**
|
|
213
|
-
* 注册委托工具到框架和主Agent
|
|
214
|
-
*/
|
|
215
161
|
_registerDelegateTool() {
|
|
216
162
|
const framework = this._framework
|
|
217
163
|
if (!framework) return
|
|
@@ -235,7 +181,6 @@ class SubAgentPlugin extends Plugin {
|
|
|
235
181
|
return { error: `Parent agent not found` }
|
|
236
182
|
}
|
|
237
183
|
|
|
238
|
-
// 发射子Agent开始处理事件
|
|
239
184
|
parentAgent.emit('subagent:chat:start', {
|
|
240
185
|
parentAgent,
|
|
241
186
|
subAgent: this._agent,
|
|
@@ -245,7 +190,6 @@ class SubAgentPlugin extends Plugin {
|
|
|
245
190
|
|
|
246
191
|
try {
|
|
247
192
|
const result = await this._agent.chat(args.task)
|
|
248
|
-
// 发射子Agent完成处理事件
|
|
249
193
|
parentAgent.emit('subagent:chat:end', {
|
|
250
194
|
parentAgent,
|
|
251
195
|
subAgent: this._agent,
|
|
@@ -258,7 +202,6 @@ class SubAgentPlugin extends Plugin {
|
|
|
258
202
|
success: result.success !== false
|
|
259
203
|
}
|
|
260
204
|
} catch (err) {
|
|
261
|
-
// 发射子Agent错误事件
|
|
262
205
|
parentAgent.emit('subagent:error', {
|
|
263
206
|
parentAgent,
|
|
264
207
|
subAgent: this._agent,
|
|
@@ -274,57 +217,37 @@ class SubAgentPlugin extends Plugin {
|
|
|
274
217
|
}
|
|
275
218
|
}
|
|
276
219
|
|
|
277
|
-
// 注册到框架(供后续创建的 Agent 同步)
|
|
278
220
|
framework.registerTool(toolDef)
|
|
279
221
|
|
|
280
|
-
// // 如果主 Agent 已存在,直接注册到它
|
|
281
222
|
if (framework._mainAgent) {
|
|
282
223
|
framework._mainAgent.registerTool(toolDef)
|
|
283
224
|
}
|
|
284
|
-
|
|
285
|
-
//console.log(`[SubAgent:${this.config.name}] Delegate tool registered`)
|
|
286
225
|
}
|
|
287
226
|
|
|
288
|
-
/**
|
|
289
|
-
* 获取子Agent实例
|
|
290
|
-
*/
|
|
291
227
|
getAgent() {
|
|
292
228
|
return this._agent
|
|
293
229
|
}
|
|
294
230
|
|
|
295
|
-
/**
|
|
296
|
-
* 调用子Agent处理任务
|
|
297
|
-
* 延迟创建 Agent,使用完整的 md 文件内容作为系统提示词
|
|
298
|
-
*/
|
|
299
231
|
async chat(task) {
|
|
300
|
-
// 延迟创建 Agent(如果尚未创建)
|
|
301
232
|
if (!this._agent) {
|
|
302
233
|
await this._createSubAgentForChat();
|
|
303
234
|
} else {
|
|
304
|
-
// 每次调用时更新系统提示词,确保使用最新的 md 文件内容
|
|
305
235
|
this._updateAgentSystemPrompt();
|
|
306
236
|
}
|
|
307
237
|
return this._agent.chat(task)
|
|
308
238
|
}
|
|
309
239
|
|
|
310
|
-
/**
|
|
311
|
-
* 创建用于聊天的高完整度 Agent
|
|
312
|
-
* 使用 SubAgentConfig 读取完整的 md 文件内容
|
|
313
|
-
*/
|
|
314
240
|
async _createSubAgentForChat() {
|
|
315
241
|
const parentAgent = this._getParentAgent();
|
|
316
242
|
if (!parentAgent) {
|
|
317
243
|
throw new Error(`SubAgent ${this.name}: parent agent not found`);
|
|
318
244
|
}
|
|
319
245
|
|
|
320
|
-
// 使用 SubAgentConfig 获取完整的系统提示词
|
|
321
246
|
const systemPrompt = this._getFullSystemPrompt();
|
|
322
247
|
const parentTools = this._getParentTools(parentAgent)
|
|
323
|
-
// 获取 LLM 配置
|
|
324
248
|
const aiPlugin = this._framework.pluginManager.get('ai');
|
|
325
249
|
const llmConfig = this.llmConfig || (aiPlugin ? aiPlugin.getConfig() : {});
|
|
326
250
|
|
|
327
|
-
// 创建 Agent,使用完整的 md 内容作为系统提示词
|
|
328
251
|
this._agent = this._framework.createSubAgent({
|
|
329
252
|
name: this.name,
|
|
330
253
|
systemPrompt: systemPrompt,
|
|
@@ -332,35 +255,26 @@ class SubAgentPlugin extends Plugin {
|
|
|
332
255
|
provider: llmConfig.provider,
|
|
333
256
|
apiKey: llmConfig.apiKey,
|
|
334
257
|
baseURL: llmConfig.baseURL,
|
|
335
|
-
tools: this.tools||{},
|
|
258
|
+
tools: this.tools||{},
|
|
336
259
|
parentTools: parentTools
|
|
337
260
|
});
|
|
338
261
|
|
|
339
|
-
// 注册到父 Agent
|
|
340
262
|
this._parentAgent = parentAgent;
|
|
341
263
|
parentAgent.registerSubAgent(this.name, this._agent, this.role, this.description);
|
|
342
264
|
}
|
|
343
265
|
|
|
344
|
-
/**
|
|
345
|
-
* 获取完整的系统提示词(从 md 文件读取)
|
|
346
|
-
*/
|
|
347
266
|
_getFullSystemPrompt() {
|
|
348
|
-
// 尝试从 SubAgentConfigManager 获取完整内容
|
|
349
267
|
const configManager = this._framework._subAgentConfigManager;
|
|
350
268
|
if (configManager) {
|
|
351
|
-
const config = configManager.get(this.name);
|
|
269
|
+
const config = configManager.get(this.name);
|
|
352
270
|
if (config) {
|
|
353
271
|
return config.getSystemPrompt();
|
|
354
272
|
}
|
|
355
273
|
}
|
|
356
274
|
|
|
357
|
-
// 回退到默认的 _buildSystemPrompt
|
|
358
275
|
return this._buildSystemPrompt();
|
|
359
276
|
}
|
|
360
277
|
|
|
361
|
-
/**
|
|
362
|
-
* 更新 Agent 的系统提示词
|
|
363
|
-
*/
|
|
364
278
|
_updateAgentSystemPrompt() {
|
|
365
279
|
if (!this._agent) return;
|
|
366
280
|
const systemPrompt = this._getFullSystemPrompt();
|
|
@@ -385,9 +299,6 @@ class SubAgentPlugin extends Plugin {
|
|
|
385
299
|
}
|
|
386
300
|
}
|
|
387
301
|
|
|
388
|
-
/**
|
|
389
|
-
* SubAgentManager - 管理多个子Agent
|
|
390
|
-
*/
|
|
391
302
|
class SubAgentManagerPlugin extends Plugin {
|
|
392
303
|
constructor(config = {}) {
|
|
393
304
|
super()
|
|
@@ -398,9 +309,9 @@ class SubAgentManagerPlugin extends Plugin {
|
|
|
398
309
|
this.systemPrompt= `你是一个子Agent管理器,负责管理多个子Agent。每个子Agent都有独立的工具集和角色描述。当需要处理特定任务时,你会选择合适的子Agent来执行。`
|
|
399
310
|
|
|
400
311
|
this.priority = 10
|
|
401
|
-
this.agents = config.agents || []
|
|
312
|
+
this.agents = config.agents || []
|
|
402
313
|
this.config = {
|
|
403
|
-
agentsDir: config.agentsDir,
|
|
314
|
+
agentsDir: config.agentsDir,
|
|
404
315
|
}
|
|
405
316
|
|
|
406
317
|
this._framework = null
|
|
@@ -413,10 +324,8 @@ class SubAgentManagerPlugin extends Plugin {
|
|
|
413
324
|
}
|
|
414
325
|
|
|
415
326
|
start(framework) {
|
|
416
|
-
// 从 agentsDir 加载子Agent配置
|
|
417
327
|
this._loadAgentsFromDir()
|
|
418
328
|
|
|
419
|
-
// 创建所有配置的子Agent
|
|
420
329
|
for (const agentConfig of this.agents) {
|
|
421
330
|
const plugin = new SubAgentPlugin(agentConfig)
|
|
422
331
|
plugin.install(framework)
|
|
@@ -424,30 +333,22 @@ class SubAgentManagerPlugin extends Plugin {
|
|
|
424
333
|
this._subAgents.set(agentConfig.name, plugin)
|
|
425
334
|
}
|
|
426
335
|
|
|
427
|
-
// 注册管理工具
|
|
428
|
-
// 如果主 Agent 已存在,直接注册到它(因为它不会自动同步框架工具)
|
|
429
336
|
if (framework._mainAgent) {
|
|
430
337
|
this._registerToolsToAgent(framework._mainAgent)
|
|
431
338
|
}
|
|
432
|
-
// 同时注册到框架(供后续创建的 Agent 同步)
|
|
433
339
|
this._registerTools(framework)
|
|
434
340
|
|
|
435
|
-
// 监听主 Agent 创建事件,为后续创建的主 Agent 注册工具
|
|
436
341
|
framework.on('agent:created', (agent) => {
|
|
437
342
|
if (framework._mainAgent && agent === framework._mainAgent) {
|
|
438
343
|
this._registerToolsToAgent(agent)
|
|
439
344
|
}
|
|
440
345
|
})
|
|
441
346
|
|
|
442
|
-
// 注册子 Agent 列表提示词
|
|
443
347
|
this.registerPromptPart('subagents', 85, () => this._buildDescription());
|
|
444
348
|
|
|
445
349
|
return this
|
|
446
350
|
}
|
|
447
351
|
|
|
448
|
-
/**
|
|
449
|
-
* 注册管理工具到指定 Agent
|
|
450
|
-
*/
|
|
451
352
|
_registerToolsToAgent(agent) {
|
|
452
353
|
agent.registerTool({
|
|
453
354
|
name: 'subagent_list',
|
|
@@ -510,13 +411,8 @@ class SubAgentManagerPlugin extends Plugin {
|
|
|
510
411
|
}
|
|
511
412
|
}
|
|
512
413
|
})
|
|
513
|
-
|
|
514
|
-
//log.info(' Management tools registered to agent')
|
|
515
414
|
}
|
|
516
415
|
|
|
517
|
-
/**
|
|
518
|
-
* 注册管理工具到框架工具注册表
|
|
519
|
-
*/
|
|
520
416
|
_registerTools(framework) {
|
|
521
417
|
framework.registerTool({
|
|
522
418
|
name: 'subagent_list',
|
|
@@ -578,31 +474,21 @@ class SubAgentManagerPlugin extends Plugin {
|
|
|
578
474
|
}
|
|
579
475
|
}
|
|
580
476
|
})
|
|
581
|
-
|
|
582
|
-
//log.info(' Management tools registered to framework')
|
|
583
477
|
}
|
|
584
478
|
|
|
585
|
-
/**
|
|
586
|
-
* 从 agentsDir 目录加载子Agent配置
|
|
587
|
-
*/
|
|
588
479
|
_loadAgentsFromDir() {
|
|
589
|
-
// 默认使用 .foliko/agents 目录
|
|
590
480
|
const agentsDir = this.config.agentsDir || path.join(this._framework?.getCwd?.() ?? process.cwd(), '.foliko', 'agents')
|
|
591
|
-
//log.info(' _loadAgentsFromDir called, agentsDir:', agentsDir)
|
|
592
481
|
if (!fs.existsSync(agentsDir)) {
|
|
593
|
-
//log.info(' agentsDir not found or does not exist')
|
|
594
482
|
return
|
|
595
483
|
}
|
|
596
484
|
|
|
597
485
|
const entries = fs.readdirSync(agentsDir, { withFileTypes: true })
|
|
598
|
-
//log.info(' Found entries:', entries.length)
|
|
599
486
|
|
|
600
487
|
for (const entry of entries) {
|
|
601
488
|
if (entry.isFile() && (entry.name.endsWith('.js') || entry.name.endsWith('.json') || entry.name.endsWith('.md'))) {
|
|
602
489
|
const baseName = entry.name.replace(/\.(js|json|md)$/, '')
|
|
603
490
|
const filePath = path.join(agentsDir, entry.name)
|
|
604
491
|
|
|
605
|
-
// 跳过与已有配置同名的
|
|
606
492
|
if (this.agents.some(a => a.name === baseName)) {
|
|
607
493
|
continue
|
|
608
494
|
}
|
|
@@ -613,11 +499,8 @@ class SubAgentManagerPlugin extends Plugin {
|
|
|
613
499
|
const content = fs.readFileSync(filePath, 'utf-8')
|
|
614
500
|
agentConfig = JSON.parse(content)
|
|
615
501
|
} else if (entry.name.endsWith('.md')) {
|
|
616
|
-
// 解析 markdown 文件,提取 JSON 配置
|
|
617
502
|
agentConfig = this._parseMarkdownConfig(filePath, baseName)
|
|
618
|
-
//log.info(' Parsed md:', baseName, agentConfig)
|
|
619
503
|
} else {
|
|
620
|
-
// 清除缓存并加载
|
|
621
504
|
delete require.cache[require.resolve(filePath)]
|
|
622
505
|
const mod = require(filePath)
|
|
623
506
|
agentConfig = typeof mod === 'function' ? mod() : mod
|
|
@@ -626,7 +509,6 @@ class SubAgentManagerPlugin extends Plugin {
|
|
|
626
509
|
if (agentConfig && agentConfig.name) {
|
|
627
510
|
agentConfig._fromDir = true
|
|
628
511
|
this.agents.push(agentConfig)
|
|
629
|
-
//log.info(' Loaded agent:', agentConfig.name)
|
|
630
512
|
} else {
|
|
631
513
|
log.warn(' Agent config has no name:', baseName, agentConfig)
|
|
632
514
|
}
|
|
@@ -637,78 +519,51 @@ class SubAgentManagerPlugin extends Plugin {
|
|
|
637
519
|
}
|
|
638
520
|
}
|
|
639
521
|
|
|
640
|
-
/**
|
|
641
|
-
* 解析 markdown 文件中的配置
|
|
642
|
-
* 支持格式:
|
|
643
|
-
* ```json
|
|
644
|
-
* { "name": "xxx", "role": "xxx" }
|
|
645
|
-
* ```
|
|
646
|
-
* 或直接用 frontmatter 格式
|
|
647
|
-
*/
|
|
648
522
|
_parseMarkdownConfig(filePath, defaultName) {
|
|
649
523
|
const content = fs.readFileSync(filePath, 'utf-8')
|
|
650
|
-
//log.info(' _parseMarkdownConfig:', filePath)
|
|
651
524
|
|
|
652
|
-
// 尝试从 code block 中提取 JSON
|
|
653
525
|
const jsonMatch = content.match(/```(?:json)?\s*\n([\s\S]*?)\n\s*```/)
|
|
654
526
|
if (jsonMatch) {
|
|
655
527
|
try {
|
|
656
|
-
|
|
657
|
-
//log.info(' Found JSON in code block')
|
|
658
|
-
return config
|
|
528
|
+
return JSON.parse(jsonMatch[1].trim())
|
|
659
529
|
} catch (err) {
|
|
660
|
-
// JSON 解析失败,继续
|
|
661
530
|
}
|
|
662
531
|
}
|
|
663
532
|
|
|
664
|
-
// 尝试从 frontmatter 格式中提取
|
|
665
533
|
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/)
|
|
666
534
|
if (frontmatterMatch) {
|
|
667
|
-
//log.info(' Found frontmatter')
|
|
668
535
|
const frontmatterContent = frontmatterMatch[1]
|
|
669
536
|
const parsed = this._parseYamlLike(frontmatterContent)
|
|
670
537
|
if (parsed && parsed.name) {
|
|
671
|
-
//log.info(' Parsed frontmatter:', parsed)
|
|
672
538
|
return { name: parsed.name || defaultName, ...parsed }
|
|
673
539
|
}
|
|
674
540
|
}
|
|
675
541
|
|
|
676
|
-
// 从 markdown 内容中提取配置(key: value 格式)
|
|
677
542
|
const config = { name: defaultName }
|
|
678
543
|
const yamlMatch = content.match(/^(name|role|description|parentTools|tools):\s*(.+)$/m)
|
|
679
544
|
if (yamlMatch) {
|
|
680
545
|
config[yamlMatch[1]] = yamlMatch[2].trim()
|
|
681
546
|
}
|
|
682
547
|
|
|
683
|
-
// 如果没有找到配置,使用文件名作为 name
|
|
684
548
|
return config
|
|
685
549
|
}
|
|
686
550
|
|
|
687
|
-
|
|
688
|
-
/**
|
|
689
|
-
* 构建子Agent描述
|
|
690
|
-
* 使用数组收集 + join 模式优化字符串拼接
|
|
691
|
-
* 动态从配置文件读取每个子Agent的专业领域
|
|
692
|
-
*/
|
|
693
551
|
_buildDescription() {
|
|
694
552
|
const allSubAgents = this.getAllSubAgents();
|
|
695
553
|
if (!allSubAgents || allSubAgents.length === 0) {
|
|
696
554
|
return '';
|
|
697
555
|
}
|
|
698
556
|
|
|
699
|
-
// 使用数组收集 + join 模式优化字符串拼接
|
|
700
557
|
const lines = ['## 子 Agent 匹配表', ''];
|
|
701
558
|
lines.push('');
|
|
702
559
|
lines.push('> **提示**:根据任务类型选择最匹配的子 Agent 处理');
|
|
703
560
|
lines.push('');
|
|
704
561
|
|
|
705
|
-
// 动态从配置文件读取每个子Agent的核心能力
|
|
706
562
|
for (const plugin of allSubAgents) {
|
|
707
563
|
const name = plugin.name;
|
|
708
564
|
const role = plugin.role;
|
|
709
565
|
const goal = plugin.description || '';
|
|
710
566
|
|
|
711
|
-
// 优先使用 SubAgentConfigManager 获取详细信息
|
|
712
567
|
const config = this._framework._subAgentConfigManager?.get(name);
|
|
713
568
|
if (config) {
|
|
714
569
|
const agentDesc = config.getDescription();
|
|
@@ -719,12 +574,10 @@ class SubAgentManagerPlugin extends Plugin {
|
|
|
719
574
|
}
|
|
720
575
|
lines.push(`- **${name}**:${info}`);
|
|
721
576
|
} else {
|
|
722
|
-
// 回退到旧逻辑
|
|
723
577
|
lines.push(`- **${name}**:${role || goal || '子代理'}`);
|
|
724
578
|
}
|
|
725
579
|
}
|
|
726
580
|
|
|
727
|
-
// 通用规则
|
|
728
581
|
lines.push('');
|
|
729
582
|
lines.push('### 子 Agent 调用规则');
|
|
730
583
|
lines.push('');
|
|
@@ -738,16 +591,10 @@ class SubAgentManagerPlugin extends Plugin {
|
|
|
738
591
|
return lines.join('\n');
|
|
739
592
|
}
|
|
740
593
|
|
|
741
|
-
/**
|
|
742
|
-
* 获取所有 subAgent 的基本信息列表
|
|
743
|
-
*/
|
|
744
594
|
getAllSubAgents() {
|
|
745
595
|
return Array.from(this._subAgents.values());
|
|
746
596
|
}
|
|
747
597
|
|
|
748
|
-
/**
|
|
749
|
-
* 解析类似 YAML 的配置
|
|
750
|
-
*/
|
|
751
598
|
_parseYamlLike(content) {
|
|
752
599
|
const result = {}
|
|
753
600
|
const lines = content.split('\n')
|
|
@@ -758,7 +605,6 @@ class SubAgentManagerPlugin extends Plugin {
|
|
|
758
605
|
const key = match[1]
|
|
759
606
|
let value = match[2].trim()
|
|
760
607
|
|
|
761
|
-
// 处理数组格式 [a, b, c] 或 [a b c]
|
|
762
608
|
if (value.startsWith('[') && value.endsWith(']')) {
|
|
763
609
|
value = value.slice(1, -1).split(/[,\s]+/).filter(Boolean)
|
|
764
610
|
}
|
|
@@ -770,30 +616,23 @@ class SubAgentManagerPlugin extends Plugin {
|
|
|
770
616
|
return result
|
|
771
617
|
}
|
|
772
618
|
|
|
773
|
-
/**
|
|
774
|
-
* 获取子Agent
|
|
775
|
-
*/
|
|
776
619
|
getSubAgent(name) {
|
|
777
620
|
const plugin = this._subAgents.get(name)
|
|
778
621
|
return plugin ? plugin.getAgent() : null
|
|
779
622
|
}
|
|
780
623
|
|
|
781
624
|
reload(framework) {
|
|
782
|
-
// 销毁旧的子Agent
|
|
783
625
|
for (const plugin of this._subAgents.values()) {
|
|
784
626
|
plugin.uninstall(framework)
|
|
785
627
|
}
|
|
786
628
|
this._subAgents.clear()
|
|
787
629
|
|
|
788
|
-
// 清空从目录加载的配置,重新加载
|
|
789
630
|
this.agents = this.agents.filter(a => !a._fromDir)
|
|
790
631
|
|
|
791
|
-
// 刷新 SubAgentConfigManager(如果存在)
|
|
792
632
|
if (framework._subAgentConfigManager) {
|
|
793
633
|
framework._subAgentConfigManager.refresh()
|
|
794
634
|
}
|
|
795
635
|
|
|
796
|
-
// 重新创建
|
|
797
636
|
this.start(framework)
|
|
798
637
|
}
|
|
799
638
|
|
|
@@ -809,4 +648,4 @@ class SubAgentManagerPlugin extends Plugin {
|
|
|
809
648
|
module.exports = {
|
|
810
649
|
SubAgentManagerPlugin,
|
|
811
650
|
SubAgentPlugin
|
|
812
|
-
}
|
|
651
|
+
}
|