foliko 1.0.74 → 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 -643
- 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 +456 -106
- 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 -249
- 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,45 +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
|
|
33
|
-
this.providerOptions.temperature = 0.3
|
|
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 的概率
|
|
34
35
|
// 原始 system prompt
|
|
35
|
-
this._originalPrompt =
|
|
36
|
+
this._originalPrompt =
|
|
37
|
+
config.systemPrompt ||
|
|
38
|
+
'你是一个智能助手。当用户提出问题或任务时,你会主动分析需求,选择合适的工具来获取信息或执行操作。你善于将复杂任务拆解为多个步骤,通过工具协作完成。';
|
|
36
39
|
|
|
37
40
|
// 共享提示模板
|
|
38
|
-
this._sharedPrompt = config.sharedPrompt || ''
|
|
41
|
+
this._sharedPrompt = config.sharedPrompt || '';
|
|
39
42
|
|
|
40
43
|
// 元数据
|
|
41
|
-
const metadata = config.metadata || {}
|
|
42
|
-
this._metadata = new Map(Object.entries(metadata))
|
|
44
|
+
const metadata = config.metadata || {};
|
|
45
|
+
this._metadata = new Map(Object.entries(metadata));
|
|
43
46
|
|
|
44
|
-
this._chatHandler = null
|
|
45
|
-
this._tools = new Map()
|
|
46
|
-
this._status = 'idle'
|
|
47
|
+
this._chatHandler = null;
|
|
48
|
+
this._tools = new Map();
|
|
49
|
+
this._status = 'idle';
|
|
47
50
|
|
|
48
51
|
// 子Agent管理
|
|
49
|
-
this._subAgents = new Map()
|
|
52
|
+
this._subAgents = new Map();
|
|
50
53
|
|
|
51
54
|
// 消息队列(用于 pushMessage)
|
|
52
|
-
this._messageQueue = []
|
|
53
|
-
this._isProcessingQueue = false
|
|
55
|
+
this._messageQueue = [];
|
|
56
|
+
this._isProcessingQueue = false;
|
|
57
|
+
|
|
58
|
+
// System prompt 构建器
|
|
59
|
+
this._systemPromptBuilder = new SystemPromptBuilder();
|
|
60
|
+
this._registerDefaultPromptParts();
|
|
54
61
|
|
|
55
62
|
// 处理后的 system prompt (带上下文)
|
|
56
|
-
this.systemPrompt = this._buildSystemPrompt()
|
|
63
|
+
this.systemPrompt = this._buildSystemPrompt();
|
|
57
64
|
|
|
58
65
|
// 初始化聊天处理器
|
|
59
|
-
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());
|
|
60
115
|
}
|
|
61
116
|
|
|
62
117
|
/**
|
|
@@ -65,26 +120,26 @@ class Agent extends EventEmitter {
|
|
|
65
120
|
_getMetadataValue(key) {
|
|
66
121
|
// 优先从 metadata 获取
|
|
67
122
|
if (this._metadata.has(key)) {
|
|
68
|
-
return this._metadata.get(key)
|
|
123
|
+
return this._metadata.get(key);
|
|
69
124
|
}
|
|
70
125
|
|
|
71
126
|
// 内置变量
|
|
72
127
|
switch (key) {
|
|
73
128
|
case 'WORK_DIR':
|
|
74
129
|
case 'CWD':
|
|
75
|
-
return process.cwd()
|
|
130
|
+
return process.cwd();
|
|
76
131
|
case 'HOME_DIR':
|
|
77
|
-
return os.homedir()
|
|
132
|
+
return os.homedir();
|
|
78
133
|
case 'HOST_NAME':
|
|
79
|
-
return os.hostname()
|
|
134
|
+
return os.hostname();
|
|
80
135
|
case 'PLATFORM':
|
|
81
|
-
return process.platform
|
|
136
|
+
return process.platform;
|
|
82
137
|
case 'TIME':
|
|
83
|
-
return new Date().toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' })
|
|
138
|
+
return new Date().toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' });
|
|
84
139
|
case 'DATE':
|
|
85
|
-
return new Date().toISOString().split('T')[0]
|
|
140
|
+
return new Date().toISOString().split('T')[0];
|
|
86
141
|
default:
|
|
87
|
-
return `{{${key}}}
|
|
142
|
+
return `{{${key}}}`;
|
|
88
143
|
}
|
|
89
144
|
}
|
|
90
145
|
|
|
@@ -93,8 +148,8 @@ class Agent extends EventEmitter {
|
|
|
93
148
|
*/
|
|
94
149
|
_replacePlaceholders(template) {
|
|
95
150
|
return template.replace(/\{\{(\w+)\}\}/g, (match, key) => {
|
|
96
|
-
return this._getMetadataValue(key)
|
|
97
|
-
})
|
|
151
|
+
return this._getMetadataValue(key);
|
|
152
|
+
});
|
|
98
153
|
}
|
|
99
154
|
|
|
100
155
|
/**
|
|
@@ -102,155 +157,295 @@ class Agent extends EventEmitter {
|
|
|
102
157
|
*/
|
|
103
158
|
_buildToolsDescription() {
|
|
104
159
|
if (this._tools.size === 0) {
|
|
105
|
-
return ''
|
|
160
|
+
return '';
|
|
106
161
|
}
|
|
107
162
|
|
|
108
|
-
|
|
163
|
+
// 需要排除的子Agent相关工具(它们通过专门的子Agent部分提供)
|
|
164
|
+
// const excludedTools = new Set(['subagent_call', 'subagent_list', 'subagent_reload']);
|
|
165
|
+
|
|
166
|
+
let desc = '【可用工具】\n';
|
|
109
167
|
for (const [name, tool] of this._tools) {
|
|
110
168
|
// 跳过没有描述的工具(对LLM无帮助)
|
|
111
|
-
if (!tool.description) continue
|
|
112
|
-
|
|
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`;
|
|
113
175
|
}
|
|
114
|
-
return desc.trim()
|
|
176
|
+
return desc.trim();
|
|
115
177
|
}
|
|
116
178
|
|
|
117
179
|
/**
|
|
118
180
|
* 构建技能描述
|
|
119
181
|
*/
|
|
120
182
|
_buildSkillsDescription() {
|
|
121
|
-
const skillManager = this.framework.pluginManager.get('skill-manager')
|
|
183
|
+
const skillManager = this.framework.pluginManager.get('skill-manager');
|
|
122
184
|
if (!skillManager) {
|
|
123
|
-
return ''
|
|
185
|
+
return '';
|
|
124
186
|
}
|
|
125
187
|
|
|
126
|
-
const skills = skillManager.getAllSkills()
|
|
188
|
+
const skills = skillManager.getAllSkills();
|
|
127
189
|
if (!skills || skills.length === 0) {
|
|
128
|
-
return ''
|
|
190
|
+
return '';
|
|
129
191
|
}
|
|
130
192
|
|
|
131
|
-
let desc = '【可用技能】\n'
|
|
193
|
+
let desc = '【可用技能】\n';
|
|
132
194
|
for (const skill of skills) {
|
|
133
|
-
const name = skill.metadata?.name || skill.name || 'unknown'
|
|
134
|
-
const descText = skill.metadata?.description || ''
|
|
135
|
-
desc += `- ${name}: ${descText}\n
|
|
195
|
+
const name = skill.metadata?.name || skill.name || 'unknown';
|
|
196
|
+
const descText = skill.metadata?.description || '';
|
|
197
|
+
desc += `- ${name}: ${descText}\n`;
|
|
136
198
|
}
|
|
137
|
-
desc +=
|
|
138
|
-
|
|
199
|
+
desc +=
|
|
200
|
+
'\n重要:当需要开发插件、执行专业任务时,必须先使用 loadSkill 工具加载对应技能,获取专业指导。';
|
|
201
|
+
return desc.trim();
|
|
139
202
|
}
|
|
140
203
|
|
|
141
204
|
/**
|
|
142
205
|
* 构建系统能力描述
|
|
143
206
|
*/
|
|
144
207
|
_buildCapabilitiesDescription() {
|
|
145
|
-
const plugins = this.framework.pluginManager.getAll()
|
|
208
|
+
const plugins = this.framework.pluginManager.getAll();
|
|
146
209
|
if (!plugins || plugins.length === 0) {
|
|
147
|
-
return ''
|
|
210
|
+
return '';
|
|
148
211
|
}
|
|
149
212
|
|
|
150
213
|
// 过滤出有描述的关键插件(排除内部插件)
|
|
151
|
-
const keyPlugins = plugins.filter(p => {
|
|
152
|
-
const name = p.name
|
|
214
|
+
const keyPlugins = plugins.filter((p) => {
|
|
215
|
+
const name = p.name;
|
|
153
216
|
// 排除默认配置插件和内部插件
|
|
154
|
-
return name !== 'defaults' && name !== 'agent'
|
|
155
|
-
})
|
|
217
|
+
return name !== 'defaults' && name !== 'agent';
|
|
218
|
+
});
|
|
156
219
|
|
|
157
220
|
if (keyPlugins.length === 0) {
|
|
158
|
-
return ''
|
|
221
|
+
return '';
|
|
159
222
|
}
|
|
160
223
|
|
|
161
|
-
let desc = '【系统能力】\n'
|
|
224
|
+
let desc = '【系统能力】\n';
|
|
162
225
|
for (const plugin of keyPlugins) {
|
|
163
|
-
const name = plugin.instance?.name || plugin.name || 'unknown'
|
|
164
|
-
const description = plugin.instance?.description || '无描述'
|
|
165
|
-
desc += `- ${name}: ${description}\n
|
|
226
|
+
const name = plugin.instance?.name || plugin.name || 'unknown';
|
|
227
|
+
const description = plugin.instance?.description || '无描述';
|
|
228
|
+
desc += `- ${name}: ${description}\n`;
|
|
166
229
|
}
|
|
167
230
|
|
|
168
|
-
return desc.trim()
|
|
231
|
+
return desc.trim();
|
|
169
232
|
}
|
|
170
233
|
|
|
171
234
|
/**
|
|
172
235
|
* 构建子Agent描述
|
|
236
|
+
* 动态从配置文件读取每个子Agent的专业领域
|
|
173
237
|
*/
|
|
174
238
|
_buildSubAgentsDescription() {
|
|
175
|
-
|
|
176
|
-
|
|
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
|
+
}
|
|
177
270
|
}
|
|
178
271
|
|
|
179
|
-
|
|
180
|
-
desc += '
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
desc += '2. 你需要对任务进行拆分,传递给对应的子Agent执行。\n'
|
|
185
|
-
desc += '3. 多个不同类型的任务必须分别委托给不同的子Agent,每个子Agent只处理自己专业领域的任务。\n'
|
|
186
|
-
desc += '\n【可委托的子 Agent】\n'
|
|
187
|
-
for (const [name, { role, goal }] of this._subAgents) {
|
|
188
|
-
desc += ` - ${name}: ${role || goal || '子代理'}\n`
|
|
189
|
-
}
|
|
190
|
-
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';
|
|
191
277
|
|
|
192
|
-
return desc.trim()
|
|
278
|
+
return desc.trim();
|
|
193
279
|
}
|
|
194
280
|
|
|
195
281
|
/**
|
|
196
|
-
*
|
|
282
|
+
* 从配置文件动态读取子Agent的核心能力
|
|
283
|
+
* 支持 .json 和 .md 格式
|
|
284
|
+
* @private
|
|
197
285
|
*/
|
|
198
|
-
|
|
199
|
-
|
|
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
|
+
}
|
|
200
305
|
|
|
201
|
-
|
|
202
|
-
|
|
306
|
+
if (!filePath) {
|
|
307
|
+
return null;
|
|
308
|
+
}
|
|
203
309
|
|
|
204
|
-
|
|
205
|
-
if (this._sharedPrompt) {
|
|
206
|
-
const replaced = this._replacePlaceholders(this._sharedPrompt)
|
|
207
|
-
parts.push(replaced)
|
|
208
|
-
}
|
|
310
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
209
311
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
if (typeof value === 'object') {
|
|
215
|
-
metaParts.push(`- ${key}: ${JSON.stringify(value)}`)
|
|
216
|
-
} else {
|
|
217
|
-
metaParts.push(`- ${key}: ${value}`)
|
|
218
|
-
}
|
|
312
|
+
// .json 格式
|
|
313
|
+
if (filePath.endsWith('.json')) {
|
|
314
|
+
const config = JSON.parse(content);
|
|
315
|
+
return this._extractCapabilitiesFromConfig(config);
|
|
219
316
|
}
|
|
220
|
-
parts.push(metaParts.join('\n'))
|
|
221
|
-
}
|
|
222
317
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
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;
|
|
227
326
|
}
|
|
327
|
+
}
|
|
228
328
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
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;
|
|
233
345
|
}
|
|
346
|
+
return config.description || null;
|
|
347
|
+
}
|
|
234
348
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
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;
|
|
239
357
|
}
|
|
240
358
|
|
|
241
|
-
|
|
242
|
-
const
|
|
243
|
-
|
|
244
|
-
|
|
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
|
+
}
|
|
245
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
|
+
}
|
|
246
396
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
if (
|
|
250
|
-
|
|
397
|
+
_buildSystemPrompt() {
|
|
398
|
+
// 如果没变脏,返回缓存
|
|
399
|
+
if (!this._systemPromptDirty && this._systemPromptCache !== null) {
|
|
400
|
+
return this._systemPromptCache;
|
|
251
401
|
}
|
|
252
402
|
|
|
253
|
-
|
|
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;
|
|
254
449
|
}
|
|
255
450
|
|
|
256
451
|
/**
|
|
@@ -259,12 +454,13 @@ class Agent extends EventEmitter {
|
|
|
259
454
|
*/
|
|
260
455
|
_getToolCoreRules() {
|
|
261
456
|
return `【工具调用核心规则】
|
|
262
|
-
1.
|
|
263
|
-
2.
|
|
264
|
-
3.
|
|
265
|
-
4.
|
|
266
|
-
5.
|
|
267
|
-
6.
|
|
457
|
+
1. **子Agent优先**:任务匹配子Agent专业领域时,**必须优先使用** 使用 subagent_call 工具并指定 agentName 委托给对应子Agent处理,而不是直接调用工具。只有当没有匹配的子Agent时,才直接调用工具。
|
|
458
|
+
2. **必须先调用工具再回复**:当问题需要信息、操作或计算时,必须调用工具获取真实结果后才能回答。禁止在未调用工具的情况下直接给出答案。
|
|
459
|
+
3. **禁止编造数据**:不许捏造用户、订单、任务、文件、内容等任何数据。所有数据必须通过工具获取。
|
|
460
|
+
4. **工具优先**:可用工具列表会提供,格式为 toolName(toolArgs)。不确定用哪个工具时,优先调用可能相关的工具。
|
|
461
|
+
5. **结果导向**:调用工具后,基于返回结果回答,不要重复工具的内部实现细节。
|
|
462
|
+
6. **多步骤任务**:复杂任务拆解为多个工具调用,逐步完成,每步基于结果决定下一步。
|
|
463
|
+
|
|
268
464
|
|
|
269
465
|
【响应规范】
|
|
270
466
|
- 直接给出结论或结果,不说"我需要..."、"我建议..."等铺垫话术
|
|
@@ -274,16 +470,16 @@ class Agent extends EventEmitter {
|
|
|
274
470
|
【禁止事项】
|
|
275
471
|
- 不调用工具就直接回答
|
|
276
472
|
- 编造不存在的数据、文件、订单、用户等信息
|
|
277
|
-
-
|
|
473
|
+
- 回复含糊不清,让用户无法确定答案是否正确`;
|
|
278
474
|
}
|
|
279
475
|
|
|
280
476
|
/**
|
|
281
477
|
* 刷新上下文
|
|
282
478
|
*/
|
|
283
479
|
_refreshContext() {
|
|
284
|
-
this.systemPrompt = this._buildSystemPrompt()
|
|
480
|
+
this.systemPrompt = this._buildSystemPrompt();
|
|
285
481
|
if (this._chatHandler) {
|
|
286
|
-
this._chatHandler.setSystemPrompt(this.systemPrompt)
|
|
482
|
+
this._chatHandler.setSystemPrompt(this.systemPrompt);
|
|
287
483
|
}
|
|
288
484
|
}
|
|
289
485
|
|
|
@@ -292,10 +488,10 @@ class Agent extends EventEmitter {
|
|
|
292
488
|
* @private
|
|
293
489
|
*/
|
|
294
490
|
_initChatHandler() {
|
|
295
|
-
let aiClient = null
|
|
296
|
-
const aiPlugin = this.framework.pluginManager.get('ai')
|
|
491
|
+
let aiClient = null;
|
|
492
|
+
const aiPlugin = this.framework.pluginManager.get('ai');
|
|
297
493
|
if (aiPlugin) {
|
|
298
|
-
aiClient = aiPlugin.getAIClient()
|
|
494
|
+
aiClient = aiPlugin.getAIClient();
|
|
299
495
|
}
|
|
300
496
|
|
|
301
497
|
this._chatHandler = new AgentChatHandler(this, {
|
|
@@ -308,52 +504,53 @@ class Agent extends EventEmitter {
|
|
|
308
504
|
maxContextTokens: this.config.maxContextTokens,
|
|
309
505
|
compressionThreshold: this.config.compressionThreshold,
|
|
310
506
|
keepRecentMessages: this.config.keepRecentMessages,
|
|
311
|
-
enableSmartCompress: this.config.enableSmartCompress
|
|
312
|
-
})
|
|
507
|
+
enableSmartCompress: this.config.enableSmartCompress,
|
|
508
|
+
});
|
|
313
509
|
|
|
314
510
|
if (aiClient) {
|
|
315
|
-
this._chatHandler.setAIClient(aiClient)
|
|
511
|
+
this._chatHandler.setAIClient(aiClient);
|
|
316
512
|
}
|
|
317
513
|
|
|
318
514
|
// 转发事件
|
|
319
|
-
this._chatHandler.on('message', (msg) => this.emit('message', msg))
|
|
320
|
-
this._chatHandler.on('chunk', (chunk) => this.emit('chunk', chunk))
|
|
321
|
-
this._chatHandler.on('tool-call', (tool) => this.emit('tool-call', tool))
|
|
322
|
-
this._chatHandler.on('tool-result', (result) => this.emit('tool-result', result))
|
|
323
|
-
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));
|
|
324
520
|
|
|
325
|
-
this._syncTools()
|
|
521
|
+
this._syncTools();
|
|
326
522
|
}
|
|
327
523
|
|
|
328
524
|
/**
|
|
329
525
|
* 设置系统提示
|
|
330
526
|
*/
|
|
331
527
|
setSystemPrompt(prompt) {
|
|
332
|
-
this._originalPrompt = prompt
|
|
333
|
-
this.systemPrompt = this._buildSystemPrompt()
|
|
528
|
+
this._originalPrompt = prompt;
|
|
529
|
+
this.systemPrompt = this._buildSystemPrompt();
|
|
334
530
|
if (this._chatHandler) {
|
|
335
|
-
this._chatHandler.setSystemPrompt(this.systemPrompt)
|
|
531
|
+
this._chatHandler.setSystemPrompt(this.systemPrompt);
|
|
336
532
|
}
|
|
337
|
-
return this
|
|
533
|
+
return this;
|
|
338
534
|
}
|
|
339
535
|
|
|
340
536
|
/**
|
|
341
537
|
* 注册工具到 Agent
|
|
342
538
|
*/
|
|
343
539
|
registerTool(tool) {
|
|
344
|
-
this._tools.set(tool.name, tool)
|
|
540
|
+
this._tools.set(tool.name, tool);
|
|
541
|
+
this._invalidateSystemPromptCache();
|
|
345
542
|
if (this._chatHandler) {
|
|
346
|
-
this._chatHandler.registerTool(tool)
|
|
543
|
+
this._chatHandler.registerTool(tool);
|
|
347
544
|
}
|
|
348
|
-
this._refreshContext()
|
|
349
|
-
return this
|
|
545
|
+
this._refreshContext();
|
|
546
|
+
return this;
|
|
350
547
|
}
|
|
351
548
|
|
|
352
549
|
/**
|
|
353
550
|
* 获取已注册工具
|
|
354
551
|
*/
|
|
355
552
|
getTools() {
|
|
356
|
-
return Array.from(this._tools.values())
|
|
553
|
+
return Array.from(this._tools.values());
|
|
357
554
|
}
|
|
358
555
|
|
|
359
556
|
/**
|
|
@@ -364,7 +561,7 @@ class Agent extends EventEmitter {
|
|
|
364
561
|
if (this.framework.toolRegistry.size() > 0) {
|
|
365
562
|
for (const tool of this.framework.getTools()) {
|
|
366
563
|
if (!this._tools.has(tool.name)) {
|
|
367
|
-
this.registerTool(tool)
|
|
564
|
+
this.registerTool(tool);
|
|
368
565
|
}
|
|
369
566
|
}
|
|
370
567
|
}
|
|
@@ -378,25 +575,27 @@ class Agent extends EventEmitter {
|
|
|
378
575
|
* @param {string} goal - 目标描述
|
|
379
576
|
*/
|
|
380
577
|
registerSubAgent(name, agent, role, goal) {
|
|
381
|
-
this._subAgents.set(name, { agent, role, goal })
|
|
382
|
-
this.
|
|
383
|
-
|
|
578
|
+
this._subAgents.set(name, { agent, role, goal });
|
|
579
|
+
this._invalidateSystemPromptCache();
|
|
580
|
+
this._refreshContext();
|
|
581
|
+
return this;
|
|
384
582
|
}
|
|
385
583
|
|
|
386
584
|
/**
|
|
387
585
|
* 注销子Agent
|
|
388
586
|
*/
|
|
389
587
|
unregisterSubAgent(name) {
|
|
390
|
-
this._subAgents.delete(name)
|
|
391
|
-
this.
|
|
392
|
-
|
|
588
|
+
this._subAgents.delete(name);
|
|
589
|
+
this._invalidateSystemPromptCache();
|
|
590
|
+
this._refreshContext();
|
|
591
|
+
return this;
|
|
393
592
|
}
|
|
394
593
|
|
|
395
594
|
/**
|
|
396
595
|
* 获取所有子Agent
|
|
397
596
|
*/
|
|
398
597
|
getSubAgents() {
|
|
399
|
-
return this._subAgents
|
|
598
|
+
return this._subAgents;
|
|
400
599
|
}
|
|
401
600
|
|
|
402
601
|
/**
|
|
@@ -404,22 +603,22 @@ class Agent extends EventEmitter {
|
|
|
404
603
|
*/
|
|
405
604
|
_getAndClearSchedulerNotifications() {
|
|
406
605
|
try {
|
|
407
|
-
const scheduler = this.framework.pluginManager.get('scheduler')
|
|
606
|
+
const scheduler = this.framework.pluginManager.get('scheduler');
|
|
408
607
|
if (scheduler && scheduler.instance && scheduler.instance.getPendingNotifications) {
|
|
409
|
-
const results = scheduler.instance.getPendingNotifications()
|
|
608
|
+
const results = scheduler.instance.getPendingNotifications();
|
|
410
609
|
if (results.length > 0) {
|
|
411
|
-
const notifications = results.slice(-5).reverse() // 最多5条,最新的在前
|
|
610
|
+
const notifications = results.slice(-5).reverse(); // 最多5条,最新的在前
|
|
412
611
|
// 清除已发送的通知
|
|
413
612
|
if (scheduler.instance.clearDeliveredNotifications) {
|
|
414
|
-
scheduler.instance.clearDeliveredNotifications(notifications.length)
|
|
613
|
+
scheduler.instance.clearDeliveredNotifications(notifications.length);
|
|
415
614
|
}
|
|
416
|
-
return notifications
|
|
615
|
+
return notifications;
|
|
417
616
|
}
|
|
418
617
|
}
|
|
419
618
|
} catch (err) {
|
|
420
619
|
// 忽略错误,避免影响主流程
|
|
421
620
|
}
|
|
422
|
-
return []
|
|
621
|
+
return [];
|
|
423
622
|
}
|
|
424
623
|
|
|
425
624
|
/**
|
|
@@ -427,38 +626,42 @@ class Agent extends EventEmitter {
|
|
|
427
626
|
*/
|
|
428
627
|
_getAndClearThinkNotifications() {
|
|
429
628
|
try {
|
|
430
|
-
const think = this.framework.pluginManager.get('think')
|
|
629
|
+
const think = this.framework.pluginManager.get('think');
|
|
431
630
|
if (think && think.instance && think.instance.getPendingThoughts) {
|
|
432
|
-
const thoughts = think.instance.getPendingThoughts()
|
|
631
|
+
const thoughts = think.instance.getPendingThoughts();
|
|
433
632
|
if (thoughts.length > 0) {
|
|
434
|
-
return thoughts.slice(-5).reverse() // 最多5条,最新的在前
|
|
633
|
+
return thoughts.slice(-5).reverse(); // 最多5条,最新的在前
|
|
435
634
|
}
|
|
436
635
|
}
|
|
437
636
|
} catch (err) {
|
|
438
637
|
// 忽略错误,避免影响主流程
|
|
439
638
|
}
|
|
440
|
-
return []
|
|
639
|
+
return [];
|
|
441
640
|
}
|
|
442
641
|
|
|
443
642
|
/**
|
|
444
643
|
* 获取所有待处理的系统通知(调度 + 思考)
|
|
445
644
|
*/
|
|
446
645
|
_getAllPendingNotifications() {
|
|
447
|
-
const notifications = []
|
|
646
|
+
const notifications = [];
|
|
448
647
|
|
|
449
648
|
// 调度通知
|
|
450
|
-
const schedulerNotifs = this._getAndClearSchedulerNotifications()
|
|
649
|
+
const schedulerNotifs = this._getAndClearSchedulerNotifications();
|
|
451
650
|
for (const n of schedulerNotifs) {
|
|
452
|
-
notifications.push(
|
|
651
|
+
notifications.push(
|
|
652
|
+
`【定时任务通知】\n任务: ${n.taskName || n.taskId}\n执行时间: ${n.executedAt}\n结果: ${n.result || n.action || '执行完成'}`
|
|
653
|
+
);
|
|
453
654
|
}
|
|
454
655
|
|
|
455
656
|
// 思考通知
|
|
456
|
-
const thinkNotifs = this._getAndClearThinkNotifications()
|
|
657
|
+
const thinkNotifs = this._getAndClearThinkNotifications();
|
|
457
658
|
for (const t of thinkNotifs) {
|
|
458
|
-
notifications.push(
|
|
659
|
+
notifications.push(
|
|
660
|
+
`【主动思考】\n模式: ${t.mode}\n主题: ${t.topic}\n结果: ${t.result || '思考完成'}`
|
|
661
|
+
);
|
|
459
662
|
}
|
|
460
663
|
|
|
461
|
-
return notifications
|
|
664
|
+
return notifications;
|
|
462
665
|
}
|
|
463
666
|
|
|
464
667
|
/**
|
|
@@ -466,42 +669,42 @@ class Agent extends EventEmitter {
|
|
|
466
669
|
*/
|
|
467
670
|
async chat(message, options = {}) {
|
|
468
671
|
if (this._status === 'busy') {
|
|
469
|
-
throw new Error('Agent is busy')
|
|
672
|
+
throw new Error('Agent is busy');
|
|
470
673
|
}
|
|
471
674
|
|
|
472
675
|
if (this._status === 'error') {
|
|
473
|
-
this._status = 'idle'
|
|
676
|
+
this._status = 'idle';
|
|
474
677
|
}
|
|
475
678
|
|
|
476
|
-
this._status = 'busy'
|
|
477
|
-
this.emit('status', { status: 'busy' })
|
|
679
|
+
this._status = 'busy';
|
|
680
|
+
this.emit('status', { status: 'busy' });
|
|
478
681
|
|
|
479
682
|
try {
|
|
480
683
|
// 检查是否有待处理的系统通知(调度 + 思考)
|
|
481
|
-
const notifications = this._getAllPendingNotifications()
|
|
482
|
-
let enhancedMessage = message
|
|
684
|
+
const notifications = this._getAllPendingNotifications();
|
|
685
|
+
let enhancedMessage = message;
|
|
483
686
|
if (notifications.length > 0) {
|
|
484
|
-
enhancedMessage = `【系统通知】\n${notifications.join('\n\n')}\n\n---\n用户消息: ${message}
|
|
687
|
+
enhancedMessage = `【系统通知】\n${notifications.join('\n\n')}\n\n---\n用户消息: ${message}`;
|
|
485
688
|
}
|
|
486
689
|
|
|
487
|
-
this._syncTools()
|
|
690
|
+
this._syncTools();
|
|
488
691
|
|
|
489
|
-
const result = await this._chatHandler.chat(enhancedMessage, options)
|
|
490
|
-
this._status = 'idle'
|
|
491
|
-
this.emit('status', { status: 'idle' })
|
|
692
|
+
const result = await this._chatHandler.chat(enhancedMessage, options);
|
|
693
|
+
this._status = 'idle';
|
|
694
|
+
this.emit('status', { status: 'idle' });
|
|
492
695
|
|
|
493
696
|
// 处理队列中的下一条消息
|
|
494
|
-
setImmediate(() => this._processQueue())
|
|
697
|
+
setImmediate(() => this._processQueue());
|
|
495
698
|
|
|
496
|
-
return result
|
|
699
|
+
return result;
|
|
497
700
|
} catch (err) {
|
|
498
|
-
this._status = 'error'
|
|
499
|
-
this.emit('status', { status: 'error', error: err.message })
|
|
701
|
+
this._status = 'error';
|
|
702
|
+
this.emit('status', { status: 'error', error: err.message });
|
|
500
703
|
|
|
501
704
|
// 发生错误时也要处理队列
|
|
502
|
-
setImmediate(() => this._processQueue())
|
|
705
|
+
setImmediate(() => this._processQueue());
|
|
503
706
|
|
|
504
|
-
throw err
|
|
707
|
+
throw err;
|
|
505
708
|
}
|
|
506
709
|
}
|
|
507
710
|
|
|
@@ -515,25 +718,25 @@ class Agent extends EventEmitter {
|
|
|
515
718
|
*/
|
|
516
719
|
async pushMessage(message, options = {}) {
|
|
517
720
|
// 自动从执行上下文获取 sessionId
|
|
518
|
-
const ctx = this.framework.getExecutionContext()
|
|
721
|
+
const ctx = this.framework.getExecutionContext();
|
|
519
722
|
if (ctx?.sessionId && !options.sessionId) {
|
|
520
|
-
options.sessionId = ctx.sessionId
|
|
723
|
+
options.sessionId = ctx.sessionId;
|
|
521
724
|
}
|
|
522
725
|
|
|
523
726
|
// 如果忙碌,进入队列等待
|
|
524
727
|
if (this._status === 'busy') {
|
|
525
|
-
const queuedItem = { message, options, resolve: null, reject: null }
|
|
728
|
+
const queuedItem = { message, options, resolve: null, reject: null };
|
|
526
729
|
const promise = new Promise((resolve, reject) => {
|
|
527
|
-
queuedItem.resolve = resolve
|
|
528
|
-
queuedItem.reject = reject
|
|
529
|
-
})
|
|
530
|
-
this._messageQueue.push(queuedItem)
|
|
531
|
-
|
|
532
|
-
return promise
|
|
730
|
+
queuedItem.resolve = resolve;
|
|
731
|
+
queuedItem.reject = reject;
|
|
732
|
+
});
|
|
733
|
+
this._messageQueue.push(queuedItem);
|
|
734
|
+
// Agent busy, message queued
|
|
735
|
+
return promise;
|
|
533
736
|
}
|
|
534
737
|
|
|
535
738
|
// 空闲则直接处理
|
|
536
|
-
return this.chat(message, options)
|
|
739
|
+
return this.chat(message, options);
|
|
537
740
|
}
|
|
538
741
|
|
|
539
742
|
/**
|
|
@@ -542,25 +745,25 @@ class Agent extends EventEmitter {
|
|
|
542
745
|
*/
|
|
543
746
|
async _processQueue() {
|
|
544
747
|
if (this._isProcessingQueue || this._messageQueue.length === 0) {
|
|
545
|
-
return
|
|
748
|
+
return;
|
|
546
749
|
}
|
|
547
750
|
|
|
548
|
-
this._isProcessingQueue = true
|
|
751
|
+
this._isProcessingQueue = true;
|
|
549
752
|
|
|
550
753
|
// 强制设置为 idle,确保 this.chat() 能执行
|
|
551
|
-
this._status = 'idle'
|
|
754
|
+
this._status = 'idle';
|
|
552
755
|
|
|
553
756
|
while (this._messageQueue.length > 0) {
|
|
554
|
-
const item = this._messageQueue.shift()
|
|
757
|
+
const item = this._messageQueue.shift();
|
|
555
758
|
try {
|
|
556
|
-
const result = await this.chat(item.message, item.options)
|
|
557
|
-
item.resolve(result)
|
|
759
|
+
const result = await this.chat(item.message, item.options);
|
|
760
|
+
item.resolve(result);
|
|
558
761
|
} catch (err) {
|
|
559
|
-
item.reject(err)
|
|
762
|
+
item.reject(err);
|
|
560
763
|
}
|
|
561
764
|
}
|
|
562
765
|
|
|
563
|
-
this._isProcessingQueue = false
|
|
766
|
+
this._isProcessingQueue = false;
|
|
564
767
|
}
|
|
565
768
|
|
|
566
769
|
/**
|
|
@@ -568,41 +771,41 @@ class Agent extends EventEmitter {
|
|
|
568
771
|
*/
|
|
569
772
|
async *chatStream(message, options = {}) {
|
|
570
773
|
if (this._status === 'busy') {
|
|
571
|
-
throw new Error('Agent is busy')
|
|
774
|
+
throw new Error('Agent is busy');
|
|
572
775
|
}
|
|
573
776
|
|
|
574
777
|
// 允许从 error 状态重试
|
|
575
778
|
if (this._status === 'error') {
|
|
576
|
-
this._status = 'idle'
|
|
779
|
+
this._status = 'idle';
|
|
577
780
|
}
|
|
578
781
|
|
|
579
|
-
this._status = 'busy'
|
|
580
|
-
this.emit('status', { status: 'busy' })
|
|
782
|
+
this._status = 'busy';
|
|
783
|
+
this.emit('status', { status: 'busy' });
|
|
581
784
|
|
|
582
785
|
try {
|
|
583
786
|
// 检查是否有待处理的系统通知(调度 + 思考)
|
|
584
|
-
const notifications = this._getAllPendingNotifications()
|
|
585
|
-
let enhancedMessage = message
|
|
787
|
+
const notifications = this._getAllPendingNotifications();
|
|
788
|
+
let enhancedMessage = message;
|
|
586
789
|
if (notifications.length > 0) {
|
|
587
|
-
enhancedMessage = `【系统通知】\n${notifications.join('\n\n')}\n\n---\n用户消息: ${message}
|
|
790
|
+
enhancedMessage = `【系统通知】\n${notifications.join('\n\n')}\n\n---\n用户消息: ${message}`;
|
|
588
791
|
}
|
|
589
792
|
|
|
590
|
-
this._syncTools()
|
|
793
|
+
this._syncTools();
|
|
591
794
|
|
|
592
|
-
yield* this._chatHandler.chatStream(enhancedMessage, options)
|
|
593
|
-
this._status = 'idle'
|
|
594
|
-
this.emit('status', { status: 'idle' })
|
|
795
|
+
yield* this._chatHandler.chatStream(enhancedMessage, options);
|
|
796
|
+
this._status = 'idle';
|
|
797
|
+
this.emit('status', { status: 'idle' });
|
|
595
798
|
|
|
596
799
|
// 处理队列中的下一条消息
|
|
597
|
-
setImmediate(() => this._processQueue())
|
|
800
|
+
setImmediate(() => this._processQueue());
|
|
598
801
|
} catch (err) {
|
|
599
|
-
this._status = 'error'
|
|
600
|
-
this.emit('status', { status: 'error', error: err.message })
|
|
802
|
+
this._status = 'error';
|
|
803
|
+
this.emit('status', { status: 'error', error: err.message });
|
|
601
804
|
|
|
602
805
|
// 发生错误时也要处理队列
|
|
603
|
-
setImmediate(() => this._processQueue())
|
|
806
|
+
setImmediate(() => this._processQueue());
|
|
604
807
|
|
|
605
|
-
throw err
|
|
808
|
+
throw err;
|
|
606
809
|
}
|
|
607
810
|
}
|
|
608
811
|
|
|
@@ -611,39 +814,40 @@ class Agent extends EventEmitter {
|
|
|
611
814
|
*/
|
|
612
815
|
setMetadata(keyOrObj, value) {
|
|
613
816
|
if (typeof keyOrObj === 'string') {
|
|
614
|
-
this._metadata.set(keyOrObj, value)
|
|
817
|
+
this._metadata.set(keyOrObj, value);
|
|
615
818
|
} else if (keyOrObj && typeof keyOrObj === 'object') {
|
|
616
819
|
for (const [key, val] of Object.entries(keyOrObj)) {
|
|
617
|
-
this._metadata.set(key, val)
|
|
820
|
+
this._metadata.set(key, val);
|
|
618
821
|
}
|
|
619
822
|
}
|
|
620
|
-
this.
|
|
621
|
-
|
|
823
|
+
this._invalidateSystemPromptCache();
|
|
824
|
+
this._refreshContext();
|
|
825
|
+
return this;
|
|
622
826
|
}
|
|
623
827
|
|
|
624
828
|
/**
|
|
625
829
|
* 获取元数据
|
|
626
830
|
*/
|
|
627
831
|
getMetadata(key) {
|
|
628
|
-
return this._metadata.get(key)
|
|
832
|
+
return this._metadata.get(key);
|
|
629
833
|
}
|
|
630
834
|
|
|
631
835
|
/**
|
|
632
836
|
* 删除元数据
|
|
633
837
|
*/
|
|
634
838
|
deleteMetadata(key) {
|
|
635
|
-
this._metadata.delete(key)
|
|
636
|
-
this._refreshContext()
|
|
637
|
-
return this
|
|
839
|
+
this._metadata.delete(key);
|
|
840
|
+
this._refreshContext();
|
|
841
|
+
return this;
|
|
638
842
|
}
|
|
639
843
|
|
|
640
844
|
/**
|
|
641
845
|
* 清空元数据
|
|
642
846
|
*/
|
|
643
847
|
clearMetadata() {
|
|
644
|
-
this._metadata.clear()
|
|
645
|
-
this._refreshContext()
|
|
646
|
-
return this
|
|
848
|
+
this._metadata.clear();
|
|
849
|
+
this._refreshContext();
|
|
850
|
+
return this;
|
|
647
851
|
}
|
|
648
852
|
|
|
649
853
|
/**
|
|
@@ -651,25 +855,25 @@ class Agent extends EventEmitter {
|
|
|
651
855
|
*/
|
|
652
856
|
clearHistory() {
|
|
653
857
|
if (this._chatHandler) {
|
|
654
|
-
this._chatHandler.clearHistory()
|
|
858
|
+
this._chatHandler.clearHistory();
|
|
655
859
|
}
|
|
656
|
-
return this
|
|
860
|
+
return this;
|
|
657
861
|
}
|
|
658
862
|
|
|
659
863
|
/**
|
|
660
864
|
* 获取状态
|
|
661
865
|
*/
|
|
662
866
|
getStatus() {
|
|
663
|
-
return this._status
|
|
867
|
+
return this._status;
|
|
664
868
|
}
|
|
665
869
|
|
|
666
870
|
/**
|
|
667
871
|
* 重置状态(从卡住状态恢复)
|
|
668
872
|
*/
|
|
669
873
|
resetStatus() {
|
|
670
|
-
this._status = 'idle'
|
|
671
|
-
this.emit('status', { status: 'idle' })
|
|
672
|
-
return this
|
|
874
|
+
this._status = 'idle';
|
|
875
|
+
this.emit('status', { status: 'idle' });
|
|
876
|
+
return this;
|
|
673
877
|
}
|
|
674
878
|
|
|
675
879
|
/**
|
|
@@ -677,12 +881,12 @@ class Agent extends EventEmitter {
|
|
|
677
881
|
*/
|
|
678
882
|
destroy() {
|
|
679
883
|
if (this._chatHandler) {
|
|
680
|
-
this._chatHandler.destroy()
|
|
884
|
+
this._chatHandler.destroy();
|
|
681
885
|
}
|
|
682
|
-
this._tools.clear()
|
|
683
|
-
this.removeAllListeners()
|
|
684
|
-
this.emit('destroyed')
|
|
886
|
+
this._tools.clear();
|
|
887
|
+
this.removeAllListeners();
|
|
888
|
+
this.emit('destroyed');
|
|
685
889
|
}
|
|
686
890
|
}
|
|
687
891
|
|
|
688
|
-
module.exports = { Agent }
|
|
892
|
+
module.exports = { Agent };
|