foliko 2.0.4 → 2.0.6

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.
Files changed (59) hide show
  1. package/.claude/settings.local.json +4 -1
  2. package/.cli_default_systemPrompt.md +291 -0
  3. package/CLAUDE.md +3 -0
  4. package/README.md +20 -3
  5. package/docs/architecture.md +34 -2
  6. package/docs/extensions.md +199 -0
  7. package/docs/migration.md +100 -0
  8. package/docs/public-api.md +1180 -6
  9. package/docs/usage.md +122 -30
  10. package/package.json +1 -1
  11. package/plugins/core/audit/index.js +1 -1
  12. package/plugins/core/default/bootstrap.js +65 -19
  13. package/plugins/core/python-loader/index.js +43 -25
  14. package/plugins/core/skill-manager/PROMPT.md +6 -0
  15. package/plugins/core/skill-manager/index.js +538 -93
  16. package/plugins/core/sub-agent/PROMPT.md +10 -0
  17. package/plugins/core/sub-agent/index.js +36 -3
  18. package/plugins/core/think/index.js +1 -0
  19. package/plugins/core/workflow/index.js +106 -22
  20. package/plugins/executors/data-splitter/PROMPT.md +13 -0
  21. package/plugins/executors/data-splitter/index.js +5 -4
  22. package/plugins/executors/extension/extension-registry.js +145 -0
  23. package/plugins/executors/extension/index.js +405 -437
  24. package/plugins/executors/extension/prompt-builder.js +359 -0
  25. package/plugins/executors/extension/skill-helper.js +143 -0
  26. package/plugins/messaging/feishu/index.js +5 -3
  27. package/plugins/messaging/qq/index.js +6 -4
  28. package/plugins/messaging/telegram/index.js +6 -3
  29. package/plugins/messaging/weixin/index.js +5 -3
  30. package/plugins/tools/PROMPT.md +26 -0
  31. package/plugins/tools/index.js +6 -5
  32. package/skills/foliko/AGENTS.md +196 -43
  33. package/skills/foliko/SKILL.md +157 -28
  34. package/skills/mcp/SKILL.md +77 -118
  35. package/skills/plugins/SKILL.md +89 -3
  36. package/skills/python/SKILL.md +57 -39
  37. package/skills/skill-guide/SKILL.md +42 -34
  38. package/skills/workflows/SKILL.md +224 -9
  39. package/skills/workflows/workflow-troubleshooting/SKILL.md +221 -281
  40. package/src/agent/chat.js +48 -27
  41. package/src/agent/main.js +34 -13
  42. package/src/agent/prompt-registry.js +133 -87
  43. package/src/agent/prompts/PROMPT.md +3 -0
  44. package/src/agent/sub.js +1 -1
  45. package/src/cli/ui/chat-ui-old.js +5 -2
  46. package/src/cli/ui/chat-ui.js +5 -2
  47. package/src/common/constants.js +12 -0
  48. package/src/common/error-capture.js +91 -0
  49. package/src/common/logger.js +2 -2
  50. package/src/context/compressor.js +6 -2
  51. package/src/executors/mcp-executor.js +105 -125
  52. package/src/framework/framework.js +632 -6
  53. package/src/index.js +4 -0
  54. package/src/plugin/base.js +913 -10
  55. package/src/plugin/manager.js +29 -8
  56. package/src/tool/schema.js +32 -9
  57. package/tests/core/plugin-prompts.test.js +13 -13
  58. package/tests/core/prompt-registry.test.js +59 -51
  59. package/website/index.html +821 -0
@@ -1,391 +1,331 @@
1
1
  ---
2
2
  name: workflow-troubleshooting
3
- description: 工作流故障排除与修复指南。当工作流执行失败、fetch 工具不可用、模板变量问题时调用此技能。
4
- allowed-tools: python-executor, shell, read_file, write_file, execute_workflow, fetch
3
+ description: 工作流故障排除与修复指南。当工作流执行失败、工具调用失败、模板变量问题时调用此技能。
4
+ allowed-tools: python-executor, shell, read_file, write_file, execute_workflow, workflow_reload
5
5
  ---
6
6
 
