foliko 1.1.93 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +2 -1
- package/CLAUDE.md +56 -30
- package/REFACTORING_PLAN.md +645 -0
- package/docs/architecture.md +131 -0
- package/docs/migration.md +57 -0
- package/docs/public-api.md +138 -0
- package/docs/usage.md +385 -0
- package/examples/ambient-example.js +20 -137
- package/examples/basic.js +21 -48
- package/examples/bootstrap.js +16 -74
- package/examples/mcp-example.js +6 -29
- package/examples/skill-example.js +6 -19
- package/examples/workflow.js +8 -56
- package/package.json +8 -4
- package/plugins/README.md +49 -0
- package/plugins/{ambient-agent → ambient}/EventWatcher.js +1 -1
- package/plugins/{ambient-agent → ambient}/ExplorerLoop.js +3 -3
- package/plugins/{ambient-agent → ambient}/GoalManager.js +2 -2
- package/plugins/ambient/README.md +14 -0
- package/plugins/{ambient-agent → ambient}/Reflector.js +1 -1
- package/plugins/{ambient-agent → ambient}/StateStore.js +1 -1
- package/plugins/{ambient-agent → ambient}/index.js +2 -2
- package/plugins/{ai-plugin.js → core/ai/index.js} +14 -30
- package/plugins/{audit-plugin.js → core/audit/index.js} +3 -30
- package/plugins/{coordinator-plugin.js → core/coordinator/index.js} +3 -35
- package/plugins/core/default/bootstrap.js +224 -0
- package/plugins/core/default/config.js +222 -0
- package/plugins/core/default/index.js +58 -0
- package/plugins/core/mcp/index.js +1 -0
- package/plugins/{python-plugin-loader.js → core/python-loader/index.js} +7 -187
- package/plugins/{rules-plugin.js → core/rules/index.js} +121 -64
- package/plugins/{scheduler-plugin.js → core/scheduler/index.js} +12 -114
- package/plugins/{session-plugin.js → core/session/index.js} +9 -73
- package/{src/capabilities/skill-manager.js → plugins/core/skill-manager/index.js} +64 -18
- package/plugins/{storage-plugin.js → core/storage/index.js} +5 -29
- package/plugins/{subagent-plugin.js → core/sub-agent/index.js} +10 -171
- package/plugins/{think-plugin.js → core/think/index.js} +24 -91
- package/{src/capabilities/workflow-engine.js → plugins/core/workflow/index.js} +87 -85
- package/plugins/default-plugins.js +6 -720
- package/plugins/{data-splitter-plugin.js → executors/data-splitter/index.js} +9 -83
- package/plugins/{extension-executor-plugin.js → executors/extension/index.js} +13 -97
- package/plugins/{python-executor-plugin.js → executors/python/index.js} +6 -31
- package/plugins/{shell-executor-plugin.js → executors/shell/index.js} +2 -5
- package/plugins/install/README.md +9 -0
- package/plugins/{install-plugin.js → install/index.js} +3 -3
- package/plugins/{file-system-plugin.js → io/file-system/index.js} +34 -236
- package/plugins/{web-plugin.js → io/web/index.js} +11 -113
- package/plugins/memory/README.md +13 -0
- package/plugins/{memory-plugin.js → memory/index.js} +4 -18
- package/plugins/messaging/email/README.md +19 -0
- package/plugins/{email → messaging/email}/index.js +3 -3
- package/plugins/{feishu-plugin.js → messaging/feishu/index.js} +4 -4
- package/plugins/{qq-plugin.js → messaging/qq/index.js} +6 -17
- package/plugins/{telegram-plugin.js → messaging/telegram/index.js} +4 -4
- package/plugins/{weixin-plugin.js → messaging/weixin/index.js} +16 -16
- package/plugins/{plugin-manager-plugin.js → plugin-manager/index.js} +36 -180
- package/plugins/{tools-plugin.js → tools/index.js} +68 -116
- package/plugins/trading/README.md +15 -0
- package/plugins/{gate-trading.js → trading/index.js} +8 -8
- package/{examples → sandbox}/test-concurrent-chat.js +2 -2
- package/{examples → sandbox}/test-long-chat.js +2 -2
- package/{examples → sandbox}/test-session-chat.js +2 -2
- package/{examples → sandbox}/test-web-plugin.js +1 -1
- package/{examples → sandbox}/test-weixin-feishu.js +2 -2
- package/src/agent/base.js +56 -0
- package/src/{core/agent-chat.js → agent/chat.js} +11 -11
- package/src/{core/coordinator-manager.js → agent/coordinator.js} +3 -3
- package/src/agent/index.js +111 -0
- package/src/agent/main.js +337 -0
- package/src/agent/prompt.js +78 -0
- package/src/agent/sub.js +198 -0
- package/src/agent/worker.js +104 -0
- package/{cli/bin/foliko.js → src/cli/bin.js} +1 -1
- package/{cli/src → src/cli}/commands/chat.js +25 -21
- package/{cli/src → src/cli}/index.js +1 -0
- package/{cli/src → src/cli}/ui/chat-ui-old.js +40 -178
- package/{cli/src → src/cli}/ui/chat-ui.js +3 -3
- package/{cli/src → src/cli}/ui/components/footer-bar.js +1 -1
- package/src/common/errors.js +402 -0
- package/src/{utils → common}/logger.js +33 -0
- package/src/{utils/chat-queue.js → common/queue.js} +2 -2
- package/src/config/plugin-config.js +50 -0
- package/src/context/agent.js +32 -0
- package/src/context/compaction-prompts.js +170 -0
- package/src/context/compaction-utils.js +191 -0
- package/src/context/compressor.js +413 -0
- package/src/context/index.js +9 -0
- package/src/{core/context-manager.js → context/manager.js} +1 -1
- package/src/context/request.js +50 -0
- package/src/context/session.js +33 -0
- package/src/context/storage.js +30 -0
- package/src/executors/mcp-client.js +153 -0
- package/src/executors/mcp-desc.js +236 -0
- package/src/executors/mcp-executor.js +91 -956
- package/src/{core → framework}/command-registry.js +1 -1
- package/src/framework/framework.js +300 -0
- package/src/framework/index.js +18 -0
- package/src/framework/lifecycle.js +203 -0
- package/src/framework/loader.js +78 -0
- package/src/framework/registry.js +86 -0
- package/src/{core/ui-extension-context.js → framework/ui-extension.js} +1 -1
- package/src/index.js +130 -15
- package/src/llm/index.js +26 -0
- package/src/llm/provider.js +212 -0
- package/src/llm/registry.js +11 -0
- package/src/{core/token-counter.js → llm/tokens.js} +4 -37
- package/src/{core/plugin-base.js → plugin/base.js} +10 -136
- package/src/plugin/index.js +14 -0
- package/src/plugin/loader.js +101 -0
- package/src/plugin/manager.js +484 -0
- package/src/{core → session}/branch-summary-auto.js +2 -2
- package/src/{core/chat-session.js → session/chat.js} +2 -2
- package/src/session/index.js +7 -0
- package/src/{core/session-manager.js → session/session.js} +2 -2
- package/src/session/ttl.js +92 -0
- package/src/{core/jsonl-storage.js → storage/jsonl.js} +1 -1
- package/src/tool/executor.js +85 -0
- package/src/tool/index.js +15 -0
- package/src/tool/registry.js +143 -0
- package/src/{core/tool-router.js → tool/router.js} +17 -124
- package/src/tool/schema.js +108 -0
- package/src/utils/data-splitter.js +1 -1
- package/src/utils/download.js +1 -1
- package/src/utils/index.js +6 -6
- package/src/utils/message-validator.js +1 -1
- package/tests/core/context-storage.test.js +46 -0
- package/tests/core/llm.test.js +54 -0
- package/tests/core/plugin.test.js +42 -0
- package/tests/core/tool.test.js +60 -0
- package/tests/setup.js +10 -0
- package/tests/smoke.test.js +58 -0
- package/vitest.config.js +9 -0
- package/cli/src/daemon.js +0 -149
- package/docs/CONTEXT_DESIGN.md +0 -1596
- package/docs/ai-sdk-optimization.md +0 -655
- package/docs/features.md +0 -120
- package/docs/qq-bot.md +0 -976
- package/docs/quick-reference.md +0 -160
- package/docs/user-manual.md +0 -1391
- package/images/geometric_shapes.jpg +0 -0
- package/images/sunset_mountain_lake.jpg +0 -0
- package/skills/poster-guide/SKILL.md +0 -792
- package/src/capabilities/index.js +0 -11
- package/src/core/agent.js +0 -808
- package/src/core/context-compressor.js +0 -959
- package/src/core/enhanced-context-compressor.js +0 -210
- package/src/core/framework.js +0 -1422
- package/src/core/index.js +0 -30
- package/src/core/plugin-manager.js +0 -961
- package/src/core/provider-registry.js +0 -159
- package/src/core/provider.js +0 -156
- package/src/core/request-context.js +0 -98
- package/src/core/subagent.js +0 -442
- package/src/core/system-prompt-builder.js +0 -120
- package/src/core/tool-executor.js +0 -202
- package/src/core/tool-registry.js +0 -517
- package/src/core/worker-agent.js +0 -192
- package/src/executors/executor-base.js +0 -58
- package/src/utils/error-boundary.js +0 -363
- package/src/utils/error.js +0 -374
- package/system.md +0 -1645
- package/website_v2/README.md +0 -57
- package/website_v2/SPEC.md +0 -1
- package/website_v2/docs/api.html +0 -128
- package/website_v2/docs/configuration.html +0 -147
- package/website_v2/docs/plugin-development.html +0 -129
- package/website_v2/docs/project-structure.html +0 -89
- package/website_v2/docs/skill-development.html +0 -85
- package/website_v2/index.html +0 -489
- package/website_v2/scripts/main.js +0 -93
- package/website_v2/styles/animations.css +0 -8
- package/website_v2/styles/docs.css +0 -83
- package/website_v2/styles/main.css +0 -417
- package/xhs_auth.json +0 -268
- package//346/265/267/346/212/245/346/217/222/344/273/266.md +0 -621
- /package/plugins/{ambient-agent → ambient}/constants.js +0 -0
- /package/plugins/{email → messaging/email}/constants.js +0 -0
- /package/plugins/{email → messaging/email}/handlers.js +0 -0
- /package/plugins/{email → messaging/email}/monitor.js +0 -0
- /package/plugins/{email → messaging/email}/parser.js +0 -0
- /package/plugins/{email → messaging/email}/reply.js +0 -0
- /package/plugins/{email → messaging/email}/utils.js +0 -0
- /package/{examples → sandbox}/test-chat.js +0 -0
- /package/{examples → sandbox}/test-mcp.js +0 -0
- /package/{examples → sandbox}/test-reload.js +0 -0
- /package/{examples → sandbox}/test-telegram.js +0 -0
- /package/{examples → sandbox}/test-tg-bot.js +0 -0
- /package/{examples → sandbox}/test-tg-simple.js +0 -0
- /package/{examples → sandbox}/test-tg.js +0 -0
- /package/{examples → sandbox}/test-think.js +0 -0
- /package/src/{core/sub-agent-config.js → agent/sub-config.js} +0 -0
- /package/{cli/src → src/cli}/commands/daemon.js +0 -0
- /package/{cli/src → src/cli}/commands/list.js +0 -0
- /package/{cli/src → src/cli}/commands/plugin.js +0 -0
- /package/{cli/src → src/cli}/ui/components/agent-mention-provider.js +0 -0
- /package/{cli/src → src/cli}/ui/components/chained-autocomplete-provider.js +0 -0
- /package/{cli/src → src/cli}/ui/components/message-bubble.js +0 -0
- /package/{cli/src → src/cli}/ui/components/status-bar.js +0 -0
- /package/{cli/src → src/cli}/utils/ansi.js +0 -0
- /package/{cli/src → src/cli}/utils/config.js +0 -0
- /package/{cli/src → src/cli}/utils/markdown.js +0 -0
- /package/{cli/src → src/cli}/utils/plugin-config.js +0 -0
- /package/{cli/src → src/cli}/utils/render-diff.js +0 -0
- /package/src/{utils/circuit-breaker.js → common/circuit.js} +0 -0
- /package/src/{core → common}/constants.js +0 -0
- /package/src/{utils/edit-diff.js → common/diff.js} +0 -0
- /package/src/{utils/event-emitter.js → common/events.js} +0 -0
- /package/src/{utils → common}/id.js +0 -0
- /package/src/{utils → common}/retry.js +0 -0
- /package/src/{core/notification-manager.js → notification/manager.js} +0 -0
- /package/src/{core/session-entry.js → session/entry.js} +0 -0
- /package/src/{core/storage-manager.js → storage/manager.js} +0 -0
package/examples/workflow.js
CHANGED
|
@@ -3,21 +3,18 @@
|
|
|
3
3
|
* 展示如何使用工作流引擎
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
const
|
|
7
|
-
const { WorkflowPlugin } = require('../
|
|
6
|
+
const foliko = require('../src');
|
|
7
|
+
const { WorkflowPlugin } = require('../plugins/core/workflow');
|
|
8
8
|
|
|
9
9
|
async function main() {
|
|
10
10
|
console.log('=== Workflow Example ===\n');
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
const framework = new Framework({ debug: true });
|
|
12
|
+
const framework = foliko.createApp({ debug: true });
|
|
14
13
|
|
|
15
14
|
// 加载工作流插件
|
|
16
15
|
await framework.loadPlugin(new WorkflowPlugin());
|
|
17
16
|
|
|
18
17
|
console.log('\n--- Testing Script Step ---');
|
|
19
|
-
|
|
20
|
-
// 直接执行工作流
|
|
21
18
|
const result1 = await framework.executeTool('execute_workflow', {
|
|
22
19
|
workflow: JSON.stringify({
|
|
23
20
|
steps: [
|
|
@@ -44,11 +41,9 @@ async function main() {
|
|
|
44
41
|
}),
|
|
45
42
|
input: {},
|
|
46
43
|
});
|
|
47
|
-
|
|
48
44
|
console.log('Result:', result1);
|
|
49
45
|
|
|
50
46
|
console.log('\n--- Testing Loop Step ---');
|
|
51
|
-
|
|
52
47
|
const result2 = await framework.executeTool('execute_workflow', {
|
|
53
48
|
workflow: JSON.stringify({
|
|
54
49
|
steps: [
|
|
@@ -61,10 +56,7 @@ async function main() {
|
|
|
61
56
|
{
|
|
62
57
|
type: 'script',
|
|
63
58
|
name: 'Log iteration',
|
|
64
|
-
script: `
|
|
65
|
-
console.log('Iteration ' + context.variables.i);
|
|
66
|
-
return context.variables.i;
|
|
67
|
-
`,
|
|
59
|
+
script: `console.log('Iteration ' + context.variables.i); return context.variables.i;`,
|
|
68
60
|
},
|
|
69
61
|
],
|
|
70
62
|
},
|
|
@@ -72,11 +64,9 @@ async function main() {
|
|
|
72
64
|
}),
|
|
73
65
|
input: {},
|
|
74
66
|
});
|
|
75
|
-
|
|
76
67
|
console.log('Result:', result2);
|
|
77
68
|
|
|
78
69
|
console.log('\n--- Testing Condition Step ---');
|
|
79
|
-
|
|
80
70
|
const result3 = await framework.executeTool('execute_workflow', {
|
|
81
71
|
workflow: JSON.stringify({
|
|
82
72
|
steps: [
|
|
@@ -84,10 +74,7 @@ async function main() {
|
|
|
84
74
|
type: 'script',
|
|
85
75
|
name: 'Set value',
|
|
86
76
|
outputVariable: 'value',
|
|
87
|
-
script: `
|
|
88
|
-
context.variables.value = 15;
|
|
89
|
-
return 15;
|
|
90
|
-
`,
|
|
77
|
+
script: `context.variables.value = 15; return 15;`,
|
|
91
78
|
},
|
|
92
79
|
{
|
|
93
80
|
type: 'condition',
|
|
@@ -97,22 +84,14 @@ async function main() {
|
|
|
97
84
|
name: 'Greater than 10',
|
|
98
85
|
condition: 'context.variables.value > 10',
|
|
99
86
|
steps: [
|
|
100
|
-
{
|
|
101
|
-
type: 'script',
|
|
102
|
-
name: 'Log greater',
|
|
103
|
-
script: `console.log('Value is greater than 10'); return 'greater';`,
|
|
104
|
-
},
|
|
87
|
+
{ type: 'script', name: 'Log greater', script: `console.log('Value is greater than 10'); return 'greater';` },
|
|
105
88
|
],
|
|
106
89
|
},
|
|
107
90
|
{
|
|
108
91
|
name: 'Less than or equal 10',
|
|
109
92
|
condition: 'context.variables.value <= 10',
|
|
110
93
|
steps: [
|
|
111
|
-
{
|
|
112
|
-
type: 'script',
|
|
113
|
-
name: 'Log less',
|
|
114
|
-
script: `console.log('Value is less than or equal 10'); return 'less-or-equal';`,
|
|
115
|
-
},
|
|
94
|
+
{ type: 'script', name: 'Log less', script: `console.log('Value is less than or equal 10'); return 'less-or-equal';` },
|
|
116
95
|
],
|
|
117
96
|
},
|
|
118
97
|
],
|
|
@@ -121,37 +100,10 @@ async function main() {
|
|
|
121
100
|
}),
|
|
122
101
|
input: {},
|
|
123
102
|
});
|
|
124
|
-
|
|
125
103
|
console.log('Result:', result3);
|
|
126
104
|
|
|
127
|
-
console.log('\n--- Testing Delay ---');
|
|
128
|
-
|
|
129
|
-
const startTime = Date.now();
|
|
130
|
-
const result4 = await framework.executeTool('execute_workflow', {
|
|
131
|
-
workflow: JSON.stringify({
|
|
132
|
-
steps: [
|
|
133
|
-
{
|
|
134
|
-
type: 'delay',
|
|
135
|
-
name: 'Wait 500ms',
|
|
136
|
-
delayMs: 500,
|
|
137
|
-
},
|
|
138
|
-
{
|
|
139
|
-
type: 'script',
|
|
140
|
-
name: 'Check elapsed',
|
|
141
|
-
script: `
|
|
142
|
-
const elapsed = Date.now() - context.variables.startTime;
|
|
143
|
-
return { elapsed: elapsed, expected: 500 };
|
|
144
|
-
`,
|
|
145
|
-
},
|
|
146
|
-
],
|
|
147
|
-
}),
|
|
148
|
-
input: {},
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
console.log('Result:', result4);
|
|
152
|
-
|
|
153
105
|
// 清理
|
|
154
|
-
await
|
|
106
|
+
await foliko.destroy(framework);
|
|
155
107
|
console.log('\n[Done]');
|
|
156
108
|
}
|
|
157
109
|
|
package/package.json
CHANGED
|
@@ -1,19 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "foliko",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"description": "简约的插件化 Agent 框架",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"type": "commonjs",
|
|
7
7
|
"bin": {
|
|
8
|
-
"foliko": "./cli/bin
|
|
8
|
+
"foliko": "./src/cli/bin.js"
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
11
|
"start": "node examples/basic.js",
|
|
12
|
-
"chat": "node cli/bin
|
|
12
|
+
"chat": "node src/cli/bin.js chat",
|
|
13
|
+
"chat:old": "node src/cli/bin.js chat --old",
|
|
13
14
|
"dev": "node --watch examples/basic.js",
|
|
14
15
|
"lint": "echo \"No linter configured\"",
|
|
15
16
|
"format": "prettier --write \"**/*.{js,jsx,ts,tsx,json,yaml,yml,md,css,html}\"",
|
|
16
17
|
"format:check": "prettier --check \"**/*.{js,jsx,ts,tsx,json,yaml,yml,md,css,html}\"",
|
|
18
|
+
"test": "vitest run",
|
|
19
|
+
"test:watch": "vitest",
|
|
17
20
|
"prepare": "husky"
|
|
18
21
|
},
|
|
19
22
|
"lint-staged": {
|
|
@@ -90,6 +93,7 @@
|
|
|
90
93
|
"devDependencies": {
|
|
91
94
|
"husky": "^9.1.7",
|
|
92
95
|
"lint-staged": "^16.4.0",
|
|
93
|
-
"prettier": "^3.8.1"
|
|
96
|
+
"prettier": "^3.8.1",
|
|
97
|
+
"vitest": "^4.1.9"
|
|
94
98
|
}
|
|
95
99
|
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Foliko 内置插件
|
|
2
|
+
|
|
3
|
+
插件按职能分组:
|
|
4
|
+
|
|
5
|
+
## `core/` 核心插件
|
|
6
|
+
- **ai** - AI 对话能力
|
|
7
|
+
- **default** - 默认插件加载与 bootstrap 配置
|
|
8
|
+
- **tool-manager** - 工具管理
|
|
9
|
+
- **plugin-manager** - 远程插件管理
|
|
10
|
+
- **session** - 多会话管理
|
|
11
|
+
- **sub-agent** - 子 Agent 管理
|
|
12
|
+
- **coordinator** - Coordinator 模式
|
|
13
|
+
- **scheduler** - 定时任务调度
|
|
14
|
+
- **skill-manager** - 技能管理
|
|
15
|
+
- **workflow** - 工作流引擎
|
|
16
|
+
- **mcp** - MCP 协议集成
|
|
17
|
+
- **storage** - 键值存储
|
|
18
|
+
- **audit** - 审计日志
|
|
19
|
+
- **rules** - 权限/内容规则
|
|
20
|
+
- **think** - 主动思考
|
|
21
|
+
|
|
22
|
+
## `executors/` 执行器
|
|
23
|
+
- **shell** - Shell 命令执行
|
|
24
|
+
- **python** - Python 代码/脚本执行
|
|
25
|
+
- **extension** - 扩展插件执行器
|
|
26
|
+
- **data-splitter** - 大数据自动分拆
|
|
27
|
+
|
|
28
|
+
## `io/` 输入输出
|
|
29
|
+
- **file-system** - 文件系统操作
|
|
30
|
+
- **web** - HTTP 服务与 Webhook
|
|
31
|
+
|
|
32
|
+
## `messaging/` 消息集成
|
|
33
|
+
- **email** - SMTP/IMAP 邮件
|
|
34
|
+
- **telegram** - Telegram 机器人
|
|
35
|
+
- **qq** - QQ 机器人
|
|
36
|
+
- **weixin** - 微信机器人
|
|
37
|
+
- **feishu** - 飞书机器人
|
|
38
|
+
|
|
39
|
+
## `memory/` 记忆
|
|
40
|
+
- **memory-plugin** - 四层记忆系统
|
|
41
|
+
|
|
42
|
+
## `ambient/` Ambient Agent
|
|
43
|
+
- **ambient-agent** - 持续后台运行
|
|
44
|
+
|
|
45
|
+
## `install/` 安装
|
|
46
|
+
- **install-plugin** - npm 包自动安装
|
|
47
|
+
|
|
48
|
+
## `trading/` 交易
|
|
49
|
+
- **gate-trading** - Gate.io API 交易
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
* ExplorerLoop - 主自主循环,决定并执行操作
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
const { Plugin } = require('../../src/
|
|
6
|
-
const { logger } = require('../../src/
|
|
7
|
-
const { StepExecutor } = require('../../
|
|
5
|
+
const { Plugin } = require('../../src/plugin/base')
|
|
6
|
+
const { logger } = require('../../src/common/logger')
|
|
7
|
+
const { StepExecutor } = require('../../plugins/core/workflow')
|
|
8
8
|
const { SystemPrompts, ThinkModePrompts, FreeThinkPrompts } = require('./constants')
|
|
9
9
|
|
|
10
10
|
const log = logger.child('Ambient:ExplorerLoop')
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
* GoalManager - 管理目标及其生命周期状态
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
const { logger } = require('../../src/
|
|
5
|
+
const { logger } = require('../../src/common/logger')
|
|
6
6
|
const { GoalState } = require('./constants')
|
|
7
|
-
const { generateId } = require('../../src/
|
|
7
|
+
const { generateId } = require('../../src/common/id')
|
|
8
8
|
|
|
9
9
|
const log = logger.child('Ambient:GoalManager')
|
|
10
10
|
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
* 持续后台运行的智能代理,监控事件并主动执行操作
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
const { Plugin } = require('../../src/
|
|
7
|
-
const { logger } = require('../../src/
|
|
6
|
+
const { Plugin } = require('../../src/plugin/base')
|
|
7
|
+
const { logger } = require('../../src/common/logger')
|
|
8
8
|
const { z } = require('zod')
|
|
9
9
|
|
|
10
10
|
// 导入子模块
|
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
* 提供 AI 对话能力
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
const { Plugin } = require('
|
|
7
|
-
const { logger } = require('
|
|
6
|
+
const { Plugin } = require('../../../src/plugin/base')
|
|
7
|
+
const { logger } = require('../../../src/common/logger')
|
|
8
8
|
const log = logger.child('AIPlugin')
|
|
9
|
-
const {
|
|
9
|
+
const { LLMProvider } = require('../../../src/llm/provider')
|
|
10
10
|
|
|
11
11
|
class AIPlugin extends Plugin {
|
|
12
12
|
constructor(config = {}) {
|
|
@@ -14,8 +14,8 @@ class AIPlugin extends Plugin {
|
|
|
14
14
|
this.name = 'ai'
|
|
15
15
|
this.version = '1.0.0'
|
|
16
16
|
this.description = 'AI 对话能力插件'
|
|
17
|
-
this.priority = 1
|
|
18
|
-
this.system = true
|
|
17
|
+
this.priority = 1
|
|
18
|
+
this.system = true
|
|
19
19
|
|
|
20
20
|
this.config = {
|
|
21
21
|
provider: config.provider || 'deepseek',
|
|
@@ -23,9 +23,10 @@ class AIPlugin extends Plugin {
|
|
|
23
23
|
apiKey: config.apiKey,
|
|
24
24
|
baseURL: config.baseURL,
|
|
25
25
|
maxSteps: config.maxSteps || 20,
|
|
26
|
-
maxOutputTokens:config.maxOutputTokens||parseInt(process.env.MAX_OUTPUT_TOKENS)||8192
|
|
26
|
+
maxOutputTokens: config.maxOutputTokens || parseInt(process.env.MAX_OUTPUT_TOKENS) || 8192,
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
this._llmProvider = null
|
|
29
30
|
this._aiClient = null
|
|
30
31
|
this._framework = null
|
|
31
32
|
}
|
|
@@ -37,63 +38,46 @@ class AIPlugin extends Plugin {
|
|
|
37
38
|
}
|
|
38
39
|
|
|
39
40
|
start(framework) {
|
|
40
|
-
// AI client 已在 install 中初始化
|
|
41
41
|
return this
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
_initAIClient() {
|
|
45
|
-
|
|
46
45
|
if (!this.config.apiKey) {
|
|
47
46
|
log.warn(' No API key provided, AI features disabled')
|
|
48
47
|
return
|
|
49
48
|
}
|
|
50
49
|
try {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
model: this.config.model,
|
|
54
|
-
apiKey: this.config.apiKey,
|
|
55
|
-
baseURL: this.config.baseURL
|
|
56
|
-
})
|
|
57
|
-
|
|
58
|
-
// 创建模型实例
|
|
59
|
-
this._aiClient = provider(this.config.model)
|
|
60
|
-
//log.info(` Initialized ${this.config.provider}/${this.config.model}`)
|
|
50
|
+
this._llmProvider = new LLMProvider(this.config)
|
|
51
|
+
this._aiClient = this._llmProvider.createModel()
|
|
61
52
|
} catch (err) {
|
|
62
53
|
log.error(' Failed to initialize AI client:', err.message)
|
|
63
54
|
}
|
|
64
55
|
}
|
|
65
56
|
|
|
66
|
-
/**
|
|
67
|
-
* 获取 AI 客户端
|
|
68
|
-
* @returns {Object} AI 模型客户端
|
|
69
|
-
*/
|
|
70
57
|
getAIClient() {
|
|
71
58
|
return this._aiClient
|
|
72
59
|
}
|
|
73
60
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
61
|
+
getLLMProvider() {
|
|
62
|
+
return this._llmProvider
|
|
63
|
+
}
|
|
64
|
+
|
|
78
65
|
getConfig() {
|
|
79
66
|
return { ...this.config }
|
|
80
67
|
}
|
|
81
68
|
|
|
82
69
|
reload(framework) {
|
|
83
|
-
//log.info(' Reloading...')
|
|
84
70
|
this._framework = framework
|
|
85
71
|
this._initAIClient()
|
|
86
|
-
|
|
87
|
-
// 刷新所有已有 Agent 的 AI client
|
|
88
72
|
for (const agent of framework._agents || []) {
|
|
89
73
|
if (agent._chatHandler) {
|
|
90
74
|
agent._chatHandler.setAIClient(this._aiClient)
|
|
91
|
-
//log.info(` Refreshed AI client for agent: ${agent.name}`)
|
|
92
75
|
}
|
|
93
76
|
}
|
|
94
77
|
}
|
|
95
78
|
|
|
96
79
|
uninstall(framework) {
|
|
80
|
+
this._llmProvider = null
|
|
97
81
|
this._aiClient = null
|
|
98
82
|
this._framework = null
|
|
99
83
|
}
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* 基于 Pino 日志系统
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
const { Plugin } = require('
|
|
8
|
-
const { logger } = require('
|
|
7
|
+
const { Plugin } = require('../../../src/plugin/base')
|
|
8
|
+
const { logger } = require('../../../src/common/logger')
|
|
9
9
|
const { z } = require('zod')
|
|
10
10
|
const path = require('path')
|
|
11
11
|
const fs = require('fs')
|
|
@@ -30,29 +30,22 @@ class AuditPlugin extends Plugin {
|
|
|
30
30
|
this._logIdCounter = 0
|
|
31
31
|
this._auditLogger = null
|
|
32
32
|
this._auditLogFile = null
|
|
33
|
-
this._queryLogs = []
|
|
33
|
+
this._queryLogs = []
|
|
34
34
|
this._initAuditLogger()
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
/**
|
|
38
|
-
* 初始化审计日志器
|
|
39
|
-
*/
|
|
40
37
|
_initAuditLogger() {
|
|
41
38
|
const pino = require('pino')
|
|
42
39
|
|
|
43
|
-
// 确保目录存在
|
|
44
40
|
if (!fs.existsSync(this.config.logDir)) {
|
|
45
41
|
fs.mkdirSync(this.config.logDir, { recursive: true })
|
|
46
42
|
}
|
|
47
43
|
|
|
48
|
-
// 审计日志文件名
|
|
49
44
|
const date = new Date().toISOString().split('T')[0]
|
|
50
45
|
this._auditLogFile = path.join(this.config.logDir, `audit-${date}.jsonl`)
|
|
51
46
|
|
|
52
|
-
// 创建文件写入流
|
|
53
47
|
const fileStream = fs.createWriteStream(this._auditLogFile, { flags: 'a' })
|
|
54
48
|
|
|
55
|
-
// 创建专门的审计 logger
|
|
56
49
|
this._auditLogger = pino({
|
|
57
50
|
name: 'audit',
|
|
58
51
|
level: 'info',
|
|
@@ -66,7 +59,6 @@ class AuditPlugin extends Plugin {
|
|
|
66
59
|
install(framework) {
|
|
67
60
|
this._framework = framework
|
|
68
61
|
|
|
69
|
-
// 监听框架事件
|
|
70
62
|
framework.on('tool:call', (data) => this._log('tool_call', data))
|
|
71
63
|
framework.on('tool-call', (data) => this._log('tool_call', data))
|
|
72
64
|
framework.on('tool:result', (data) => this._log('tool_result', data))
|
|
@@ -77,7 +69,6 @@ class AuditPlugin extends Plugin {
|
|
|
77
69
|
}
|
|
78
70
|
|
|
79
71
|
start(framework) {
|
|
80
|
-
// 注册审计查询工具
|
|
81
72
|
framework.registerTool({
|
|
82
73
|
name: 'audit_query',
|
|
83
74
|
description: '查询审计日志',
|
|
@@ -146,9 +137,6 @@ class AuditPlugin extends Plugin {
|
|
|
146
137
|
return this
|
|
147
138
|
}
|
|
148
139
|
|
|
149
|
-
/**
|
|
150
|
-
* 记录日志
|
|
151
|
-
*/
|
|
152
140
|
_log(type, data) {
|
|
153
141
|
const log = {
|
|
154
142
|
id: ++this._logIdCounter,
|
|
@@ -157,7 +145,6 @@ class AuditPlugin extends Plugin {
|
|
|
157
145
|
timestamp: new Date().toISOString()
|
|
158
146
|
}
|
|
159
147
|
|
|
160
|
-
// 写入审计日志文件
|
|
161
148
|
if (this._auditLogger) {
|
|
162
149
|
this._auditLogger.info({
|
|
163
150
|
auditId: log.id,
|
|
@@ -166,10 +153,8 @@ class AuditPlugin extends Plugin {
|
|
|
166
153
|
}, 'audit event')
|
|
167
154
|
}
|
|
168
155
|
|
|
169
|
-
// 缓存到内存用于查询
|
|
170
156
|
this._queryLogs.push(log)
|
|
171
157
|
|
|
172
|
-
// 限制缓存数量
|
|
173
158
|
if (this._queryLogs.length > this.config.maxLogs) {
|
|
174
159
|
this._queryLogs = this._queryLogs.slice(-this.config.maxLogs)
|
|
175
160
|
}
|
|
@@ -177,9 +162,6 @@ class AuditPlugin extends Plugin {
|
|
|
177
162
|
return log
|
|
178
163
|
}
|
|
179
164
|
|
|
180
|
-
/**
|
|
181
|
-
* 获取统计信息
|
|
182
|
-
*/
|
|
183
165
|
getStats() {
|
|
184
166
|
const counts = {}
|
|
185
167
|
for (const log of this._queryLogs) {
|
|
@@ -196,18 +178,13 @@ class AuditPlugin extends Plugin {
|
|
|
196
178
|
}
|
|
197
179
|
}
|
|
198
180
|
|
|
199
|
-
/**
|
|
200
|
-
* 导出日志
|
|
201
|
-
*/
|
|
202
181
|
exportLogs(options = {}) {
|
|
203
182
|
let logs = [...this._queryLogs]
|
|
204
183
|
|
|
205
|
-
// 按类型过滤
|
|
206
184
|
if (options.type) {
|
|
207
185
|
logs = logs.filter(log => log.type === options.type)
|
|
208
186
|
}
|
|
209
187
|
|
|
210
|
-
// 按日期过滤
|
|
211
188
|
if (options.startDate) {
|
|
212
189
|
const start = new Date(options.startDate)
|
|
213
190
|
logs = logs.filter(log => new Date(log.timestamp) >= start)
|
|
@@ -221,9 +198,6 @@ class AuditPlugin extends Plugin {
|
|
|
221
198
|
return { logs }
|
|
222
199
|
}
|
|
223
200
|
|
|
224
|
-
/**
|
|
225
|
-
* 手动记录日志
|
|
226
|
-
*/
|
|
227
201
|
log(type, data) {
|
|
228
202
|
return this._log(type, data)
|
|
229
203
|
}
|
|
@@ -235,7 +209,6 @@ class AuditPlugin extends Plugin {
|
|
|
235
209
|
uninstall(framework) {
|
|
236
210
|
this._queryLogs = []
|
|
237
211
|
if (this._auditLogger) {
|
|
238
|
-
// 关闭文件流
|
|
239
212
|
}
|
|
240
213
|
this._auditLogger = null
|
|
241
214
|
this._framework = null
|
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
* - list_workers: 列出Worker
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
const { Plugin } = require('
|
|
10
|
+
const { Plugin } = require('../../../src/plugin/base');
|
|
11
11
|
const { z } = require('zod');
|
|
12
|
-
const { logger } = require('
|
|
12
|
+
const { logger } = require('../../../src/common/logger');
|
|
13
13
|
|
|
14
14
|
const log = logger.child('CoordinatorPlugin');
|
|
15
15
|
|
|
@@ -33,24 +33,17 @@ class CoordinatorPlugin extends Plugin {
|
|
|
33
33
|
start(framework) {
|
|
34
34
|
this._framework = framework;
|
|
35
35
|
|
|
36
|
-
// 初始化CoordinatorManager(如果尚未初始化)
|
|
37
36
|
if (!framework._coordinatorManager) {
|
|
38
|
-
// framework.initCoordinatorManager 会创建并设置
|
|
39
37
|
}
|
|
40
38
|
|
|
41
|
-
// 获取主Agent作为默认的Coordinator
|
|
42
39
|
const mainAgent = framework._mainAgent;
|
|
43
40
|
if (mainAgent) {
|
|
44
|
-
// 初始化CoordinatorManager并传入coordinatorAgent
|
|
45
41
|
framework.initCoordinatorManager(mainAgent);
|
|
46
42
|
|
|
47
|
-
// 注册Coordinator工具到主Agent
|
|
48
43
|
this.registerTools(mainAgent);
|
|
49
44
|
|
|
50
|
-
// 注册系统提示词部分,让Agent知道如何使用Coordinator模式
|
|
51
45
|
this._registerCoordinatorPrompt(mainAgent);
|
|
52
46
|
|
|
53
|
-
// 监听Worker事件用于生成通知
|
|
54
47
|
this._setupWorkerEventListeners(framework);
|
|
55
48
|
|
|
56
49
|
log.debug(' Coordinator plugin initialized with main agent');
|
|
@@ -59,10 +52,6 @@ class CoordinatorPlugin extends Plugin {
|
|
|
59
52
|
return this;
|
|
60
53
|
}
|
|
61
54
|
|
|
62
|
-
/**
|
|
63
|
-
* 注册Coordinator模式提示词到Agent
|
|
64
|
-
* @private
|
|
65
|
-
*/
|
|
66
55
|
_registerCoordinatorPrompt(agent) {
|
|
67
56
|
if (!agent || typeof agent.registerPromptPart !== 'function' || !this.enabled) {
|
|
68
57
|
return;
|
|
@@ -91,45 +80,28 @@ class CoordinatorPlugin extends Plugin {
|
|
|
91
80
|
`);
|
|
92
81
|
}
|
|
93
82
|
|
|
94
|
-
/**
|
|
95
|
-
* 设置Worker事件监听器
|
|
96
|
-
* @private
|
|
97
|
-
*/
|
|
98
83
|
_setupWorkerEventListeners(framework) {
|
|
99
84
|
const coordinatorManager = framework.getCoordinatorManager();
|
|
100
85
|
if (!coordinatorManager) return;
|
|
101
86
|
|
|
102
|
-
// 监听Worker完成事件
|
|
103
87
|
coordinatorManager.on('worker:completed', (data) => {
|
|
104
|
-
// 通知会被发送到Coordinator Agent的事件队列
|
|
105
88
|
framework.emit('coordinator:worker-completed', data);
|
|
106
89
|
});
|
|
107
90
|
|
|
108
|
-
// 监听Worker错误事件
|
|
109
91
|
coordinatorManager.on('worker:error', (data) => {
|
|
110
92
|
framework.emit('coordinator:worker-error', data);
|
|
111
93
|
});
|
|
112
94
|
|
|
113
|
-
// 监听Worker停止事件
|
|
114
95
|
coordinatorManager.on('worker:stopped', (data) => {
|
|
115
96
|
framework.emit('coordinator:worker-stopped', data);
|
|
116
97
|
});
|
|
117
98
|
}
|
|
118
99
|
|
|
119
|
-
/**
|
|
120
|
-
* 设置Coordinator Agent
|
|
121
|
-
* @param {Agent} agent - Coordinator Agent实例
|
|
122
|
-
*/
|
|
123
100
|
setCoordinatorAgent(agent) {
|
|
124
101
|
this._coordinatorAgent = agent;
|
|
125
102
|
}
|
|
126
103
|
|
|
127
|
-
/**
|
|
128
|
-
* 注册Coordinator工具到指定Agent
|
|
129
|
-
* @param {Agent} agent - Agent实例
|
|
130
|
-
*/
|
|
131
104
|
registerTools(agent) {
|
|
132
|
-
// spawn_worker - 创建Worker
|
|
133
105
|
agent.registerTool({
|
|
134
106
|
name: 'spawn_worker',
|
|
135
107
|
description: '创建一个独立的Worker Agent来执行任务。默认会等待Worker完成后再返回结果。',
|
|
@@ -151,7 +123,7 @@ class CoordinatorPlugin extends Plugin {
|
|
|
151
123
|
task: args.task,
|
|
152
124
|
systemPrompt: args.system_prompt,
|
|
153
125
|
tools: args.tools,
|
|
154
|
-
waitForCompletion: true,
|
|
126
|
+
waitForCompletion: true,
|
|
155
127
|
});
|
|
156
128
|
|
|
157
129
|
return {
|
|
@@ -171,7 +143,6 @@ class CoordinatorPlugin extends Plugin {
|
|
|
171
143
|
},
|
|
172
144
|
});
|
|
173
145
|
|
|
174
|
-
// send_message_to_worker - 继续Worker
|
|
175
146
|
agent.registerTool({
|
|
176
147
|
name: 'send_message_to_worker',
|
|
177
148
|
description: '向指定的Worker发送消息,继续其执行',
|
|
@@ -198,7 +169,6 @@ class CoordinatorPlugin extends Plugin {
|
|
|
198
169
|
},
|
|
199
170
|
});
|
|
200
171
|
|
|
201
|
-
// stop_worker - 停止Worker
|
|
202
172
|
agent.registerTool({
|
|
203
173
|
name: 'stop_worker',
|
|
204
174
|
description: '停止指定的Worker',
|
|
@@ -224,7 +194,6 @@ class CoordinatorPlugin extends Plugin {
|
|
|
224
194
|
},
|
|
225
195
|
});
|
|
226
196
|
|
|
227
|
-
// list_workers - 列出Worker
|
|
228
197
|
agent.registerTool({
|
|
229
198
|
name: 'list_workers',
|
|
230
199
|
description: '列出所有活跃的Worker',
|
|
@@ -244,7 +213,6 @@ class CoordinatorPlugin extends Plugin {
|
|
|
244
213
|
},
|
|
245
214
|
});
|
|
246
215
|
|
|
247
|
-
// get_worker - 获取Worker详情
|
|
248
216
|
agent.registerTool({
|
|
249
217
|
name: 'get_worker',
|
|
250
218
|
description: '获取指定Worker的详细信息',
|