foliko 1.1.72 → 1.1.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/.dockerignore +45 -45
- package/.env.example +56 -56
- package/docker-compose.yml +33 -33
- package/docs/features.md +120 -120
- package/docs/quick-reference.md +160 -160
- package/package.json +1 -1
- package/plugins/extension-executor-plugin.js +18 -44
- package/skills/find-skills/SKILL.md +133 -133
- package/skills/foliko-dev/AGENTS.md +236 -236
- package/skills/mcp-usage/SKILL.md +200 -200
- package/skills/subagent-guide/SKILL.md +237 -237
- package/skills/workflow-guide/SKILL.md +646 -646
- package/src/capabilities/skill-manager.js +58 -2
- package/website_v2/styles/animations.css +7 -7
package/docs/quick-reference.md
CHANGED
|
@@ -1,160 +1,160 @@
|
|
|
1
|
-
# Foliko 快速参考
|
|
2
|
-
|
|
3
|
-
## 启动框架
|
|
4
|
-
|
|
5
|
-
```javascript
|
|
6
|
-
const framework = new Framework({ debug: false });
|
|
7
|
-
await framework.bootstrap({
|
|
8
|
-
agentDir: './.foliko',
|
|
9
|
-
aiConfig: { provider: 'deepseek', model: 'deepseek-chat', apiKey: '...' },
|
|
10
|
-
});
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
## 创建 Agent
|
|
14
|
-
|
|
15
|
-
```javascript
|
|
16
|
-
const agent = framework.createAgent({
|
|
17
|
-
name: 'MyAgent',
|
|
18
|
-
systemPrompt: '你是一个有帮助的助手。',
|
|
19
|
-
});
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
## 发送消息
|
|
23
|
-
|
|
24
|
-
```javascript
|
|
25
|
-
// 流式
|
|
26
|
-
for await (const chunk of agent.chatStream('你好')) {
|
|
27
|
-
if (chunk.type === 'text') process.stdout.write(chunk.text);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// 非流式
|
|
31
|
-
const result = await agent.chat('你好');
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
## 常用工具
|
|
35
|
-
|
|
36
|
-
| 工具 | 用途 |
|
|
37
|
-
| ---------------------- | ------------ |
|
|
38
|
-
| `list_tools` | 列出所有工具 |
|
|
39
|
-
| `loadSkill` | 加载技能 |
|
|
40
|
-
| `reload_plugins` | 重载插件 |
|
|
41
|
-
| `read_file` | 读取文件 |
|
|
42
|
-
| `write_file` | 写入文件 |
|
|
43
|
-
| `execute_command` | 执行命令 |
|
|
44
|
-
| `schedule_once` | 定时任务 |
|
|
45
|
-
| `think_now` | 主动思考 |
|
|
46
|
-
| `email_send` | 发送邮件 |
|
|
47
|
-
| `email_read` | 读取邮件 |
|
|
48
|
-
| `enable_plugin` | 启用插件 |
|
|
49
|
-
| `disable_plugin` | 禁用插件 |
|
|
50
|
-
| `update_plugin_config` | 更新插件配置 |
|
|
51
|
-
|
|
52
|
-
## 插件位置
|
|
53
|
-
|
|
54
|
-
- 内置插件:`plugins/`
|
|
55
|
-
- 用户插件:`.foliko/plugins/`
|
|
56
|
-
|
|
57
|
-
## 插件管理
|
|
58
|
-
|
|
59
|
-
```javascript
|
|
60
|
-
// 重启插件
|
|
61
|
-
await framework.executeTool('reload_plugins', {});
|
|
62
|
-
await framework.executeTool('reload_plugins', { pluginName: 'telegram' });
|
|
63
|
-
|
|
64
|
-
// 启用/禁用插件
|
|
65
|
-
await framework.executeTool('enable_plugin', { name: 'telegram' });
|
|
66
|
-
await framework.executeTool('disable_plugin', { name: 'telegram' });
|
|
67
|
-
|
|
68
|
-
// 更新插件配置(持久化)
|
|
69
|
-
await framework.executeTool('update_plugin_config', {
|
|
70
|
-
name: 'telegram',
|
|
71
|
-
config: { allowedChats: ['123'], groupMode: true },
|
|
72
|
-
});
|
|
73
|
-
await framework.executeTool('get_plugin_config', { name: 'telegram' });
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
## 事件监听
|
|
77
|
-
|
|
78
|
-
```javascript
|
|
79
|
-
// Framework 事件
|
|
80
|
-
framework.on('framework:ready', (fw) => {});
|
|
81
|
-
framework.on('plugin:loaded', (plugin) => {});
|
|
82
|
-
framework.on('tool:registered', (tool) => {});
|
|
83
|
-
|
|
84
|
-
// Agent 事件
|
|
85
|
-
agent.on('status', ({ status }) => {}); // idle/busy/error
|
|
86
|
-
agent.on('chunk', (chunk) => {}); // 流式输出
|
|
87
|
-
agent.on('tool-call', ({ name, args }) => {});
|
|
88
|
-
agent.on('tool-result', ({ name, result }) => {});
|
|
89
|
-
|
|
90
|
-
// 子 Agent 事件
|
|
91
|
-
agent.on('subagent:chat:start', (data) => {});
|
|
92
|
-
agent.on('subagent:chat:end', (data) => {});
|
|
93
|
-
agent.on('subagent:error', (data) => {});
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
## 子 Agent 注册
|
|
97
|
-
|
|
98
|
-
```javascript
|
|
99
|
-
const { tool } = require('ai')
|
|
100
|
-
const { z } = require('zod')
|
|
101
|
-
|
|
102
|
-
// 方式1:配置 agents 数组自动注册
|
|
103
|
-
class MyPlugin extends Plugin {
|
|
104
|
-
agents = [
|
|
105
|
-
{
|
|
106
|
-
name: 'code-agent',
|
|
107
|
-
role: '代码专家',
|
|
108
|
-
tools: {
|
|
109
|
-
compile: tool({
|
|
110
|
-
description: '编译',
|
|
111
|
-
parameters: z.object({ language: z.string(), code: z.string() }),
|
|
112
|
-
execute: async (args) => ({ success: true })
|
|
113
|
-
})
|
|
114
|
-
},
|
|
115
|
-
parentTools: ['read_file', 'write_file']
|
|
116
|
-
}
|
|
117
|
-
]
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// 方式2:手动调用
|
|
121
|
-
this.registerSubAgent({ name: 'code-agent', role: '代码专家', tools: {...}, parentTools: [...] })
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
## 系统提示中的部分
|
|
125
|
-
|
|
126
|
-
```
|
|
127
|
-
【可用工具】
|
|
128
|
-
- tool1: 描述
|
|
129
|
-
- tool2: 描述
|
|
130
|
-
|
|
131
|
-
【可用技能】
|
|
132
|
-
- skill1: 描述
|
|
133
|
-
- skill2: 描述
|
|
134
|
-
|
|
135
|
-
【子 Agent 分配规则】
|
|
136
|
-
- code-agent: 代码专家
|
|
137
|
-
|
|
138
|
-
【系统能力】
|
|
139
|
-
- ai: AI 对话能力
|
|
140
|
-
- storage: 存储
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
## 状态管理
|
|
144
|
-
|
|
145
|
-
```javascript
|
|
146
|
-
agent.getStatus(); // 'idle' | 'busy' | 'error'
|
|
147
|
-
agent.resetStatus(); // 重置状态
|
|
148
|
-
agent.clearHistory(); // 清空历史
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
## 配置持久化
|
|
152
|
-
|
|
153
|
-
插件配置自动保存到 `.foliko/data/plugins-state.json`
|
|
154
|
-
|
|
155
|
-
| 文件 | 用途 |
|
|
156
|
-
| --------------------------------- | ------------------- |
|
|
157
|
-
| `.foliko/data/plugins-state.json` | 插件启用状态和配置 |
|
|
158
|
-
| `.foliko/data/storage.json` | 键值存储数据 |
|
|
159
|
-
| `.foliko/data/telegram_images/` | Telegram 接收的图片 |
|
|
160
|
-
| `.foliko/data/telegram_documents/` | Telegram 接收的文档 |
|
|
1
|
+
# Foliko 快速参考
|
|
2
|
+
|
|
3
|
+
## 启动框架
|
|
4
|
+
|
|
5
|
+
```javascript
|
|
6
|
+
const framework = new Framework({ debug: false });
|
|
7
|
+
await framework.bootstrap({
|
|
8
|
+
agentDir: './.foliko',
|
|
9
|
+
aiConfig: { provider: 'deepseek', model: 'deepseek-chat', apiKey: '...' },
|
|
10
|
+
});
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## 创建 Agent
|
|
14
|
+
|
|
15
|
+
```javascript
|
|
16
|
+
const agent = framework.createAgent({
|
|
17
|
+
name: 'MyAgent',
|
|
18
|
+
systemPrompt: '你是一个有帮助的助手。',
|
|
19
|
+
});
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## 发送消息
|
|
23
|
+
|
|
24
|
+
```javascript
|
|
25
|
+
// 流式
|
|
26
|
+
for await (const chunk of agent.chatStream('你好')) {
|
|
27
|
+
if (chunk.type === 'text') process.stdout.write(chunk.text);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// 非流式
|
|
31
|
+
const result = await agent.chat('你好');
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## 常用工具
|
|
35
|
+
|
|
36
|
+
| 工具 | 用途 |
|
|
37
|
+
| ---------------------- | ------------ |
|
|
38
|
+
| `list_tools` | 列出所有工具 |
|
|
39
|
+
| `loadSkill` | 加载技能 |
|
|
40
|
+
| `reload_plugins` | 重载插件 |
|
|
41
|
+
| `read_file` | 读取文件 |
|
|
42
|
+
| `write_file` | 写入文件 |
|
|
43
|
+
| `execute_command` | 执行命令 |
|
|
44
|
+
| `schedule_once` | 定时任务 |
|
|
45
|
+
| `think_now` | 主动思考 |
|
|
46
|
+
| `email_send` | 发送邮件 |
|
|
47
|
+
| `email_read` | 读取邮件 |
|
|
48
|
+
| `enable_plugin` | 启用插件 |
|
|
49
|
+
| `disable_plugin` | 禁用插件 |
|
|
50
|
+
| `update_plugin_config` | 更新插件配置 |
|
|
51
|
+
|
|
52
|
+
## 插件位置
|
|
53
|
+
|
|
54
|
+
- 内置插件:`plugins/`
|
|
55
|
+
- 用户插件:`.foliko/plugins/`
|
|
56
|
+
|
|
57
|
+
## 插件管理
|
|
58
|
+
|
|
59
|
+
```javascript
|
|
60
|
+
// 重启插件
|
|
61
|
+
await framework.executeTool('reload_plugins', {});
|
|
62
|
+
await framework.executeTool('reload_plugins', { pluginName: 'telegram' });
|
|
63
|
+
|
|
64
|
+
// 启用/禁用插件
|
|
65
|
+
await framework.executeTool('enable_plugin', { name: 'telegram' });
|
|
66
|
+
await framework.executeTool('disable_plugin', { name: 'telegram' });
|
|
67
|
+
|
|
68
|
+
// 更新插件配置(持久化)
|
|
69
|
+
await framework.executeTool('update_plugin_config', {
|
|
70
|
+
name: 'telegram',
|
|
71
|
+
config: { allowedChats: ['123'], groupMode: true },
|
|
72
|
+
});
|
|
73
|
+
await framework.executeTool('get_plugin_config', { name: 'telegram' });
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## 事件监听
|
|
77
|
+
|
|
78
|
+
```javascript
|
|
79
|
+
// Framework 事件
|
|
80
|
+
framework.on('framework:ready', (fw) => {});
|
|
81
|
+
framework.on('plugin:loaded', (plugin) => {});
|
|
82
|
+
framework.on('tool:registered', (tool) => {});
|
|
83
|
+
|
|
84
|
+
// Agent 事件
|
|
85
|
+
agent.on('status', ({ status }) => {}); // idle/busy/error
|
|
86
|
+
agent.on('chunk', (chunk) => {}); // 流式输出
|
|
87
|
+
agent.on('tool-call', ({ name, args }) => {});
|
|
88
|
+
agent.on('tool-result', ({ name, result }) => {});
|
|
89
|
+
|
|
90
|
+
// 子 Agent 事件
|
|
91
|
+
agent.on('subagent:chat:start', (data) => {});
|
|
92
|
+
agent.on('subagent:chat:end', (data) => {});
|
|
93
|
+
agent.on('subagent:error', (data) => {});
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## 子 Agent 注册
|
|
97
|
+
|
|
98
|
+
```javascript
|
|
99
|
+
const { tool } = require('ai')
|
|
100
|
+
const { z } = require('zod')
|
|
101
|
+
|
|
102
|
+
// 方式1:配置 agents 数组自动注册
|
|
103
|
+
class MyPlugin extends Plugin {
|
|
104
|
+
agents = [
|
|
105
|
+
{
|
|
106
|
+
name: 'code-agent',
|
|
107
|
+
role: '代码专家',
|
|
108
|
+
tools: {
|
|
109
|
+
compile: tool({
|
|
110
|
+
description: '编译',
|
|
111
|
+
parameters: z.object({ language: z.string(), code: z.string() }),
|
|
112
|
+
execute: async (args) => ({ success: true })
|
|
113
|
+
})
|
|
114
|
+
},
|
|
115
|
+
parentTools: ['read_file', 'write_file']
|
|
116
|
+
}
|
|
117
|
+
]
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// 方式2:手动调用
|
|
121
|
+
this.registerSubAgent({ name: 'code-agent', role: '代码专家', tools: {...}, parentTools: [...] })
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## 系统提示中的部分
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
【可用工具】
|
|
128
|
+
- tool1: 描述
|
|
129
|
+
- tool2: 描述
|
|
130
|
+
|
|
131
|
+
【可用技能】
|
|
132
|
+
- skill1: 描述
|
|
133
|
+
- skill2: 描述
|
|
134
|
+
|
|
135
|
+
【子 Agent 分配规则】
|
|
136
|
+
- code-agent: 代码专家
|
|
137
|
+
|
|
138
|
+
【系统能力】
|
|
139
|
+
- ai: AI 对话能力
|
|
140
|
+
- storage: 存储
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## 状态管理
|
|
144
|
+
|
|
145
|
+
```javascript
|
|
146
|
+
agent.getStatus(); // 'idle' | 'busy' | 'error'
|
|
147
|
+
agent.resetStatus(); // 重置状态
|
|
148
|
+
agent.clearHistory(); // 清空历史
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## 配置持久化
|
|
152
|
+
|
|
153
|
+
插件配置自动保存到 `.foliko/data/plugins-state.json`
|
|
154
|
+
|
|
155
|
+
| 文件 | 用途 |
|
|
156
|
+
| --------------------------------- | ------------------- |
|
|
157
|
+
| `.foliko/data/plugins-state.json` | 插件启用状态和配置 |
|
|
158
|
+
| `.foliko/data/storage.json` | 键值存储数据 |
|
|
159
|
+
| `.foliko/data/telegram_images/` | Telegram 接收的图片 |
|
|
160
|
+
| `.foliko/data/telegram_documents/` | Telegram 接收的文档 |
|
package/package.json
CHANGED
|
@@ -307,22 +307,22 @@ class ExtensionExecutorPlugin extends Plugin {
|
|
|
307
307
|
|
|
308
308
|
const ext = this._extensions.get(pluginName);
|
|
309
309
|
const existingIdx = ext.tools.findIndex((t) => t.name === toolDef.name);
|
|
310
|
+
const toolEntry = {
|
|
311
|
+
name: toolDef.name,
|
|
312
|
+
description: toolDef.description || '',
|
|
313
|
+
inputSchema: toolDef.inputSchema,
|
|
314
|
+
execute: toolDef.execute,
|
|
315
|
+
};
|
|
316
|
+
// 保留额外属性(如 _options)
|
|
317
|
+
if (toolDef._options) {
|
|
318
|
+
toolEntry._options = toolDef._options;
|
|
319
|
+
}
|
|
310
320
|
if (existingIdx >= 0) {
|
|
311
321
|
// 更新已存在的工具
|
|
312
|
-
ext.tools[existingIdx] =
|
|
313
|
-
name: toolDef.name,
|
|
314
|
-
description: toolDef.description || '',
|
|
315
|
-
inputSchema: toolDef.inputSchema,
|
|
316
|
-
execute: toolDef.execute,
|
|
317
|
-
};
|
|
322
|
+
ext.tools[existingIdx] = toolEntry;
|
|
318
323
|
} else {
|
|
319
324
|
// 添加新工具
|
|
320
|
-
ext.tools.push(
|
|
321
|
-
name: toolDef.name,
|
|
322
|
-
description: toolDef.description || '',
|
|
323
|
-
inputSchema: toolDef.inputSchema,
|
|
324
|
-
execute: toolDef.execute,
|
|
325
|
-
});
|
|
325
|
+
ext.tools.push(toolEntry);
|
|
326
326
|
}
|
|
327
327
|
|
|
328
328
|
log.debug(` Registered tool '${toolDef.name}' for extension '${pluginName}'`);
|
|
@@ -413,44 +413,17 @@ class ExtensionExecutorPlugin extends Plugin {
|
|
|
413
413
|
if (this._extensions.size > 0 || (this._mcpExecutor && Object.keys(this._mcpExecutor.tools || {}).length > 0)) {
|
|
414
414
|
desc += '## 【Extensions】扩展插件\n\n';
|
|
415
415
|
desc += '**使用流程(必须按顺序执行):**\n';
|
|
416
|
-
desc += '1. 调用 `ext_skill({ plugin: "<plugin_name>" })`
|
|
417
|
-
desc += '2. 根据返回的参数定义,使用 `ext_call({ plugin: "
|
|
416
|
+
desc += '1. 调用 `ext_skill({ plugin: "<plugin_name>" })` 获取技能命令的详细参数\n';
|
|
417
|
+
desc += '2. 根据返回的参数定义,使用 `ext_call({ plugin: "<plugin_name>", tool: "<tool_name>", args: {...} })` 调用\n\n';
|
|
418
418
|
desc += '> **警告**:禁止在未执行第1步获取参数的情况下直接调用 `ext_call`!\n\n';
|
|
419
419
|
|
|
420
420
|
for (const [name, ext] of this._extensions) {
|
|
421
|
-
|
|
422
|
-
// Skill 命令按技能名分组显示
|
|
423
|
-
const toolsBySkill = {};
|
|
424
|
-
for (const tool of ext.tools) {
|
|
425
|
-
// 跳过无效工具
|
|
426
|
-
if (!tool || !tool.name) continue;
|
|
427
|
-
// 命令格式: skillname:cmdname
|
|
428
|
-
const parts = tool.name.split(':');
|
|
429
|
-
const skillName = parts[0];
|
|
430
|
-
const cmdName = parts.slice(1).join(':');
|
|
431
|
-
if (!toolsBySkill[skillName]) {
|
|
432
|
-
toolsBySkill[skillName] = [];
|
|
433
|
-
}
|
|
434
|
-
toolsBySkill[skillName].push({ name: cmdName, description: tool.description });
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
for (const [skillName, cmds] of Object.entries(toolsBySkill)) {
|
|
438
|
-
desc += `### skill.${skillName}\n`;
|
|
439
|
-
desc += `**调用方式:**\n`;
|
|
440
|
-
desc += `1. 先调用 \`loadSkill({ skill: "${skillName}" })\` 获取 \`${skillName}\` 技能的详细参数\n`;
|
|
441
|
-
desc += `2. 调用 \`ext_call({ plugin: "skill", tool: "${skillName}:<命令名>", args: { args: "参数" } })\`\n\n`;
|
|
442
|
-
desc += `**可用命令:**\n`;
|
|
443
|
-
for (const c of cmds) {
|
|
444
|
-
desc += `- \`${c.name}\`: ${c.description}\n`;
|
|
445
|
-
}
|
|
446
|
-
desc += '\n';
|
|
447
|
-
}
|
|
448
|
-
} else {
|
|
421
|
+
if (name === 'mcp'|| name === 'skill') continue; // MCP 和 Skill 工具单独列出
|
|
449
422
|
desc += `### ${ext.name || name}\n`;
|
|
450
423
|
desc += `${ext.description || '无描述'}\n`;
|
|
451
424
|
const validTools = ext.tools.filter(t => t && t.name);
|
|
452
425
|
desc += `**工具:** ${validTools.map(t => `\`${t.name}\``).join(', ')}\n\n`;
|
|
453
|
-
|
|
426
|
+
|
|
454
427
|
}
|
|
455
428
|
|
|
456
429
|
// MCP 服务器工具
|
|
@@ -461,7 +434,7 @@ class ExtensionExecutorPlugin extends Plugin {
|
|
|
461
434
|
}
|
|
462
435
|
|
|
463
436
|
desc += '\n## 禁止事项\n';
|
|
464
|
-
desc += '- 不先调用 `ext_skill
|
|
437
|
+
desc += '- 不先调用 `ext_skill` 获取参数就直接使用 `ext_call`\n';
|
|
465
438
|
}
|
|
466
439
|
|
|
467
440
|
if (!desc) {
|
|
@@ -597,6 +570,7 @@ class ExtensionExecutorPlugin extends Plugin {
|
|
|
597
570
|
.map(t => ({
|
|
598
571
|
name: t.name.replace(/^([^:]+):(.*)$/, '$1:$2'),
|
|
599
572
|
description: t.description || t.name,
|
|
573
|
+
options: t._options || null,
|
|
600
574
|
}));
|
|
601
575
|
}
|
|
602
576
|
|