7
7
  # 工作流故障排除指南
8
8
 
9
9
  ## 常见问题与解决方案
10
10
 
11
- ### 1. fetch 工具可用
11
+ ### 1. Unknown step type 错误
12
12
 
13
- **好消息**: 工作流引擎**支持** `fetch` 工具!可以直接在 steps 中使用:
13
+ **原因**:使用了不支持的步骤类型,如 `action: "ext_call"`
14
14
 
15
- ```yaml
16
- steps:
17
- - type: tool
18
- name: fetch
19
- params:
20
- url: 'https://news.baidu.com'
21
- timeout: 10000
22
- output: 'baidu_news'
23
- ```
15
+ **解决方案**:使用 `type: "tool"` + `tool: "ext_call"` 调用扩展工具
24
16
 
25
- **优势**:
17
+ ```json
18
+ // ❌ 错误
19
+ { "action": "ext_call", "params": { ... } }
26
20
 
27
- - 原生支持,无需额外 sandbox 配置
28
- - 语法简洁
29
- - 自动处理超时和错误
21
+ // 正确
22
+ {
23
+ "type": "tool",
24
+ "tool": "ext_call",
25
+ "args": {
26
+ "plugin": "skill",
27
+ "tool": "creator:creator",
28
+ "args": { "command": "-r 16:9" }
29
+ }
30
+ }
31
+ ```
30
32
 
31
- ### 2. 多个 fetch 步骤串联
33
+ ### 2. 工具参数问题:args vs params
32
34
 
33
- **已验证可用**:
35
+ **原因**:工作流引擎使用 `args` 字段传递工具参数,不是 `params`
34
36
 
35
- ```yaml
36
- steps:
37
- - type: tool
38
- name: fetch
39
- params:
40
- url: 'https://news.baidu.com'
41
- output: 'baidu_news'
37
+ **解决方案**:
42
38
 
43
- - type: tool
44
- name: fetch
45
- params:
46
- url: 'https://feeds.bbci.co.uk/news/world/rss.xml'
47
- output: 'bbc_news'
39
+ ```json
40
+ // ❌ 错误
41
+ { "type": "tool", "tool": "fetch", "params": { "url": "https://..." } }
48
42
 
49
- - type: tool
50
- name: fetch
51
- params:
52
- url: 'https://www.reddit.com/r/popular/hot.json?limit=20'
53
- output: 'reddit_news'
43
+ // 正确
44
+ { "type": "tool", "tool": "fetch", "args": { "url": "https://..." } }
54
45
  ```
55
46
 
56
- ### 3. Python 脚本获取结果
57
-
58
- **正确方式**: Python 脚本返回 JSON 格式字符串
47
+ ### 3. loop 循环语法错误
59
48
 
60
- ```python
61
- import json
62
- import requests
49
+ **正确语法**:
63
50
 
64
- result = {"news": ["标题1", "标题2"]}
65
- print(json.dumps(result)) # 输出 JSON 字符串
51
+ **固定次数循环**:
52
+ ```json
53
+ {
54
+ "type": "loop",
55
+ "maxIterations": 10,
56
+ "loopVariable": "i",
57
+ "steps": [...]
58
+ }
66
59
  ```
67
60
 
