foliko 1.0.73 → 1.0.75
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agent/.shared/ui-ux-pro-max/data/charts.csv +26 -0
- package/.agent/.shared/ui-ux-pro-max/data/colors.csv +97 -0
- package/.agent/.shared/ui-ux-pro-max/data/icons.csv +101 -0
- package/.agent/.shared/ui-ux-pro-max/data/landing.csv +31 -0
- package/.agent/.shared/ui-ux-pro-max/data/products.csv +97 -0
- package/.agent/.shared/ui-ux-pro-max/data/prompts.csv +24 -0
- package/.agent/.shared/ui-ux-pro-max/data/react-performance.csv +45 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/react.csv +54 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/vue.csv +50 -0
- package/.agent/.shared/ui-ux-pro-max/data/styles.csv +59 -0
- package/.agent/.shared/ui-ux-pro-max/data/typography.csv +58 -0
- package/.agent/.shared/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
- package/.agent/.shared/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
- package/.agent/.shared/ui-ux-pro-max/data/web-interface.csv +31 -0
- package/.agent/.shared/ui-ux-pro-max/scripts/__pycache__/core.cpython-313.pyc +0 -0
- package/.agent/.shared/ui-ux-pro-max/scripts/__pycache__/design_system.cpython-313.pyc +0 -0
- package/.agent/.shared/ui-ux-pro-max/scripts/core.py +258 -0
- package/.agent/.shared/ui-ux-pro-max/scripts/design_system.py +1067 -0
- package/.agent/.shared/ui-ux-pro-max/scripts/search.py +106 -0
- package/.agent/ARCHITECTURE.md +288 -0
- package/.agent/agents/ambient-agent.md +57 -0
- package/.agent/agents/debugger.md +55 -0
- package/.agent/agents/email-assistant.md +49 -0
- package/.agent/agents/file-manager.md +42 -0
- package/.agent/agents/python-developer.md +60 -0
- package/.agent/agents/scheduler.md +59 -0
- package/.agent/agents/web-developer.md +45 -0
- package/.agent/data/default.json +29 -0
- package/.agent/data/plugins-state.json +255 -0
- package/.agent/mcp_config.json +4 -0
- package/.agent/mcp_config_updated.json +12 -0
- package/.agent/plugins.json +5 -0
- package/.agent/rules/GEMINI.md +273 -0
- package/.agent/rules/allow-rule.md +77 -0
- package/.agent/rules/log-rule.md +83 -0
- package/.agent/rules/security-rule.md +93 -0
- package/.agent/scripts/auto_preview.py +148 -0
- package/.agent/scripts/checklist.py +217 -0
- package/.agent/scripts/session_manager.py +120 -0
- package/.agent/scripts/verify_all.py +327 -0
- package/.agent/skills/api-patterns/SKILL.md +81 -0
- package/.agent/skills/api-patterns/api-style.md +42 -0
- package/.agent/skills/api-patterns/auth.md +24 -0
- package/.agent/skills/api-patterns/documentation.md +26 -0
- package/.agent/skills/api-patterns/graphql.md +41 -0
- package/.agent/skills/api-patterns/rate-limiting.md +31 -0
- package/.agent/skills/api-patterns/response.md +37 -0
- package/.agent/skills/api-patterns/rest.md +40 -0
- package/.agent/skills/api-patterns/scripts/api_validator.py +211 -0
- package/.agent/skills/api-patterns/security-testing.md +122 -0
- package/.agent/skills/api-patterns/trpc.md +41 -0
- package/.agent/skills/api-patterns/versioning.md +22 -0
- package/.agent/skills/app-builder/SKILL.md +75 -0
- package/.agent/skills/app-builder/agent-coordination.md +71 -0
- package/.agent/skills/app-builder/feature-building.md +53 -0
- package/.agent/skills/app-builder/project-detection.md +34 -0
- package/.agent/skills/app-builder/scaffolding.md +118 -0
- package/.agent/skills/app-builder/tech-stack.md +40 -0
- package/.agent/skills/app-builder/templates/SKILL.md +39 -0
- package/.agent/skills/app-builder/templates/astro-static/TEMPLATE.md +76 -0
- package/.agent/skills/app-builder/templates/chrome-extension/TEMPLATE.md +92 -0
- package/.agent/skills/app-builder/templates/cli-tool/TEMPLATE.md +88 -0
- package/.agent/skills/app-builder/templates/electron-desktop/TEMPLATE.md +88 -0
- package/.agent/skills/app-builder/templates/express-api/TEMPLATE.md +83 -0
- package/.agent/skills/app-builder/templates/flutter-app/TEMPLATE.md +90 -0
- package/.agent/skills/app-builder/templates/monorepo-turborepo/TEMPLATE.md +90 -0
- package/.agent/skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md +122 -0
- package/.agent/skills/app-builder/templates/nextjs-saas/TEMPLATE.md +122 -0
- package/.agent/skills/app-builder/templates/nextjs-static/TEMPLATE.md +169 -0
- package/.agent/skills/app-builder/templates/nuxt-app/TEMPLATE.md +134 -0
- package/.agent/skills/app-builder/templates/python-fastapi/TEMPLATE.md +83 -0
- package/.agent/skills/app-builder/templates/react-native-app/TEMPLATE.md +119 -0
- package/.agent/skills/architecture/SKILL.md +55 -0
- package/.agent/skills/architecture/context-discovery.md +43 -0
- package/.agent/skills/architecture/examples.md +94 -0
- package/.agent/skills/architecture/pattern-selection.md +68 -0
- package/.agent/skills/architecture/patterns-reference.md +50 -0
- package/.agent/skills/architecture/trade-off-analysis.md +77 -0
- package/.agent/skills/clean-code/SKILL.md +201 -0
- package/.agent/skills/doc.md +177 -0
- package/.agent/skills/frontend-design/SKILL.md +418 -0
- package/.agent/skills/frontend-design/animation-guide.md +331 -0
- package/.agent/skills/frontend-design/color-system.md +311 -0
- package/.agent/skills/frontend-design/decision-trees.md +418 -0
- package/.agent/skills/frontend-design/motion-graphics.md +306 -0
- package/.agent/skills/frontend-design/scripts/accessibility_checker.py +183 -0
- package/.agent/skills/frontend-design/scripts/ux_audit.py +722 -0
- package/.agent/skills/frontend-design/typography-system.md +345 -0
- package/.agent/skills/frontend-design/ux-psychology.md +1116 -0
- package/.agent/skills/frontend-design/visual-effects.md +383 -0
- package/.agent/skills/i18n-localization/SKILL.md +154 -0
- package/.agent/skills/i18n-localization/scripts/i18n_checker.py +241 -0
- package/.agent/skills/mcp-builder/SKILL.md +176 -0
- package/.agent/skills/web-design-guidelines/SKILL.md +57 -0
- package/.agent/workflows/brainstorm.md +113 -0
- package/.agent/workflows/create.md +59 -0
- package/.agent/workflows/debug.md +103 -0
- package/.agent/workflows/deploy.md +176 -0
- package/.agent/workflows/enhance.md +63 -0
- package/.agent/workflows/orchestrate.md +237 -0
- package/.agent/workflows/plan.md +89 -0
- package/.agent/workflows/preview.md +81 -0
- package/.agent/workflows/simple-test.md +42 -0
- package/.agent/workflows/status.md +86 -0
- package/.agent/workflows/structured-orchestrate.md +180 -0
- package/.agent/workflows/test.md +144 -0
- package/.agent/workflows/ui-ux-pro-max.md +296 -0
- package/.claude/settings.local.json +157 -149
- package/.editorconfig +56 -0
- package/.husky/pre-commit +4 -0
- package/.lintstagedrc +7 -0
- package/.prettierignore +29 -0
- package/.prettierrc +11 -0
- package/CLAUDE.md +2 -0
- package/README.md +64 -55
- package/SPEC.md +102 -61
- package/cli/bin/foliko.js +4 -4
- package/cli/src/commands/chat.js +53 -51
- package/cli/src/commands/list.js +40 -37
- package/cli/src/index.js +18 -18
- package/cli/src/ui/chat-ui.js +78 -76
- package/cli/src/utils/ansi.js +15 -15
- package/cli/src/utils/markdown.js +112 -116
- package/docker-compose.yml +1 -1
- package/docs/ai-sdk-optimization.md +655 -636
- package/docs/features.md +80 -80
- package/docs/quick-reference.md +49 -46
- package/docs/user-manual.md +411 -380
- package/examples/ambient-example.js +95 -97
- package/examples/basic.js +115 -110
- package/examples/bootstrap.js +52 -43
- package/examples/mcp-example.js +56 -53
- package/examples/skill-example.js +49 -49
- package/examples/test-chat.js +60 -58
- package/examples/test-mcp.js +49 -43
- package/examples/test-reload.js +38 -40
- package/examples/test-telegram.js +3 -3
- package/examples/test-tg-bot.js +7 -4
- package/examples/test-tg-simple.js +4 -3
- package/examples/test-tg.js +3 -3
- package/examples/test-think.js +13 -7
- package/examples/test-web-plugin.js +61 -56
- package/examples/test-weixin-feishu.js +40 -37
- package/examples/workflow.js +49 -49
- package/foliko-1.0.75.tgz +0 -0
- package/package.json +37 -3
- package/plugins/ai-plugin.js +7 -5
- package/plugins/ambient-agent/EventWatcher.js +113 -0
- package/plugins/ambient-agent/ExplorerLoop.js +640 -0
- package/plugins/ambient-agent/GoalManager.js +197 -0
- package/plugins/ambient-agent/Reflector.js +95 -0
- package/plugins/ambient-agent/StateStore.js +90 -0
- package/plugins/ambient-agent/constants.js +101 -0
- package/plugins/ambient-agent/index.js +579 -0
- package/plugins/default-plugins.js +62 -49
- package/plugins/email/constants.js +64 -0
- package/plugins/email/handlers.js +461 -0
- package/plugins/email/index.js +278 -0
- package/plugins/email/monitor.js +269 -0
- package/plugins/email/parser.js +138 -0
- package/plugins/email/reply.js +151 -0
- package/plugins/email/utils.js +124 -0
- package/plugins/feishu-plugin.js +23 -19
- package/plugins/file-system-plugin.js +469 -120
- package/plugins/install-plugin.js +6 -4
- package/plugins/python-executor-plugin.js +3 -1
- package/plugins/python-plugin-loader.js +10 -8
- package/plugins/rules-plugin.js +5 -3
- package/plugins/scheduler-plugin.js +18 -16
- package/plugins/session-plugin.js +3 -1
- package/plugins/storage-plugin.js +5 -3
- package/plugins/subagent-plugin.js +152 -92
- package/plugins/telegram-plugin.js +26 -19
- package/plugins/think-plugin.js +4 -2
- package/plugins/tools-plugin.js +3 -1
- package/plugins/web-plugin.js +15 -13
- package/plugins/weixin-plugin.js +43 -36
- package/reports/system-health-report-20260401.md +79 -0
- package/skills/ambient-agent/SKILL.md +49 -39
- package/skills/foliko-dev/AGENTS.md +64 -61
- package/skills/foliko-dev/SKILL.md +125 -119
- package/skills/mcp-usage/SKILL.md +19 -17
- package/skills/python-plugin-dev/SKILL.md +16 -15
- package/skills/skill-guide/SKILL.md +12 -12
- package/skills/subagent-guide/SKILL.md +237 -0
- package/skills/workflow-guide/SKILL.md +90 -45
- package/skills/workflow-troubleshooting/DEBUGGING.md +36 -21
- package/skills/workflow-troubleshooting/SKILL.md +156 -79
- package/src/capabilities/index.js +4 -4
- package/src/capabilities/skill-manager.js +211 -197
- package/src/capabilities/workflow-engine.js +461 -547
- package/src/core/agent-chat.js +426 -279
- package/src/core/agent.js +453 -248
- package/src/core/framework.js +183 -149
- package/src/core/index.js +8 -8
- package/src/core/plugin-base.js +52 -52
- package/src/core/plugin-manager.js +377 -281
- package/src/core/provider.js +35 -32
- package/src/core/sub-agent-config.js +264 -0
- package/src/core/system-prompt-builder.js +120 -0
- package/src/core/tool-registry.js +416 -33
- package/src/core/tool-router.js +149 -68
- package/src/executors/executor-base.js +58 -58
- package/src/executors/mcp-executor.js +269 -257
- package/src/index.js +5 -17
- package/src/utils/circuit-breaker.js +301 -0
- package/src/utils/error-boundary.js +363 -0
- package/src/utils/error.js +374 -0
- package/src/utils/event-emitter.js +20 -20
- package/src/utils/id.js +133 -0
- package/src/utils/index.js +217 -3
- package/src/utils/logger.js +181 -0
- package/src/utils/plugin-helpers.js +90 -0
- package/src/utils/retry.js +122 -0
- package/src/utils/sandbox.js +292 -0
- package/test/tool-registry-validation.test.js +218 -0
- package/test_report.md +70 -0
- package/website/docs/api.html +169 -107
- package/website/docs/configuration.html +296 -144
- package/website/docs/plugin-development.html +154 -85
- package/website/docs/project-structure.html +110 -109
- package/website/docs/skill-development.html +117 -61
- package/website/index.html +209 -205
- package/website/script.js +20 -17
- package/website/styles.css +1 -1
- package/plugins/ambient-agent-plugin.js +0 -1565
- package/plugins/email.js +0 -1142
package/src/core/agent.js
CHANGED
|
@@ -3,9 +3,10 @@
|
|
|
3
3
|
* 负责对话和推理
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
const { EventEmitter } = require('../utils/event-emitter')
|
|
7
|
-
const { AgentChatHandler } = require('./agent-chat')
|
|
8
|
-
const
|
|
6
|
+
const { EventEmitter } = require('../utils/event-emitter');
|
|
7
|
+
const { AgentChatHandler } = require('./agent-chat');
|
|
8
|
+
const { SystemPromptBuilder } = require('./system-prompt-builder');
|
|
9
|
+
const os = require('os');
|
|
9
10
|
|
|
10
11
|
class Agent extends EventEmitter {
|
|
11
12
|
/**
|
|
@@ -18,44 +19,99 @@ class Agent extends EventEmitter {
|
|
|
18
19
|
* @param {boolean} [config.enableToolRouting=true] - 是否启用工具路由
|
|
19
20
|
*/
|
|
20
21
|
constructor(framework, config = {}) {
|
|
21
|
-
super()
|
|
22
|
-
|
|
23
|
-
this.framework = framework
|
|
24
|
-
this.config = config
|
|
25
|
-
|
|
26
|
-
this.name = config.name || 'Agent'
|
|
27
|
-
this.model = config.model || 'deepseek-chat'
|
|
28
|
-
this.apiKey = config.apiKey
|
|
29
|
-
this.baseURL = config.baseURL
|
|
30
|
-
this.provider = config.provider || 'deepseek'
|
|
31
|
-
this.providerOptions = config.providerOptions || {}
|
|
32
|
-
this.providerOptions.maxOutputTokens=8192
|
|
22
|
+
super();
|
|
23
|
+
|
|
24
|
+
this.framework = framework;
|
|
25
|
+
this.config = config;
|
|
26
|
+
|
|
27
|
+
this.name = config.name || 'Agent';
|
|
28
|
+
this.model = config.model || 'deepseek-chat';
|
|
29
|
+
this.apiKey = config.apiKey;
|
|
30
|
+
this.baseURL = config.baseURL;
|
|
31
|
+
this.provider = config.provider || 'deepseek';
|
|
32
|
+
this.providerOptions = config.providerOptions || {};
|
|
33
|
+
this.providerOptions.maxOutputTokens = 8192;
|
|
34
|
+
this.providerOptions.temperature = 0.3; // 降低 temperature 减少生成错误 JSON 的概率
|
|
33
35
|
// 原始 system prompt
|
|
34
|
-
this._originalPrompt =
|
|
36
|
+
this._originalPrompt =
|
|
37
|
+
config.systemPrompt ||
|
|
38
|
+
'你是一个智能助手。当用户提出问题或任务时,你会主动分析需求,选择合适的工具来获取信息或执行操作。你善于将复杂任务拆解为多个步骤,通过工具协作完成。';
|
|
35
39
|
|
|
36
40
|
// 共享提示模板
|
|
37
|
-
this._sharedPrompt = config.sharedPrompt || ''
|
|
41
|
+
this._sharedPrompt = config.sharedPrompt || '';
|
|
38
42
|
|
|
39
43
|
// 元数据
|
|
40
|
-
const metadata = config.metadata || {}
|
|
41
|
-
this._metadata = new Map(Object.entries(metadata))
|
|
44
|
+
const metadata = config.metadata || {};
|
|
45
|
+
this._metadata = new Map(Object.entries(metadata));
|
|
42
46
|
|
|
43
|
-
this._chatHandler = null
|
|
44
|
-
this._tools = new Map()
|
|
45
|
-
this._status = 'idle'
|
|
47
|
+
this._chatHandler = null;
|
|
48
|
+
this._tools = new Map();
|
|
49
|
+
this._status = 'idle';
|
|
46
50
|
|
|
47
51
|
// 子Agent管理
|
|
48
|
-
this._subAgents = new Map()
|
|
52
|
+
this._subAgents = new Map();
|
|
49
53
|
|
|
50
54
|
// 消息队列(用于 pushMessage)
|
|
51
|
-
this._messageQueue = []
|
|
52
|
-
this._isProcessingQueue = false
|
|
55
|
+
this._messageQueue = [];
|
|
56
|
+
this._isProcessingQueue = false;
|
|
57
|
+
|
|
58
|
+
// System prompt 构建器
|
|
59
|
+
this._systemPromptBuilder = new SystemPromptBuilder();
|
|
60
|
+
this._registerDefaultPromptParts();
|
|
53
61
|
|
|
54
62
|
// 处理后的 system prompt (带上下文)
|
|
55
|
-
this.systemPrompt = this._buildSystemPrompt()
|
|
63
|
+
this.systemPrompt = this._buildSystemPrompt();
|
|
56
64
|
|
|
57
65
|
// 初始化聊天处理器
|
|
58
|
-
this._initChatHandler()
|
|
66
|
+
this._initChatHandler();
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* 注册默认的系统提示词部分
|
|
71
|
+
* @private
|
|
72
|
+
*/
|
|
73
|
+
_registerDefaultPromptParts() {
|
|
74
|
+
// 1. 原始 system prompt (优先级 100)
|
|
75
|
+
this._systemPromptBuilder.register('original-prompt', 100, () => this._originalPrompt);
|
|
76
|
+
|
|
77
|
+
// 2. 共享提示模板 (优先级 200)
|
|
78
|
+
this._systemPromptBuilder.register('shared-prompt', 200, () => {
|
|
79
|
+
if (this._sharedPrompt) {
|
|
80
|
+
return this._replacePlaceholders(this._sharedPrompt);
|
|
81
|
+
}
|
|
82
|
+
return null;
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
// 3. 元数据 (优先级 300)
|
|
86
|
+
this._systemPromptBuilder.register('metadata', 300, () => {
|
|
87
|
+
if (this._metadata.size === 0) {
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
const metaParts = ['【元数据】'];
|
|
91
|
+
for (const [key, value] of this._metadata) {
|
|
92
|
+
if (typeof value === 'object') {
|
|
93
|
+
metaParts.push(`- ${key}: ${JSON.stringify(value)}`);
|
|
94
|
+
} else {
|
|
95
|
+
metaParts.push(`- ${key}: ${value}`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return metaParts.join('\n');
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
// 4. 工具列表 (优先级 400)
|
|
102
|
+
this._systemPromptBuilder.register('tools', 400, () => this._buildToolsDescription());
|
|
103
|
+
|
|
104
|
+
// 5. 技能列表 (优先级 500)
|
|
105
|
+
this._systemPromptBuilder.register('skills', 500, () => this._buildSkillsDescription());
|
|
106
|
+
|
|
107
|
+
// 6. 子Agent列表 (优先级 600)
|
|
108
|
+
this._systemPromptBuilder.register('subagents', 600, () => this._buildSubAgentsDescription());
|
|
109
|
+
|
|
110
|
+
// 7. 系统能力 (优先级 700)
|
|
111
|
+
this._systemPromptBuilder.register('capabilities', 700, () => this._buildCapabilitiesDescription());
|
|
112
|
+
|
|
113
|
+
// 8. 工具调用核心规则 (优先级 1000)
|
|
114
|
+
this._systemPromptBuilder.register('tool-core-rules', 1000, () => this._getToolCoreRules());
|
|
59
115
|
}
|
|
60
116
|
|
|
61
117
|
/**
|
|
@@ -64,26 +120,26 @@ class Agent extends EventEmitter {
|
|
|
64
120
|
_getMetadataValue(key) {
|
|
65
121
|
// 优先从 metadata 获取
|
|
66
122
|
if (this._metadata.has(key)) {
|
|
67
|
-
return this._metadata.get(key)
|
|
123
|
+
return this._metadata.get(key);
|
|
68
124
|
}
|
|
69
125
|
|
|
70
126
|
// 内置变量
|
|
71
127
|
switch (key) {
|
|
72
128
|
case 'WORK_DIR':
|
|
73
129
|
case 'CWD':
|
|
74
|
-
return process.cwd()
|
|
130
|
+
return process.cwd();
|
|
75
131
|
case 'HOME_DIR':
|
|
76
|
-
return os.homedir()
|
|
132
|
+
return os.homedir();
|
|
77
133
|
case 'HOST_NAME':
|
|
78
|
-
return os.hostname()
|
|
134
|
+
return os.hostname();
|
|
79
135
|
case 'PLATFORM':
|
|
80
|
-
return process.platform
|
|
136
|
+
return process.platform;
|
|
81
137
|
case 'TIME':
|
|
82
|
-
return new Date().toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' })
|
|
138
|
+
return new Date().toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' });
|
|
83
139
|
case 'DATE':
|
|
84
|
-
return new Date().toISOString().split('T')[0]
|
|
140
|
+
return new Date().toISOString().split('T')[0];
|
|
85
141
|
default:
|
|
86
|
-
return `{{${key}}}
|
|
142
|
+
return `{{${key}}}`;
|
|
87
143
|
}
|
|
88
144
|
}
|
|
89
145
|
|
|
@@ -92,8 +148,8 @@ class Agent extends EventEmitter {
|
|
|
92
148
|
*/
|
|
93
149
|
_replacePlaceholders(template) {
|
|
94
150
|
return template.replace(/\{\{(\w+)\}\}/g, (match, key) => {
|
|
95
|
-
return this._getMetadataValue(key)
|
|
96
|
-
})
|
|
151
|
+
return this._getMetadataValue(key);
|
|
152
|
+
});
|
|
97
153
|
}
|
|
98
154
|
|
|
99
155
|
/**
|
|
@@ -101,155 +157,295 @@ class Agent extends EventEmitter {
|
|
|
101
157
|
*/
|
|
102
158
|
_buildToolsDescription() {
|
|
103
159
|
if (this._tools.size === 0) {
|
|
104
|
-
return ''
|
|
160
|
+
return '';
|
|
105
161
|
}
|
|
106
162
|
|
|
107
|
-
|
|
163
|
+
// 需要排除的子Agent相关工具(它们通过专门的子Agent部分提供)
|
|
164
|
+
// const excludedTools = new Set(['subagent_call', 'subagent_list', 'subagent_reload']);
|
|
165
|
+
|
|
166
|
+
let desc = '【可用工具】\n';
|
|
108
167
|
for (const [name, tool] of this._tools) {
|
|
109
168
|
// 跳过没有描述的工具(对LLM无帮助)
|
|
110
|
-
if (!tool.description) continue
|
|
111
|
-
|
|
169
|
+
if (!tool.description) continue;
|
|
170
|
+
// // 跳过子Agent相关工具(通过专门的子Agent部分提供)
|
|
171
|
+
// if (excludedTools.has(name)) continue;
|
|
172
|
+
// // 跳过子Agent委托工具(通过专门的子Agent部分提供)
|
|
173
|
+
// if (this._subAgents.has(name)) continue;
|
|
174
|
+
desc += `- ${name}: ${tool.description}\n`;
|
|
112
175
|
}
|
|
113
|
-
return desc.trim()
|
|
176
|
+
return desc.trim();
|
|
114
177
|
}
|
|
115
178
|
|
|
116
179
|
/**
|
|
117
180
|
* 构建技能描述
|
|
118
181
|
*/
|
|
119
182
|
_buildSkillsDescription() {
|
|
120
|
-
const skillManager = this.framework.pluginManager.get('skill-manager')
|
|
183
|
+
const skillManager = this.framework.pluginManager.get('skill-manager');
|
|
121
184
|
if (!skillManager) {
|
|
122
|
-
return ''
|
|
185
|
+
return '';
|
|
123
186
|
}
|
|
124
187
|
|
|
125
|
-
const skills = skillManager.getAllSkills()
|
|
188
|
+
const skills = skillManager.getAllSkills();
|
|
126
189
|
if (!skills || skills.length === 0) {
|
|
127
|
-
return ''
|
|
190
|
+
return '';
|
|
128
191
|
}
|
|
129
192
|
|
|
130
|
-
let desc = '【可用技能】\n'
|
|
193
|
+
let desc = '【可用技能】\n';
|
|
131
194
|
for (const skill of skills) {
|
|
132
|
-
const name = skill.metadata?.name || skill.name || 'unknown'
|
|
133
|
-
const descText = skill.metadata?.description || ''
|
|
134
|
-
desc += `- ${name}: ${descText}\n
|
|
195
|
+
const name = skill.metadata?.name || skill.name || 'unknown';
|
|
196
|
+
const descText = skill.metadata?.description || '';
|
|
197
|
+
desc += `- ${name}: ${descText}\n`;
|
|
135
198
|
}
|
|
136
|
-
desc +=
|
|
137
|
-
|
|
199
|
+
desc +=
|
|
200
|
+
'\n重要:当需要开发插件、执行专业任务时,必须先使用 loadSkill 工具加载对应技能,获取专业指导。';
|
|
201
|
+
return desc.trim();
|
|
138
202
|
}
|
|
139
203
|
|
|
140
204
|
/**
|
|
141
205
|
* 构建系统能力描述
|
|
142
206
|
*/
|
|
143
207
|
_buildCapabilitiesDescription() {
|
|
144
|
-
const plugins = this.framework.pluginManager.getAll()
|
|
208
|
+
const plugins = this.framework.pluginManager.getAll();
|
|
145
209
|
if (!plugins || plugins.length === 0) {
|
|
146
|
-
return ''
|
|
210
|
+
return '';
|
|
147
211
|
}
|
|
148
212
|
|
|
149
213
|
// 过滤出有描述的关键插件(排除内部插件)
|
|
150
|
-
const keyPlugins = plugins.filter(p => {
|
|
151
|
-
const name = p.name
|
|
214
|
+
const keyPlugins = plugins.filter((p) => {
|
|
215
|
+
const name = p.name;
|
|
152
216
|
// 排除默认配置插件和内部插件
|
|
153
|
-
return name !== 'defaults' && name !== 'agent'
|
|
154
|
-
})
|
|
217
|
+
return name !== 'defaults' && name !== 'agent';
|
|
218
|
+
});
|
|
155
219
|
|
|
156
220
|
if (keyPlugins.length === 0) {
|
|
157
|
-
return ''
|
|
221
|
+
return '';
|
|
158
222
|
}
|
|
159
223
|
|
|
160
|
-
let desc = '【系统能力】\n'
|
|
224
|
+
let desc = '【系统能力】\n';
|
|
161
225
|
for (const plugin of keyPlugins) {
|
|
162
|
-
const name = plugin.instance?.name || plugin.name || 'unknown'
|
|
163
|
-
const description = plugin.instance?.description || '无描述'
|
|
164
|
-
desc += `- ${name}: ${description}\n
|
|
226
|
+
const name = plugin.instance?.name || plugin.name || 'unknown';
|
|
227
|
+
const description = plugin.instance?.description || '无描述';
|
|
228
|
+
desc += `- ${name}: ${description}\n`;
|
|
165
229
|
}
|
|
166
230
|
|
|
167
|
-
return desc.trim()
|
|
231
|
+
return desc.trim();
|
|
168
232
|
}
|
|
169
233
|
|
|
170
234
|
/**
|
|
171
235
|
* 构建子Agent描述
|
|
236
|
+
* 动态从配置文件读取每个子Agent的专业领域
|
|
172
237
|
*/
|
|
173
238
|
_buildSubAgentsDescription() {
|
|
174
|
-
|
|
175
|
-
|
|
239
|
+
const subAgentManager = this.framework.pluginManager.get('subagent-manager');
|
|
240
|
+
if (!subAgentManager) {
|
|
241
|
+
return '';
|
|
242
|
+
}
|
|
243
|
+
const allSubAgents = subAgentManager.getAllSubAgents();
|
|
244
|
+
if (!allSubAgents || allSubAgents.length === 0) {
|
|
245
|
+
return '';
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
let desc = '【子 Agent 匹配表 - 优先使用】\n';
|
|
249
|
+
|
|
250
|
+
// 动态从配置文件读取每个子Agent的核心能力
|
|
251
|
+
for (const plugin of allSubAgents) {
|
|
252
|
+
const name = plugin.name;
|
|
253
|
+
const role = plugin.role;
|
|
254
|
+
const goal = plugin.description || '';
|
|
255
|
+
|
|
256
|
+
// 优先使用 SubAgentConfigManager 获取详细信息
|
|
257
|
+
const config = this.framework._subAgentConfigManager?.get(name);
|
|
258
|
+
if (config) {
|
|
259
|
+
const agentDesc = config.getDescription();
|
|
260
|
+
const skills = config.getSkills();
|
|
261
|
+
let info = agentDesc || role || goal || '子代理';
|
|
262
|
+
if (skills && skills.length > 0) {
|
|
263
|
+
info += ` (技能: ${skills.join(', ')})`;
|
|
264
|
+
}
|
|
265
|
+
desc += ` - ${name}: ${info}\n`;
|
|
266
|
+
} else {
|
|
267
|
+
// 回退到旧逻辑
|
|
268
|
+
desc += ` - ${name}: ${role || goal || '子代理'}\n`;
|
|
269
|
+
}
|
|
176
270
|
}
|
|
177
271
|
|
|
178
|
-
|
|
179
|
-
desc += '
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
desc += '2. 你需要对任务进行拆分,传递给对应的子Agent执行。\n'
|
|
184
|
-
desc += '3. 多个不同类型的任务必须分别委托给不同的子Agent,每个子Agent只处理自己专业领域的任务。\n'
|
|
185
|
-
desc += '\n【可委托的子 Agent】\n'
|
|
186
|
-
for (const [name, { role, goal }] of this._subAgents) {
|
|
187
|
-
desc += ` - ${name}: ${role || goal || '子代理'}\n`
|
|
188
|
-
}
|
|
189
|
-
desc += '\n使用 subagent_call 工具并指定 agentName 来委托任务给相应子Agent。'
|
|
272
|
+
// 通用规则
|
|
273
|
+
desc += '\n【子Agent匹配规则 - 必须遵守】\n';
|
|
274
|
+
desc += ' - 根据上述【子 Agent 匹配表】,将任务委托给最匹配的子Agent处理\n';
|
|
275
|
+
desc += ' - 使用 subagent_call 工具并指定 agentName 来委托任务\n';
|
|
276
|
+
desc += ' - 只有当没有匹配的子Agent时,才直接调用工具\n';
|
|
190
277
|
|
|
191
|
-
return desc.trim()
|
|
278
|
+
return desc.trim();
|
|
192
279
|
}
|
|
193
280
|
|
|
194
281
|
/**
|
|
195
|
-
*
|
|
282
|
+
* 从配置文件动态读取子Agent的核心能力
|
|
283
|
+
* 支持 .json 和 .md 格式
|
|
284
|
+
* @private
|
|
196
285
|
*/
|
|
197
|
-
|
|
198
|
-
|
|
286
|
+
_getSubAgentCapabilities(name) {
|
|
287
|
+
try {
|
|
288
|
+
const fs = require('fs');
|
|
289
|
+
const path = require('path');
|
|
290
|
+
const agentsDir = path.join(process.cwd(), '.agent', 'agents');
|
|
291
|
+
|
|
292
|
+
// 尝试多种文件格式
|
|
293
|
+
const possiblePaths = [
|
|
294
|
+
path.join(agentsDir, `${name}.md`),
|
|
295
|
+
path.join(agentsDir, `${name}.json`),
|
|
296
|
+
];
|
|
297
|
+
|
|
298
|
+
let filePath = null;
|
|
299
|
+
for (const p of possiblePaths) {
|
|
300
|
+
if (fs.existsSync(p)) {
|
|
301
|
+
filePath = p;
|
|
302
|
+
break;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
199
305
|
|
|
200
|
-
|
|
201
|
-
|
|
306
|
+
if (!filePath) {
|
|
307
|
+
return null;
|
|
308
|
+
}
|
|
202
309
|
|
|
203
|
-
|
|
204
|
-
if (this._sharedPrompt) {
|
|
205
|
-
const replaced = this._replacePlaceholders(this._sharedPrompt)
|
|
206
|
-
parts.push(replaced)
|
|
207
|
-
}
|
|
310
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
208
311
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
if (typeof value === 'object') {
|
|
214
|
-
metaParts.push(`- ${key}: ${JSON.stringify(value)}`)
|
|
215
|
-
} else {
|
|
216
|
-
metaParts.push(`- ${key}: ${value}`)
|
|
217
|
-
}
|
|
312
|
+
// .json 格式
|
|
313
|
+
if (filePath.endsWith('.json')) {
|
|
314
|
+
const config = JSON.parse(content);
|
|
315
|
+
return this._extractCapabilitiesFromConfig(config);
|
|
218
316
|
}
|
|
219
|
-
parts.push(metaParts.join('\n'))
|
|
220
|
-
}
|
|
221
317
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
318
|
+
// .md 格式(YAML front matter + markdown)
|
|
319
|
+
if (filePath.endsWith('.md')) {
|
|
320
|
+
return this._extractCapabilitiesFromMd(content);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
return null;
|
|
324
|
+
} catch (e) {
|
|
325
|
+
return null;
|
|
226
326
|
}
|
|
327
|
+
}
|
|
227
328
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
329
|
+
/**
|
|
330
|
+
* 从 JSON 配置中提取核心能力
|
|
331
|
+
*/
|
|
332
|
+
_extractCapabilitiesFromConfig(config) {
|
|
333
|
+
if (config.instructions) {
|
|
334
|
+
const match = config.instructions.match(/【核心能力】([\s\S]*?)(?=【|$)/);
|
|
335
|
+
if (match) {
|
|
336
|
+
const capabilities = match[1]
|
|
337
|
+
.split('\n')
|
|
338
|
+
.map((line) => line.replace(/^[·\-*]\s*/, '').trim())
|
|
339
|
+
.filter((line) => line && !line.startsWith('你是一个'))
|
|
340
|
+
.slice(0, 4)
|
|
341
|
+
.join('、');
|
|
342
|
+
return capabilities || config.description;
|
|
343
|
+
}
|
|
344
|
+
return config.description;
|
|
232
345
|
}
|
|
346
|
+
return config.description || null;
|
|
347
|
+
}
|
|
233
348
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
349
|
+
/**
|
|
350
|
+
* 从 .md 文件(YAML front matter)中提取核心能力
|
|
351
|
+
*/
|
|
352
|
+
_extractCapabilitiesFromMd(mdContent) {
|
|
353
|
+
// 解析 YAML front matter
|
|
354
|
+
const frontMatterMatch = mdContent.match(/^---\n([\s\S]*?)\n---/);
|
|
355
|
+
if (!frontMatterMatch) {
|
|
356
|
+
return null;
|
|
238
357
|
}
|
|
239
358
|
|
|
240
|
-
|
|
241
|
-
const
|
|
242
|
-
|
|
243
|
-
|
|
359
|
+
const frontMatter = frontMatterMatch[1];
|
|
360
|
+
const config = {};
|
|
361
|
+
|
|
362
|
+
// 简单解析 YAML front matter
|
|
363
|
+
for (const line of frontMatter.split('\n')) {
|
|
364
|
+
const colonIndex = line.indexOf(':');
|
|
365
|
+
if (colonIndex > 0) {
|
|
366
|
+
const key = line.substring(0, colonIndex).trim();
|
|
367
|
+
let value = line.substring(colonIndex + 1).trim();
|
|
368
|
+
// 移除可能的引号
|
|
369
|
+
if ((value.startsWith('"') && value.endsWith('"')) ||
|
|
370
|
+
(value.startsWith("'") && value.endsWith("'"))) {
|
|
371
|
+
value = value.slice(1, -1);
|
|
372
|
+
}
|
|
373
|
+
config[key] = value;
|
|
374
|
+
}
|
|
244
375
|
}
|
|
376
|
+
// 从 description 字段提取能力
|
|
377
|
+
if (config.description) {
|
|
378
|
+
const desc = config.description;
|
|
379
|
+
// 按逗号/顿号分隔
|
|
380
|
+
const parts = desc.split(/[,,、]/).map(s => s.trim());
|
|
381
|
+
// 取第一部分(通常是最核心的能力描述)
|
|
382
|
+
const firstPart = parts[0];
|
|
383
|
+
// 如果第一部分太长(说明是句子),取前50个字符
|
|
384
|
+
if (firstPart.length > 50) {
|
|
385
|
+
return firstPart.substring(0, 50).trim() + '...';
|
|
386
|
+
}
|
|
387
|
+
// 如果有多个部分,取前3个
|
|
388
|
+
if (parts.length > 1) {
|
|
389
|
+
return parts.slice(0, 3).join('、');
|
|
390
|
+
}
|
|
391
|
+
return firstPart;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
return null;
|
|
395
|
+
}
|
|
245
396
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
if (
|
|
249
|
-
|
|
397
|
+
_buildSystemPrompt() {
|
|
398
|
+
// 如果没变脏,返回缓存
|
|
399
|
+
if (!this._systemPromptDirty && this._systemPromptCache !== null) {
|
|
400
|
+
return this._systemPromptCache;
|
|
250
401
|
}
|
|
251
402
|
|
|
252
|
-
|
|
403
|
+
// 使用 builder 构建系统提示词
|
|
404
|
+
this._systemPromptCache = this._systemPromptBuilder.build();
|
|
405
|
+
this._systemPromptDirty = false;
|
|
406
|
+
return this._systemPromptCache;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* 使 system prompt 缓存失效
|
|
411
|
+
* @private
|
|
412
|
+
*/
|
|
413
|
+
_invalidateSystemPromptCache() {
|
|
414
|
+
this._systemPromptDirty = true;
|
|
415
|
+
// 同时使 builder 中所有部分失效
|
|
416
|
+
this._systemPromptBuilder.invalidateAll();
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
/**
|
|
420
|
+
* 注册自定义系统提示词部分(供插件使用)
|
|
421
|
+
* @param {string} name - 部分名称
|
|
422
|
+
* @param {number} priority - 优先级
|
|
423
|
+
* @param {Function} provider - 返回提示词内容的函数
|
|
424
|
+
*/
|
|
425
|
+
registerPromptPart(name, priority, provider) {
|
|
426
|
+
this._systemPromptBuilder.register(name, priority, provider);
|
|
427
|
+
this._invalidateSystemPromptCache();
|
|
428
|
+
return this;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* 注销系统提示词部分
|
|
433
|
+
* @param {string} name - 部分名称
|
|
434
|
+
*/
|
|
435
|
+
unregisterPromptPart(name) {
|
|
436
|
+
this._systemPromptBuilder.unregister(name);
|
|
437
|
+
this._invalidateSystemPromptCache();
|
|
438
|
+
return this;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
/**
|
|
442
|
+
* 使特定系统提示词部分失效
|
|
443
|
+
* @param {string} name - 部分名称
|
|
444
|
+
*/
|
|
445
|
+
invalidatePromptPart(name) {
|
|
446
|
+
this._systemPromptBuilder.invalidate(name);
|
|
447
|
+
this._systemPromptDirty = true;
|
|
448
|
+
return this;
|
|
253
449
|
}
|
|
254
450
|
|
|
255
451
|
/**
|
|
@@ -258,12 +454,13 @@ class Agent extends EventEmitter {
|
|
|
258
454
|
*/
|
|
259
455
|
_getToolCoreRules() {
|
|
260
456
|
return `【工具调用核心规则】
|
|
261
|
-
1.
|
|
262
|
-
2.
|
|
263
|
-
3.
|
|
264
|
-
4.
|
|
265
|
-
5.
|
|
266
|
-
6.
|
|
457
|
+
1. **子Agent优先**:任务匹配子Agent专业领域时,**必须优先使用** 使用 subagent_call 工具并指定 agentName 委托给对应子Agent处理,而不是直接调用工具。只有当没有匹配的子Agent时,才直接调用工具。
|
|
458
|
+
2. **必须先调用工具再回复**:当问题需要信息、操作或计算时,必须调用工具获取真实结果后才能回答。禁止在未调用工具的情况下直接给出答案。
|
|
459
|
+
3. **禁止编造数据**:不许捏造用户、订单、任务、文件、内容等任何数据。所有数据必须通过工具获取。
|
|
460
|
+
4. **工具优先**:可用工具列表会提供,格式为 toolName(toolArgs)。不确定用哪个工具时,优先调用可能相关的工具。
|
|
461
|
+
5. **结果导向**:调用工具后,基于返回结果回答,不要重复工具的内部实现细节。
|
|
462
|
+
6. **多步骤任务**:复杂任务拆解为多个工具调用,逐步完成,每步基于结果决定下一步。
|
|
463
|
+
|
|
267
464
|
|
|
268
465
|
【响应规范】
|
|
269
466
|
- 直接给出结论或结果,不说"我需要..."、"我建议..."等铺垫话术
|
|
@@ -273,16 +470,16 @@ class Agent extends EventEmitter {
|
|
|
273
470
|
【禁止事项】
|
|
274
471
|
- 不调用工具就直接回答
|
|
275
472
|
- 编造不存在的数据、文件、订单、用户等信息
|
|
276
|
-
-
|
|
473
|
+
- 回复含糊不清,让用户无法确定答案是否正确`;
|
|
277
474
|
}
|
|
278
475
|
|
|
279
476
|
/**
|
|
280
477
|
* 刷新上下文
|
|
281
478
|
*/
|
|
282
479
|
_refreshContext() {
|
|
283
|
-
this.systemPrompt = this._buildSystemPrompt()
|
|
480
|
+
this.systemPrompt = this._buildSystemPrompt();
|
|
284
481
|
if (this._chatHandler) {
|
|
285
|
-
this._chatHandler.setSystemPrompt(this.systemPrompt)
|
|
482
|
+
this._chatHandler.setSystemPrompt(this.systemPrompt);
|
|
286
483
|
}
|
|
287
484
|
}
|
|
288
485
|
|
|
@@ -291,10 +488,10 @@ class Agent extends EventEmitter {
|
|
|
291
488
|
* @private
|
|
292
489
|
*/
|
|
293
490
|
_initChatHandler() {
|
|
294
|
-
let aiClient = null
|
|
295
|
-
const aiPlugin = this.framework.pluginManager.get('ai')
|
|
491
|
+
let aiClient = null;
|
|
492
|
+
const aiPlugin = this.framework.pluginManager.get('ai');
|
|
296
493
|
if (aiPlugin) {
|
|
297
|
-
aiClient = aiPlugin.getAIClient()
|
|
494
|
+
aiClient = aiPlugin.getAIClient();
|
|
298
495
|
}
|
|
299
496
|
|
|
300
497
|
this._chatHandler = new AgentChatHandler(this, {
|
|
@@ -307,52 +504,53 @@ class Agent extends EventEmitter {
|
|
|
307
504
|
maxContextTokens: this.config.maxContextTokens,
|
|
308
505
|
compressionThreshold: this.config.compressionThreshold,
|
|
309
506
|
keepRecentMessages: this.config.keepRecentMessages,
|
|
310
|
-
enableSmartCompress: this.config.enableSmartCompress
|
|
311
|
-
})
|
|
507
|
+
enableSmartCompress: this.config.enableSmartCompress,
|
|
508
|
+
});
|
|
312
509
|
|
|
313
510
|
if (aiClient) {
|
|
314
|
-
this._chatHandler.setAIClient(aiClient)
|
|
511
|
+
this._chatHandler.setAIClient(aiClient);
|
|
315
512
|
}
|
|
316
513
|
|
|
317
514
|
// 转发事件
|
|
318
|
-
this._chatHandler.on('message', (msg) => this.emit('message', msg))
|
|
319
|
-
this._chatHandler.on('chunk', (chunk) => this.emit('chunk', chunk))
|
|
320
|
-
this._chatHandler.on('tool-call', (tool) => this.emit('tool-call', tool))
|
|
321
|
-
this._chatHandler.on('tool-result', (result) => this.emit('tool-result', result))
|
|
322
|
-
this._chatHandler.on('error', (err) => this.emit('error', err))
|
|
515
|
+
this._chatHandler.on('message', (msg) => this.emit('message', msg));
|
|
516
|
+
this._chatHandler.on('chunk', (chunk) => this.emit('chunk', chunk));
|
|
517
|
+
this._chatHandler.on('tool-call', (tool) => this.emit('tool-call', tool));
|
|
518
|
+
this._chatHandler.on('tool-result', (result) => this.emit('tool-result', result));
|
|
519
|
+
this._chatHandler.on('error', (err) => this.emit('error', err));
|
|
323
520
|
|
|
324
|
-
this._syncTools()
|
|
521
|
+
this._syncTools();
|
|
325
522
|
}
|
|
326
523
|
|
|
327
524
|
/**
|
|
328
525
|
* 设置系统提示
|
|
329
526
|
*/
|
|
330
527
|
setSystemPrompt(prompt) {
|
|
331
|
-
this._originalPrompt = prompt
|
|
332
|
-
this.systemPrompt = this._buildSystemPrompt()
|
|
528
|
+
this._originalPrompt = prompt;
|
|
529
|
+
this.systemPrompt = this._buildSystemPrompt();
|
|
333
530
|
if (this._chatHandler) {
|
|
334
|
-
this._chatHandler.setSystemPrompt(this.systemPrompt)
|
|
531
|
+
this._chatHandler.setSystemPrompt(this.systemPrompt);
|
|
335
532
|
}
|
|
336
|
-
return this
|
|
533
|
+
return this;
|
|
337
534
|
}
|
|
338
535
|
|
|
339
536
|
/**
|
|
340
537
|
* 注册工具到 Agent
|
|
341
538
|
*/
|
|
342
539
|
registerTool(tool) {
|
|
343
|
-
this._tools.set(tool.name, tool)
|
|
540
|
+
this._tools.set(tool.name, tool);
|
|
541
|
+
this._invalidateSystemPromptCache();
|
|
344
542
|
if (this._chatHandler) {
|
|
345
|
-
this._chatHandler.registerTool(tool)
|
|
543
|
+
this._chatHandler.registerTool(tool);
|
|
346
544
|
}
|
|
347
|
-
this._refreshContext()
|
|
348
|
-
return this
|
|
545
|
+
this._refreshContext();
|
|
546
|
+
return this;
|
|
349
547
|
}
|
|
350
548
|
|
|
351
549
|
/**
|
|
352
550
|
* 获取已注册工具
|
|
353
551
|
*/
|
|
354
552
|
getTools() {
|
|
355
|
-
return Array.from(this._tools.values())
|
|
553
|
+
return Array.from(this._tools.values());
|
|
356
554
|
}
|
|
357
555
|
|
|
358
556
|
/**
|
|
@@ -363,7 +561,7 @@ class Agent extends EventEmitter {
|
|
|
363
561
|
if (this.framework.toolRegistry.size() > 0) {
|
|
364
562
|
for (const tool of this.framework.getTools()) {
|
|
365
563
|
if (!this._tools.has(tool.name)) {
|
|
366
|
-
this.registerTool(tool)
|
|
564
|
+
this.registerTool(tool);
|
|
367
565
|
}
|
|
368
566
|
}
|
|
369
567
|
}
|
|
@@ -377,25 +575,27 @@ class Agent extends EventEmitter {
|
|
|
377
575
|
* @param {string} goal - 目标描述
|
|
378
576
|
*/
|
|
379
577
|
registerSubAgent(name, agent, role, goal) {
|
|
380
|
-
this._subAgents.set(name, { agent, role, goal })
|
|
381
|
-
this.
|
|
382
|
-
|
|
578
|
+
this._subAgents.set(name, { agent, role, goal });
|
|
579
|
+
this._invalidateSystemPromptCache();
|
|
580
|
+
this._refreshContext();
|
|
581
|
+
return this;
|
|
383
582
|
}
|
|
384
583
|
|
|
385
584
|
/**
|
|
386
585
|
* 注销子Agent
|
|
387
586
|
*/
|
|
388
587
|
unregisterSubAgent(name) {
|
|
389
|
-
this._subAgents.delete(name)
|
|
390
|
-
this.
|
|
391
|
-
|
|
588
|
+
this._subAgents.delete(name);
|
|
589
|
+
this._invalidateSystemPromptCache();
|
|
590
|
+
this._refreshContext();
|
|
591
|
+
return this;
|
|
392
592
|
}
|
|
393
593
|
|
|
394
594
|
/**
|
|
395
595
|
* 获取所有子Agent
|
|
396
596
|
*/
|
|
397
597
|
getSubAgents() {
|
|
398
|
-
return this._subAgents
|
|
598
|
+
return this._subAgents;
|
|
399
599
|
}
|
|
400
600
|
|
|
401
601
|
/**
|
|
@@ -403,22 +603,22 @@ class Agent extends EventEmitter {
|
|
|
403
603
|
*/
|
|
404
604
|
_getAndClearSchedulerNotifications() {
|
|
405
605
|
try {
|
|
406
|
-
const scheduler = this.framework.pluginManager.get('scheduler')
|
|
606
|
+
const scheduler = this.framework.pluginManager.get('scheduler');
|
|
407
607
|
if (scheduler && scheduler.instance && scheduler.instance.getPendingNotifications) {
|
|
408
|
-
const results = scheduler.instance.getPendingNotifications()
|
|
608
|
+
const results = scheduler.instance.getPendingNotifications();
|
|
409
609
|
if (results.length > 0) {
|
|
410
|
-
const notifications = results.slice(-5).reverse() // 最多5条,最新的在前
|
|
610
|
+
const notifications = results.slice(-5).reverse(); // 最多5条,最新的在前
|
|
411
611
|
// 清除已发送的通知
|
|
412
612
|
if (scheduler.instance.clearDeliveredNotifications) {
|
|
413
|
-
scheduler.instance.clearDeliveredNotifications(notifications.length)
|
|
613
|
+
scheduler.instance.clearDeliveredNotifications(notifications.length);
|
|
414
614
|
}
|
|
415
|
-
return notifications
|
|
615
|
+
return notifications;
|
|
416
616
|
}
|
|
417
617
|
}
|
|
418
618
|
} catch (err) {
|
|
419
619
|
// 忽略错误,避免影响主流程
|
|
420
620
|
}
|
|
421
|
-
return []
|
|
621
|
+
return [];
|
|
422
622
|
}
|
|
423
623
|
|
|
424
624
|
/**
|
|
@@ -426,38 +626,42 @@ class Agent extends EventEmitter {
|
|
|
426
626
|
*/
|
|
427
627
|
_getAndClearThinkNotifications() {
|
|
428
628
|
try {
|
|
429
|
-
const think = this.framework.pluginManager.get('think')
|
|
629
|
+
const think = this.framework.pluginManager.get('think');
|
|
430
630
|
if (think && think.instance && think.instance.getPendingThoughts) {
|
|
431
|
-
const thoughts = think.instance.getPendingThoughts()
|
|
631
|
+
const thoughts = think.instance.getPendingThoughts();
|
|
432
632
|
if (thoughts.length > 0) {
|
|
433
|
-
return thoughts.slice(-5).reverse() // 最多5条,最新的在前
|
|
633
|
+
return thoughts.slice(-5).reverse(); // 最多5条,最新的在前
|
|
434
634
|
}
|
|
435
635
|
}
|
|
436
636
|
} catch (err) {
|
|
437
637
|
// 忽略错误,避免影响主流程
|
|
438
638
|
}
|
|
439
|
-
return []
|
|
639
|
+
return [];
|
|
440
640
|
}
|
|
441
641
|
|
|
442
642
|
/**
|
|
443
643
|
* 获取所有待处理的系统通知(调度 + 思考)
|
|
444
644
|
*/
|
|
445
645
|
_getAllPendingNotifications() {
|
|
446
|
-
const notifications = []
|
|
646
|
+
const notifications = [];
|
|
447
647
|
|
|
448
648
|
// 调度通知
|
|
449
|
-
const schedulerNotifs = this._getAndClearSchedulerNotifications()
|
|
649
|
+
const schedulerNotifs = this._getAndClearSchedulerNotifications();
|
|
450
650
|
for (const n of schedulerNotifs) {
|
|
451
|
-
notifications.push(
|
|
651
|
+
notifications.push(
|
|
652
|
+
`【定时任务通知】\n任务: ${n.taskName || n.taskId}\n执行时间: ${n.executedAt}\n结果: ${n.result || n.action || '执行完成'}`
|
|
653
|
+
);
|
|
452
654
|
}
|
|
453
655
|
|
|
454
656
|
// 思考通知
|
|
455
|
-
const thinkNotifs = this._getAndClearThinkNotifications()
|
|
657
|
+
const thinkNotifs = this._getAndClearThinkNotifications();
|
|
456
658
|
for (const t of thinkNotifs) {
|
|
457
|
-
notifications.push(
|
|
659
|
+
notifications.push(
|
|
660
|
+
`【主动思考】\n模式: ${t.mode}\n主题: ${t.topic}\n结果: ${t.result || '思考完成'}`
|
|
661
|
+
);
|
|
458
662
|
}
|
|
459
663
|
|
|
460
|
-
return notifications
|
|
664
|
+
return notifications;
|
|
461
665
|
}
|
|
462
666
|
|
|
463
667
|
/**
|
|
@@ -465,42 +669,42 @@ class Agent extends EventEmitter {
|
|
|
465
669
|
*/
|
|
466
670
|
async chat(message, options = {}) {
|
|
467
671
|
if (this._status === 'busy') {
|
|
468
|
-
throw new Error('Agent is busy')
|
|
672
|
+
throw new Error('Agent is busy');
|
|
469
673
|
}
|
|
470
674
|
|
|
471
675
|
if (this._status === 'error') {
|
|
472
|
-
this._status = 'idle'
|
|
676
|
+
this._status = 'idle';
|
|
473
677
|
}
|
|
474
678
|
|
|
475
|
-
this._status = 'busy'
|
|
476
|
-
this.emit('status', { status: 'busy' })
|
|
679
|
+
this._status = 'busy';
|
|
680
|
+
this.emit('status', { status: 'busy' });
|
|
477
681
|
|
|
478
682
|
try {
|
|
479
683
|
// 检查是否有待处理的系统通知(调度 + 思考)
|
|
480
|
-
const notifications = this._getAllPendingNotifications()
|
|
481
|
-
let enhancedMessage = message
|
|
684
|
+
const notifications = this._getAllPendingNotifications();
|
|
685
|
+
let enhancedMessage = message;
|
|
482
686
|
if (notifications.length > 0) {
|
|
483
|
-
enhancedMessage = `【系统通知】\n${notifications.join('\n\n')}\n\n---\n用户消息: ${message}
|
|
687
|
+
enhancedMessage = `【系统通知】\n${notifications.join('\n\n')}\n\n---\n用户消息: ${message}`;
|
|
484
688
|
}
|
|
485
689
|
|
|
486
|
-
this._syncTools()
|
|
690
|
+
this._syncTools();
|
|
487
691
|
|
|
488
|
-
const result = await this._chatHandler.chat(enhancedMessage, options)
|
|
489
|
-
this._status = 'idle'
|
|
490
|
-
this.emit('status', { status: 'idle' })
|
|
692
|
+
const result = await this._chatHandler.chat(enhancedMessage, options);
|
|
693
|
+
this._status = 'idle';
|
|
694
|
+
this.emit('status', { status: 'idle' });
|
|
491
695
|
|
|
492
696
|
// 处理队列中的下一条消息
|
|
493
|
-
setImmediate(() => this._processQueue())
|
|
697
|
+
setImmediate(() => this._processQueue());
|
|
494
698
|
|
|
495
|
-
return result
|
|
699
|
+
return result;
|
|
496
700
|
} catch (err) {
|
|
497
|
-
this._status = 'error'
|
|
498
|
-
this.emit('status', { status: 'error', error: err.message })
|
|
701
|
+
this._status = 'error';
|
|
702
|
+
this.emit('status', { status: 'error', error: err.message });
|
|
499
703
|
|
|
500
704
|
// 发生错误时也要处理队列
|
|
501
|
-
setImmediate(() => this._processQueue())
|
|
705
|
+
setImmediate(() => this._processQueue());
|
|
502
706
|
|
|
503
|
-
throw err
|
|
707
|
+
throw err;
|
|
504
708
|
}
|
|
505
709
|
}
|
|
506
710
|
|
|
@@ -514,25 +718,25 @@ class Agent extends EventEmitter {
|
|
|
514
718
|
*/
|
|
515
719
|
async pushMessage(message, options = {}) {
|
|
516
720
|
// 自动从执行上下文获取 sessionId
|
|
517
|
-
const ctx = this.framework.getExecutionContext()
|
|
721
|
+
const ctx = this.framework.getExecutionContext();
|
|
518
722
|
if (ctx?.sessionId && !options.sessionId) {
|
|
519
|
-
options.sessionId = ctx.sessionId
|
|
723
|
+
options.sessionId = ctx.sessionId;
|
|
520
724
|
}
|
|
521
725
|
|
|
522
726
|
// 如果忙碌,进入队列等待
|
|
523
727
|
if (this._status === 'busy') {
|
|
524
|
-
const queuedItem = { message, options, resolve: null, reject: null }
|
|
728
|
+
const queuedItem = { message, options, resolve: null, reject: null };
|
|
525
729
|
const promise = new Promise((resolve, reject) => {
|
|
526
|
-
queuedItem.resolve = resolve
|
|
527
|
-
queuedItem.reject = reject
|
|
528
|
-
})
|
|
529
|
-
this._messageQueue.push(queuedItem)
|
|
530
|
-
|
|
531
|
-
return promise
|
|
730
|
+
queuedItem.resolve = resolve;
|
|
731
|
+
queuedItem.reject = reject;
|
|
732
|
+
});
|
|
733
|
+
this._messageQueue.push(queuedItem);
|
|
734
|
+
// Agent busy, message queued
|
|
735
|
+
return promise;
|
|
532
736
|
}
|
|
533
737
|
|
|
534
738
|
// 空闲则直接处理
|
|
535
|
-
return this.chat(message, options)
|
|
739
|
+
return this.chat(message, options);
|
|
536
740
|
}
|
|
537
741
|
|
|
538
742
|
/**
|
|
@@ -541,25 +745,25 @@ class Agent extends EventEmitter {
|
|
|
541
745
|
*/
|
|
542
746
|
async _processQueue() {
|
|
543
747
|
if (this._isProcessingQueue || this._messageQueue.length === 0) {
|
|
544
|
-
return
|
|
748
|
+
return;
|
|
545
749
|
}
|
|
546
750
|
|
|
547
|
-
this._isProcessingQueue = true
|
|
751
|
+
this._isProcessingQueue = true;
|
|
548
752
|
|
|
549
753
|
// 强制设置为 idle,确保 this.chat() 能执行
|
|
550
|
-
this._status = 'idle'
|
|
754
|
+
this._status = 'idle';
|
|
551
755
|
|
|
552
756
|
while (this._messageQueue.length > 0) {
|
|
553
|
-
const item = this._messageQueue.shift()
|
|
757
|
+
const item = this._messageQueue.shift();
|
|
554
758
|
try {
|
|
555
|
-
const result = await this.chat(item.message, item.options)
|
|
556
|
-
item.resolve(result)
|
|
759
|
+
const result = await this.chat(item.message, item.options);
|
|
760
|
+
item.resolve(result);
|
|
557
761
|
} catch (err) {
|
|
558
|
-
item.reject(err)
|
|
762
|
+
item.reject(err);
|
|
559
763
|
}
|
|
560
764
|
}
|
|
561
765
|
|
|
562
|
-
this._isProcessingQueue = false
|
|
766
|
+
this._isProcessingQueue = false;
|
|
563
767
|
}
|
|
564
768
|
|
|
565
769
|
/**
|
|
@@ -567,41 +771,41 @@ class Agent extends EventEmitter {
|
|
|
567
771
|
*/
|
|
568
772
|
async *chatStream(message, options = {}) {
|
|
569
773
|
if (this._status === 'busy') {
|
|
570
|
-
throw new Error('Agent is busy')
|
|
774
|
+
throw new Error('Agent is busy');
|
|
571
775
|
}
|
|
572
776
|
|
|
573
777
|
// 允许从 error 状态重试
|
|
574
778
|
if (this._status === 'error') {
|
|
575
|
-
this._status = 'idle'
|
|
779
|
+
this._status = 'idle';
|
|
576
780
|
}
|
|
577
781
|
|
|
578
|
-
this._status = 'busy'
|
|
579
|
-
this.emit('status', { status: 'busy' })
|
|
782
|
+
this._status = 'busy';
|
|
783
|
+
this.emit('status', { status: 'busy' });
|
|
580
784
|
|
|
581
785
|
try {
|
|
582
786
|
// 检查是否有待处理的系统通知(调度 + 思考)
|
|
583
|
-
const notifications = this._getAllPendingNotifications()
|
|
584
|
-
let enhancedMessage = message
|
|
787
|
+
const notifications = this._getAllPendingNotifications();
|
|
788
|
+
let enhancedMessage = message;
|
|
585
789
|
if (notifications.length > 0) {
|
|
586
|
-
enhancedMessage = `【系统通知】\n${notifications.join('\n\n')}\n\n---\n用户消息: ${message}
|
|
790
|
+
enhancedMessage = `【系统通知】\n${notifications.join('\n\n')}\n\n---\n用户消息: ${message}`;
|
|
587
791
|
}
|
|
588
792
|
|
|
589
|
-
this._syncTools()
|
|
793
|
+
this._syncTools();
|
|
590
794
|
|
|
591
|
-
yield* this._chatHandler.chatStream(enhancedMessage, options)
|
|
592
|
-
this._status = 'idle'
|
|
593
|
-
this.emit('status', { status: 'idle' })
|
|
795
|
+
yield* this._chatHandler.chatStream(enhancedMessage, options);
|
|
796
|
+
this._status = 'idle';
|
|
797
|
+
this.emit('status', { status: 'idle' });
|
|
594
798
|
|
|
595
799
|
// 处理队列中的下一条消息
|
|
596
|
-
setImmediate(() => this._processQueue())
|
|
800
|
+
setImmediate(() => this._processQueue());
|
|
597
801
|
} catch (err) {
|
|
598
|
-
this._status = 'error'
|
|
599
|
-
this.emit('status', { status: 'error', error: err.message })
|
|
802
|
+
this._status = 'error';
|
|
803
|
+
this.emit('status', { status: 'error', error: err.message });
|
|
600
804
|
|
|
601
805
|
// 发生错误时也要处理队列
|
|
602
|
-
setImmediate(() => this._processQueue())
|
|
806
|
+
setImmediate(() => this._processQueue());
|
|
603
807
|
|
|
604
|
-
throw err
|
|
808
|
+
throw err;
|
|
605
809
|
}
|
|
606
810
|
}
|
|
607
811
|
|
|
@@ -610,39 +814,40 @@ class Agent extends EventEmitter {
|
|
|
610
814
|
*/
|
|
611
815
|
setMetadata(keyOrObj, value) {
|
|
612
816
|
if (typeof keyOrObj === 'string') {
|
|
613
|
-
this._metadata.set(keyOrObj, value)
|
|
817
|
+
this._metadata.set(keyOrObj, value);
|
|
614
818
|
} else if (keyOrObj && typeof keyOrObj === 'object') {
|
|
615
819
|
for (const [key, val] of Object.entries(keyOrObj)) {
|
|
616
|
-
this._metadata.set(key, val)
|
|
820
|
+
this._metadata.set(key, val);
|
|
617
821
|
}
|
|
618
822
|
}
|
|
619
|
-
this.
|
|
620
|
-
|
|
823
|
+
this._invalidateSystemPromptCache();
|
|
824
|
+
this._refreshContext();
|
|
825
|
+
return this;
|
|
621
826
|
}
|
|
622
827
|
|
|
623
828
|
/**
|
|
624
829
|
* 获取元数据
|
|
625
830
|
*/
|
|
626
831
|
getMetadata(key) {
|
|
627
|
-
return this._metadata.get(key)
|
|
832
|
+
return this._metadata.get(key);
|
|
628
833
|
}
|
|
629
834
|
|
|
630
835
|
/**
|
|
631
836
|
* 删除元数据
|
|
632
837
|
*/
|
|
633
838
|
deleteMetadata(key) {
|
|
634
|
-
this._metadata.delete(key)
|
|
635
|
-
this._refreshContext()
|
|
636
|
-
return this
|
|
839
|
+
this._metadata.delete(key);
|
|
840
|
+
this._refreshContext();
|
|
841
|
+
return this;
|
|
637
842
|
}
|
|
638
843
|
|
|
639
844
|
/**
|
|
640
845
|
* 清空元数据
|
|
641
846
|
*/
|
|
642
847
|
clearMetadata() {
|
|
643
|
-
this._metadata.clear()
|
|
644
|
-
this._refreshContext()
|
|
645
|
-
return this
|
|
848
|
+
this._metadata.clear();
|
|
849
|
+
this._refreshContext();
|
|
850
|
+
return this;
|
|
646
851
|
}
|
|
647
852
|
|
|
648
853
|
/**
|
|
@@ -650,25 +855,25 @@ class Agent extends EventEmitter {
|
|
|
650
855
|
*/
|
|
651
856
|
clearHistory() {
|
|
652
857
|
if (this._chatHandler) {
|
|
653
|
-
this._chatHandler.clearHistory()
|
|
858
|
+
this._chatHandler.clearHistory();
|
|
654
859
|
}
|
|
655
|
-
return this
|
|
860
|
+
return this;
|
|
656
861
|
}
|
|
657
862
|
|
|
658
863
|
/**
|
|
659
864
|
* 获取状态
|
|
660
865
|
*/
|
|
661
866
|
getStatus() {
|
|
662
|
-
return this._status
|
|
867
|
+
return this._status;
|
|
663
868
|
}
|
|
664
869
|
|
|
665
870
|
/**
|
|
666
871
|
* 重置状态(从卡住状态恢复)
|
|
667
872
|
*/
|
|
668
873
|
resetStatus() {
|
|
669
|
-
this._status = 'idle'
|
|
670
|
-
this.emit('status', { status: 'idle' })
|
|
671
|
-
return this
|
|
874
|
+
this._status = 'idle';
|
|
875
|
+
this.emit('status', { status: 'idle' });
|
|
876
|
+
return this;
|
|
672
877
|
}
|
|
673
878
|
|
|
674
879
|
/**
|
|
@@ -676,12 +881,12 @@ class Agent extends EventEmitter {
|
|
|
676
881
|
*/
|
|
677
882
|
destroy() {
|
|
678
883
|
if (this._chatHandler) {
|
|
679
|
-
this._chatHandler.destroy()
|
|
884
|
+
this._chatHandler.destroy();
|
|
680
885
|
}
|
|
681
|
-
this._tools.clear()
|
|
682
|
-
this.removeAllListeners()
|
|
683
|
-
this.emit('destroyed')
|
|
886
|
+
this._tools.clear();
|
|
887
|
+
this.removeAllListeners();
|
|
888
|
+
this.emit('destroyed');
|
|
684
889
|
}
|
|
685
890
|
}
|
|
686
891
|
|
|
687
|
-
module.exports = { Agent }
|
|
892
|
+
module.exports = { Agent };
|