68
- ### 4. webhook 类型步骤
69
-
70
- **警告**: `webhook` 类型需要 HTTP 服务支持,否则会失败。
71
-
72
- - 如需接收外部数据,使用 `web_register_webhook` 注册路由
73
- - 测试时改用 `tool` + `fetch` 组合
74
-
75
- ### 5. 变量传递问题
76
-
77
- - **原因**: sandbox 环境无法访问主环境变量
78
- - **解决方案**:
79
- - 使用上下文变量 `$.context.xxx`
80
- - 或直接在脚本中硬编码(测试用)
81
-
82
- ## 调试技巧
83
-
84
- 1. **先单独测试每个步骤** - 用简单输入验证
85
- 2. **检查工作流定义语法** - YAML/JSON 格式正确性
86
- 3. **使用简单输入测试变量传递**
87
- 4. **fetch 失败时**: 加 `timeout` 参数,加 `proxy: true` 重试
88
-
89
- ## 成功案例
90
-
91
- ### 真实新闻聚合工作流
92
-
93
- ```yaml
94
- name: 'news-fetcher'
95
- steps:
96
- - type: 'context'
97
- key: 'current_time'
98
- value: '$.time.current'
99
-
100
- - type: 'tool'
101
- name: 'fetch'
102
- params:
103
- url: 'https://news.baidu.com'
104
- timeout: 15000
105
- output: 'baidu_news'
106
-
107
- - type: 'tool'
108
- name: 'fetch'
109
- params:
110
- url: 'https://feeds.bbci.co.uk/news/world/rss.xml'
111
- timeout: 15000
112
- output: 'bbc_news'
113
-
114
- - type: 'tool'
115
- name: 'fetch'
116
- params:
117
- url: 'https://www.reddit.com/r/popular/hot.json?limit=20'
118
- timeout: 15000
119
- output: 'reddit_news'
120
-
121
- - type: 'python'
122
- script: |
123
- import json
124
- # 处理新闻数据...
125
- result = {"status": "success", "sources": ["baidu", "bbc", "reddit"]}
126
- print(json.dumps(result))
61
+ **数组迭代循环(over)**:
62
+ ```json
63
+ {
64
+ "type": "loop",
65
+ "over": "input.slides",
66
+ "as": "slide",
67
+ "index": "slideIndex",
68
+ "maxIterations": 10,
69
+ "steps": [...]
70
+ }
127
71
  ```
128
72
 
129
- ### 网络不稳定时加代理
73
+ - `over`: 要迭代的数组路径
74
+ - `as`: 每个元素的变量名
75
+ - `index`: 索引变量名(从 0 开始)
130
76
 
131
- ```yaml
132
- - type: 'tool'
133
- name: 'fetch'
134
- params:
135
- url: 'https://feeds.bbci.co.uk/news/world/rss.xml'
136
- timeout: 15000
137
- proxy: true # 失败时自动启用
138
- output: 'bbc_news'
139
- ```
140
-
141
- ## 复杂工作流步骤类型测试 ✅
77
+ - `maxIterations`: 最大迭代次数(必填)
78
+ - `loopVariable`: 循环计数器变量名(默认 `loopIndex`)
79
+ - `steps`: 循环执行的步骤数组
142
80
 
143
- 以下步骤类型已通过完整测试验证:
81
+ ### 4. condition 条件语法错误
144
82
 
145
- ### 1. parallel (并行执行) ✅
83
+ **原因**:使用了不存在的字段如 `if`、`then`
146
84
 
147
- 多个任务同时执行,提高效率:
85
+ **正确语法**:
148
86
 
149
87
  ```json
150
88
  {
151
- "type": "parallel",
152
- "steps": [
153
- { "type": "tool", "name": "get_time", "output": "current_time" },
154
- {
155
- "type": "tool",
156
- "name": "storage_set",
157
- "params": { "key": "test", "value": "ok" },
158
- "output": "storage_result"
159
- },
89
+ "type": "condition",
90
+ "branches": [
160
91
  {
161
- "type": "tool",
162
- "name": "fetch",
163
- "params": { "url": "https://news.baidu.com" },
164
- "output": "news"
92
+ "name": "条件1",
93
+ "condition": "context.variables.value > 10",
94
+ "steps": [...]
165
95
  }
166
- ]
96
+ ],
97
+ "defaultBranch": {
98
+ "steps": [...]
99
+ }
167
100
  }
168
101
  ```
169
102
 
170
- ### 2. condition (条件分支)
103
+ - `condition`: JavaScript 表达式字符串
104
+ - `branches`: 条件分支数组
105
+ - `defaultBranch`: 默认分支(可选)
106
+
107
+ ### 5. switch 分支语法错误
171
108
 
172
- 支持 if/else 逻辑判断:
109
+ **正确语法**:
173
110
 
174
111
  ```json
175
112
  {
176
- "type": "condition",
177
- "if": { "key": "$.context.storage_result", "equals": "success" },
178
- "then": [
179
- {
180
- "type": "tool",
181
- "name": "notification_send",
182
- "params": { "title": "成功", "message": "条件成立" }
183
- }
113
+ "type": "switch",
114
+ "value": "{{status}}",
115
+ "branches": [
116
+ { "case": "success", "steps": [...] },
117
+ { "case": "error", "steps": [...] }
184
118
  ],
185
- "else": [
186
- {
187
- "type": "tool",
188
- "name": "notification_send",
189
- "params": { "title": "失败", "message": "条件不成立" }
190
- }
191
- ]
119
+ "default": { "steps": [...] }
192
120
  }
193
121
  ```
194
122
 
195
- **支持的操作符**:`equals`, `not_equals`, `contains`, `greater_than`, `less_than`, `exists`, `not_exists`
123
+ - `value`: 要匹配的值,支持 `{{variable}}` 引用
124
+ - `branches`: 分支数组,匹配 `case` 等于 `value` 的分支
125
+ - `default`: 默认分支
196
126
 
197
- ### 3. loop (循环执行) ✅
127
+ ### 6. try-catch 语法错误
198
128
 
199
- 支持指定次数的循环:
129
+ **正确语法**:
200
130
 
201
131
  ```json
202
132
  {
203
- "type": "loop",
204
- "count": 3,
205
- "steps": [
206
- {
207
- "type": "tool",
208
- "name": "notification_send",
209
- "params": { "title": "循环", "message": "第 {{index}} 次" }
210
- }
211
- ]
133
+ "type": "try",
134
+ "try": {
135
+ "steps": [
136
+ { "type": "tool", "tool": "可能失败的工具", "args": {} }
137
+ ]
138
+ },
139
+ "catch": {
140
+ "steps": [...]
141
+ }
212
142
  }
213
143
  ```
214
144
 
215
- ### 4. switch (多分支) ✅
145
+ ### 7. parallel 并行执行语法
216
146
 
217
- 类似 switch-case 的多条件分支:
147
+ **正确语法**:
218
148
 
219
149
  ```json
220
150
  {
221
- "type": "switch",
222
- "value": "$.context.status",
223
- "cases": [
224
- {
225
- "value": "success",
226
- "steps": [{ "type": "tool", "name": "notification_send", "params": { "title": "成功" } }]
227
- },
228
- {
229
- "value": "error",
230
- "steps": [{ "type": "tool", "name": "notification_send", "params": { "title": "错误" } }]
231
- }
232
- ],
233
- "default": [{ "type": "tool", "name": "notification_send", "params": { "title": "默认" } }]
151
+ "type": "parallel",
152
+ "steps": [
153
+ { "type": "tool", "tool": "task1", "args": {} },
154
+ { "type": "tool", "tool": "task2", "args": {} }
155
+ ]
234
156
  }
235
157
  ```
236
158
 
237
- ### 5. try-catch (错误处理) ✅
159
+ ## 调试技巧
160
+
161
+ ### 1. 先单独测试每个步骤
238
162
 
239
- 捕获步骤执行中的错误,防止中断:
163
+ 创建简单的单步骤工作流验证工具是否可用:
240
164
 
241
165
  ```json
242
166
  {
243
- "type": "try",
244
- "steps": [{ "type": "tool", "name": "email_unread_count" }],
245
- "catch": [
167
+ "name": "test-tool",
168
+ "steps": [
246
169
  {
247
170
  "type": "tool",
248
- "name": "notification_send",
249
- "params": { "title": "捕获错误", "message": "邮件服务超时,使用备用方案" }
171
+ "name": "测试",
172
+ "tool": "notification_send",
173
+ "args": { "message": "测试消息" }
250
174
  }
251
175
  ]
252
176
  }
253
177
  ```
254
178
 
255
- ### 6. delay (延迟执行)
256
-
257
- 在步骤之间添加延迟:
179
+ ### 2. 使用 script 步骤调试变量
258
180
 
259
181
  ```json
260
182
  {
261
- "type": "delay",
262
- "ms": 500
183
+ "type": "script",
184
+ "name": "调试变量",
185
+ "outputVariable": "debug",
186
+ "script": "return JSON.stringify(context.variables, null, 2);"
263
187
  }
264
188
  ```
265
189
 
266
- ### 7. nested workflow (嵌套工作流) ✅
267
-
268
- 在主工作流中调用子工作流:
190
+ ### 3. 检查工具是否存在
269
191
 
270
- ```json
271
- {
272
- "type": "workflow",
273
- "name": "workflow_file-backup",
274
- "input": {}
275
- }
276
- ```
192
+ 使用 `workflow_list` 工具查看所有已注册的工作流工具。
277
193
 
278
- ### 8. context (上下文变量) ✅
194
+ ### 4. 变量引用格式
279
195
 
280
- 在步骤间传递数据:
196
+ | 格式 | 说明 |
197
+ | ---- | ---- |
198
+ | `{{result}}` | 上一步完整结果 |
199
+ | `{{result.field}}` | 从结果提取字段 |
200
+ | `{{lastResult}}` | result 的别名 |
201
+ | `{{variables.x}}` | 显式引用 variables |
202
+ | `{{input.x}}` | 引用工作流输入 |
203
+ | `${stepId.output}` | 引用指定步骤输出(兼容旧格式) |
281
204
 
282
- ```json
283
- {
284
- "type": "context",
285
- "key": "workflow_status",
286
- "value": "completed"
287
- }
288
- ```
205
+ ## 完整工作流示例
289
206
 
290
- ## 复杂工作流完整示例
207
+ ### 示例:使用 ext_call 调用 skill 命令
291
208
 
292
209
  ```json
293
210
  {
294
- "name": "complex-workflow-demo",
295
- "input": {},
211
+ "name": "video-creator",
212
+ "description": "视频创作工作流示例",
213
+ "input": {
214
+ "title": "测试视频",
215
+ "slides": ["slide1", "slide2"]
216
+ },
296
217
  "steps": [
297
218
  {
298
- "type": "parallel",
299
- "steps": [
300
- { "type": "tool", "name": "get_time", "output": "time" },
301
- {
302
- "type": "tool",
303
- "name": "storage_set",
304
- "params": { "key": "status", "value": "started" },
305
- "output": "storage"
306
- },
307
- { "type": "tool", "name": "storage_list", "output": "namespaces" }
308
- ]
219
+ "type": "tool",
220
+ "name": "创建项目",
221
+ "tool": "ext_call",
222
+ "args": {
223
+ "plugin": "skill",
224
+ "tool": "creator:creator",
225
+ "args": {
226
+ "command": "-r 16:9 -t true -v female-shaonv-jingpin"
227
+ }
228
+ },
229
+ "outputVariable": "videoId"
309
230
  },
310
231
  {
311
- "type": "condition",
312
- "if": { "key": "$.context.storage", "exists": true },
313
- "then": [
314
- {
315
- "type": "tool",
316
- "name": "notification_send",
317
- "params": { "title": "开始", "message": "工作流启动" }
232
+ "type": "tool",
233
+ "name": "添加片头",
234
+ "tool": "ext_call",
235
+ "args": {
236
+ "plugin": "skill",
237
+ "tool": "creator:addCover",
238
+ "args": {
239
+ "command": "-i {{videoId}} -t '{{input.title}}'"
318
240
  }
319
- ]
241
+ }
320
242
  },
321
- { "type": "delay", "ms": 300 },
322
243
  {
323
244
  "type": "loop",
324
- "count": 2,
245
+ "name": "添加幻灯片",
246
+ "maxIterations": 10,
247
+ "loopVariable": "i",
325
248
  "steps": [
326
249
  {
327
- "type": "tool",
328
- "name": "notification_send",
329
- "params": { "title": "循环", "message": "第 {{index}} 次" }
330
- }
331
- ]
332
- },
333
- {
334
- "type": "switch",
335
- "value": "$.context.storage",
336
- "cases": [
337
- {
338
- "value": "started",
339
- "steps": [
250
+ "type": "condition",
251
+ "name": "检查是否还有幻灯片",
252
+ "branches": [
340
253
  {
341
- "type": "tool",
342
- "name": "notification_send",
343
- "params": { "title": "状态", "message": "已开始" }
254
+ "name": "有幻灯片",
255
+ "condition": "context.variables.i < context.input.slides.length",
256
+ "steps": [
257
+ {
258
+ "type": "tool",
259
+ "name": "添加幻灯片",
260
+ "tool": "ext_call",
261
+ "args": {
262
+ "plugin": "skill",
263
+ "tool": "creator:addSlide",
264
+ "args": {
265
+ "command": "-i {{videoId}} -n {{i}}"
266
+ }
267
+ }
268
+ }
269
+ ]
344
270
  }
345
271
  ]
346
272
  }
347
- ],
348
- "default": [
349
- {
350
- "type": "tool",
351
- "name": "notification_send",
352
- "params": { "title": "状态", "message": "默认状态" }
353
- }
354
273
  ]
355
274
  },
356
275
  {
357
- "type": "try",
358
- "steps": [{ "type": "tool", "name": "email_unread_count" }],
359
- "catch": [
360
- {
361
- "type": "tool",
362
- "name": "notification_send",
363
- "params": { "title": "错误处理", "message": "捕获异常完成" }
276
+ "type": "tool",
277
+ "name": "渲染视频",
278
+ "tool": "ext_call",
279
+ "args": {
280
+ "plugin": "skill",
281
+ "tool": "creator:render",
282
+ "args": {
283
+ "command": "-i {{videoId}} -o output.mp4"
364
284
  }
365
- ]
285
+ }
286
+ }
287
+ ]
288
+ }
289
+ ```
290
+
291
+ ## 快速修复清单
292
+
293
+ | 问题 | 修复 |
294
+ | ---- | ---- |
295
+ | `Unknown step type: ext_call` | 改用 `type: "tool"` + `tool: "ext_call"` |
296
+ | 工具参数不传递 | 将 `params` 改为 `args` |
297
+ | loop 不执行 | 检查 `maxIterations` 和 `steps` 字段 |
298
+ | condition 不生效 | 使用 `condition` 字段,不是 `if` |
299
+ | switch 不匹配 | 确保有 `default` 分支兜底 |
300
+ | 变量引用失败 | 使用 `{{result}}` 而非 `${result}` |
301
+
302
+ ## 成功案例
303
+
304
+ ### 视频创作工作流(已验证)
305
+
306
+ ```json
307
+ {
308
+ "name": "hot-news-video",
309
+ "steps": [
310
+ {
311
+ "type": "tool",
312
+ "tool": "ext_call",
313
+ "args": {
314
+ "plugin": "skill",
315
+ "tool": "creator:creator",
316
+ "args": { "command": "-r 16:9 -t true -v female-shaonv-jingpin" }
317
+ },
318
+ "outputVariable": "videoId"
366
319
  },
367
- { "type": "workflow", "name": "workflow_file-backup", "input": {} },
368
320
  {
369
321
  "type": "tool",
370
- "name": "notification_send",
371
- "params": { "title": "完成", "message": "复杂工作流执行成功" }
322
+ "tool": "ext_call",
323
+ "args": {
324
+ "plugin": "skill",
325
+ "tool": "creator:addCover",
326
+ "args": { "command": "-i {{videoId}} -t '{{input.title}}'" }
327
+ }
372
328
  }
373
329
  ]
374
330
  }
375
331
  ```
376
-
377
- ## 关键结论
378
-
379
- | 场景 | 推荐方案 |
380
- | ------------ | ---------------------------- |
381
- | 获取网络数据 | ✅ `fetch` 工具 |
382
- | 本地脚本处理 | ✅ `python` 类型 + JSON 输出 |
383
- | 接收外部请求 | `webhook` 类型(需服务运行) |
384
- | 串行任务 | ✅ 多个 `tool`/`python` 步骤 |
385
- | 并行任务 | ✅ `parallel` 类型 |
386
- | 条件分支 | ✅ `condition` 类型 |
387
- | 循环执行 | ✅ `loop` 类型 |
388
- | 多分支选择 | ✅ `switch` 类型 |
389
- | 错误处理 | ✅ `try-catch` 类型 |
390
- | 延迟等待 | ✅ `delay` 类型 |
391
- | 子工作流调用 | ✅ `workflow` 类型 |