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
@@ -176,13 +176,17 @@ module.exports = [
176
176
 
177
177
  ### ext_call 调用格式
178
178
 
179
- 当需要通过 AI 调用 skill 命令时,使用 `ext_call` 工具:
179
+ 每个 skill 自动注册为 `skill:<技能名>` 扩展,通过 `ext_call` + `ext_skill` 统一调用。
180
180
 
181
181
  ```javascript
182
+ // 1. 先查询命令参数
183
+ ext_skill({ plugin: "skill:<技能名>" })
184
+
185
+ // 2. 用命令行字符串调用
182
186
  ext_call({
183
- plugin: "skill",
184
- tool: "<skillname>:<commandname>",
185
- args: { command: "<命令行>" }
187
+ plugin: "skill:<技能名>",
188
+ tool: "<commandname>",
189
+ args: { command: "-n Alice -l en" }
186
190
  });
187
191
  ```
188
192
 
@@ -190,31 +194,31 @@ ext_call({
190
194
 
191
195
  | 参数 | 类型 | 说明 |
192
196
  |------|------|------|
193
- | `plugin` | string | 固定为 `"skill"` |
194
- | `tool` | string | 格式为 `<技能名>:<命令名>`,如 `test-skill:greet` |
195
- | `args.command` | string | 命令行参数字符串 |
197
+ | `plugin` | string | 固定为 `"skill:<技能名>"`,如 `skill:test-skill` |
198
+ | `tool` | string | 命令名(不带技能前缀),如 `greet` |
199
+ | `args` | object | 固定为 `{ command: "命令行字符串" }` |
196
200
 
197
201
  **示例:**
198
202
 
199
203
  ```javascript
200
- // 调用 test-skill 的 greet 命令,无参数
204
+ // 调用 test-skill 的 greet 命令
201
205
  ext_call({
202
- plugin: "skill",
203
- tool: "test-skill:greet",
204
- args: { command: "" }
206
+ plugin: "skill:test-skill",
207
+ tool: "greet",
208
+ args: { command: "-n Alice" }
205
209
  });
206
210
 
207
- // 调用 test-skill 的 greet 命令,带参数
211
+ // 调用 test-skill 的 greet 命令,带可选 lang
208
212
  ext_call({
209
- plugin: "skill",
210
- tool: "test-skill:greet",
211
- args: { command: "Alice" }
213
+ plugin: "skill:test-skill",
214
+ tool: "greet",
215
+ args: { command: "-n Alice -l en" }
212
216
  });
213
217
 
214
218
  // 调用 test-skill 的 echo 命令
215
219
  ext_call({
216
- plugin: "skill",
217
- tool: "test-skill:echo",
220
+ plugin: "skill:test-skill",
221
+ tool: "echo",
218
222
  args: { command: "Hello World" }
219
223
  });
220
224
  ```
@@ -383,13 +387,17 @@ module.exports = [
383
387
 
384
388
  ### ext_call 调用格式
385
389
 
386
- 当需要通过 AI 调用 skill 命令时,使用 `ext_call` 工具:
390
+ 每个 skill 自动注册为 `skill:<技能名>` 扩展,通过 `ext_call` + `ext_skill` 统一调用。
387
391
 
388
392
  ```javascript
393
+ // 1. 先查询命令参数
394
+ ext_skill({ plugin: "skill:<技能名>" })
395
+
396
+ // 2. 用命令行字符串调用
389
397
  ext_call({
390
- plugin: "skill",
391
- tool: "<skillname>:<commandname>",
392
- args: { command: "<命令行>" }
398
+ plugin: "skill:<技能名>",
399
+ tool: "<commandname>",
400
+ args: { command: "-n Alice -l en" }
393
401
  });
394
402
  ```
395
403
 
@@ -397,31 +405,31 @@ ext_call({
397
405
 
398
406
  | 参数 | 类型 | 说明 |
399
407
  |------|------|------|
400
- | `plugin` | string | 固定为 `"skill"` |
401
- | `tool` | string | 格式为 `<技能名>:<命令名>`,如 `test-skill:greet` |
402
- | `args.command` | string | 命令行参数字符串 |
408
+ | `plugin` | string | 固定为 `"skill:<技能名>"`,如 `skill:test-skill` |
409
+ | `tool` | string | 命令名(不带技能前缀),如 `greet` |
410
+ | `args` | object | 固定为 `{ command: "命令行字符串" }` |
403
411
 
404
412
  **示例:**
405
413
 
406
414
  ```javascript
407
- // 调用 test-skill 的 greet 命令,无参数
415
+ // 调用 test-skill 的 greet 命令
408
416
  ext_call({
409
- plugin: "skill",
410
- tool: "test-skill:greet",
411
- args: { command: "" }
417
+ plugin: "skill:test-skill",
418
+ tool: "greet",
419
+ args: { command: "-n Alice" }
412
420
  });
413
421
 
414
- // 调用 test-skill 的 greet 命令,带参数
422
+ // 调用 test-skill 的 greet 命令,带可选 lang
415
423
  ext_call({
416
- plugin: "skill",
417
- tool: "test-skill:greet",
418
- args: { command: "Alice" }
424
+ plugin: "skill:test-skill",
425
+ tool: "greet",
426
+ args: { command: "-n Alice -l en" }
419
427
  });
420
428
 
421
429
  // 调用 test-skill 的 echo 命令
422
430
  ext_call({
423
- plugin: "skill",
424
- tool: "test-skill:echo",
431
+ plugin: "skill:test-skill",
432
+ tool: "echo",
425
433
  args: { command: "Hello World" }
426
434
  });
427
435
  ```
@@ -144,6 +144,18 @@ allowed-tools: execute_workflow,workflow_reload
144
144
  | `args` | object | 否 | 工具参数 |
145
145
  | `outputVariable` | string | 否 | 结果保存到的变量名 |
146
146
 
147
+ **重要:`args` vs `params` 字段**:
148
+
149
+ 工作流引擎使用 `args` 字段传递工具参数,不是 `params`:
150
+
151
+ ```json
152
+ // ✅ 正确
153
+ { "type": "tool", "tool": "fetch", "args": { "url": "https://..." } }
154
+
155
+ // ❌ 错误
156
+ { "type": "tool", "tool": "fetch", "params": { "url": "https://..." } }
157
+ ```
158
+
147
159
  **args 中支持变量引用**:
148
160
 
149
161
  使用 `{{variableName}}` 语法引用 context.variables 中的变量:
@@ -199,9 +211,61 @@ allowed-tools: execute_workflow,workflow_reload
199
211
 
200
212
  **自动 JSON 解析**:如果字段值是 JSON 字符串,会自动解析为对象后再提取嵌套字段。
201
213
 
202
- ### 3. loop - 循环步骤
214
+ ### 3. 调用扩展工具(ext_call)
215
+
216
+ 使用 `ext_call` 工具调用插件扩展的命令(如 skill 插件的命令):
217
+
218
+ ```json
219
+ {
220
+ "type": "tool",
221
+ "name": "调用视频创作命令",
222
+ "tool": "ext_call",
223
+ "args": {
224
+ "plugin": "skill:creator",
225
+ "tool": "creator",
226
+ "args": {
227
+ "aspectRatio": "16:9",
228
+ "title": true,
229
+ "voice": "female-shaonv-jingpin"
230
+ }
231
+ },
232
+ "outputVariable": "videoId"
233
+ }
234
+ ```
235
+
236
+ **参数说明**:
237
+
238
+ | 字段 | 类型 | 必填 | 说明 |
239
+ | ------- | ------ | ---- | ----------------------- |
240
+ | `plugin` | string | 是 | 扩展名(格式:`skill:<技能名>` / `mcp:<server>` / `python:<插件名>`) |
241
+ | `tool` | string | 是 | 工具名(不带扩展名前缀) |
242
+ | `args` | object | 是 | Zod 结构化参数(无需拼装命令字符串) |
243
+
244
+ **调用 skill 命令示例**:
245
+
246
+ ```json
247
+ {
248
+ "type": "tool",
249
+ "name": "创建项目",
250
+ "tool": "ext_call",
251
+ "args": {
252
+ "plugin": "skill:creator",
253
+ "tool": "creator",
254
+ "args": {
255
+ "aspectRatio": "16:9",
256
+ "title": true,
257
+ "voice": "female-shaonv-jingpin",
258
+ "audio": true
259
+ }
260
+ }
261
+ }
262
+ ```
263
+
264
+ ### 4. loop - 循环步骤
265
+
266
+ 支持两种循环模式:
203
267
 
204
- 重复执行一组步骤:
268
+ **模式一:固定次数循环**
205
269
 
206
270
  ```json
207
271
  {
@@ -216,7 +280,63 @@ allowed-tools: execute_workflow,workflow_reload
216
280
  - `maxIterations`: 最大迭代次数
217
281
  - `loopVariable`: 循环计数器变量名(从 0 开始)
218
282
 
219
- ### 4. condition - 条件分支
283
+ **模式二:数组迭代循环(over)**
284
+
285
+ ```json
286
+ {
287
+ "type": "loop",
288
+ "name": "处理幻灯片",
289
+ "over": "input.slides",
290
+ "as": "slide",
291
+ "index": "slideIndex",
292
+ "maxIterations": 10,
293
+ "steps": [
294
+ {
295
+ "type": "tool",
296
+ "tool": "ext_call",
297
+ "args": {
298
+ "plugin": "skill:creator",
299
+ "tool": "addSlide",
300
+ "args": {
301
+ "videoId": "{{videoId}}",
302
+ "slideIndex": "{{slideIndex}}",
303
+ "bgColor": "{{slide.bgColor}}"
304
+ }
305
+ }
306
+ }
307
+ ]
308
+ }
309
+ ```
310
+
311
+ - `over`: 要迭代的数组路径(如 `input.slides`、`slide.cards`)
312
+ - `as`: 每个元素的变量名(如 `slide`)
313
+ - `index`: 索引变量名(如 `slideIndex`,从 0 开始)
314
+ - `maxIterations`: 最大迭代次数(可选,默认为数组长度)
315
+
316
+ **嵌套循环示例**:
317
+
318
+ ```json
319
+ {
320
+ "type": "loop",
321
+ "over": "input.slides",
322
+ "as": "slide",
323
+ "index": "slideIndex",
324
+ "steps": [
325
+ {
326
+ "name": "处理数据卡片",
327
+ "type": "loop",
328
+ "over": "slide.cards",
329
+ "as": "card",
330
+ "index": "cardIndex",
331
+ "steps": [
332
+ { "type": "tool", "tool": "addCard", "args": { ... } }
333
+ ]
334
+ }
335
+ ]
336
+ }
337
+ ```
338
+
339
+ ### 5. condition - 条件分支
220
340
 
221
341
  根据条件选择执行分支:
222
342
 
@@ -239,7 +359,7 @@ allowed-tools: execute_workflow,workflow_reload
239
359
  }
240
360
  ```
241
361
 
242
- ### 5. switch - 开关分支
362
+ ### 6. switch - 开关分支
243
363
 
244
364
  根据值匹配执行对应分支(类似编程语言的 switch-case):
245
365
 
@@ -260,7 +380,7 @@ allowed-tools: execute_workflow,workflow_reload
260
380
  - `branches`: 分支数组,匹配第一个 `case` 等于 `value` 的分支
261
381
  - `default`: 默认分支(可选)
262
382
 
263
- ### 6. try - 异常捕获
383
+ ### 7. try - 异常捕获
264
384
 
265
385
  尝试执行,失败时执行 catch 分支:
266
386
 
@@ -284,7 +404,7 @@ allowed-tools: execute_workflow,workflow_reload
284
404
  - `try`: 尝试执行的步骤
285
405
  - `catch`: 捕获异常后执行的步骤
286
406
 
287
- ### 7. parallel - 并行执行
407
+ ### 8. parallel - 并行执行
288
408
 
289
409
  多个步骤同时并行执行:
290
410
 
@@ -302,7 +422,7 @@ allowed-tools: execute_workflow,workflow_reload
302
422
 
303
423
  返回数组形式的执行结果。
304
424
 
305
- ### 8. workflow - 嵌套工作流
425
+ ### 9. workflow - 嵌套工作流
306
426
 
307
427
  在一个工作流中调用另一个工作流:
308
428
 
@@ -322,7 +442,7 @@ allowed-tools: execute_workflow,workflow_reload
322
442
 
323
443
  子工作流的输出会合并到父工作流的上下文变量中。
324
444
 
325
- ### 9. delay - 延时步骤
445
+ ### 10. delay - 延时步骤
326
446
 
327
447
  等待指定毫秒数:
328
448
 
@@ -334,7 +454,7 @@ allowed-tools: execute_workflow,workflow_reload
334
454
  }
335
455
  ```
336
456
 
337
- ### 10. sequential - 顺序步骤
457
+ ### 11. sequential - 顺序步骤
338
458
 
339
459
  将多个步骤组合为顺序执行(可嵌套使用):
340
460
 
@@ -644,3 +764,98 @@ allowed-tools: execute_workflow,workflow_reload
644
764
  "default": { "steps": [{ "type": "tool", "tool": "notification_send", "args": {"message": "未知状态"} }] }
645
765
  }
646
766
  ```
767
+
768
+ ### 示例:ext_call + loop 调用 skill 命令处理列表
769
+
770
+ **调用 skill 插件命令的正确方式**:
771
+
772
+ ```json
773
+ {
774
+ "name": "process-videos",
775
+ "description": "使用 ext_call 调用 skill 命令处理多个视频",
776
+ "input": {
777
+ "videos": ["video1.mp4", "video2.mp4", "video3.mp4"]
778
+ },
779
+ "steps": [
780
+ {
781
+ "type": "script",
782
+ "name": "初始化",
783
+ "outputVariable": "videoList",
784
+ "script": "return context.input.videos || [];"
785
+ },
786
+ {
787
+ "type": "loop",
788
+ "name": "处理每个视频",
789
+ "maxIterations": 10,
790
+ "loopVariable": "i",
791
+ "steps": [
792
+ {
793
+ "type": "condition",
794
+ "name": "检查是否还有视频",
795
+ "branches": [
796
+ {
797
+ "name": "有视频",
798
+ "condition": "context.variables.i < context.variables.videoList.length",
799
+ "steps": [
800
+ {
801
+ "type": "script",
802
+ "name": "获取当前视频",
803
+ "outputVariable": "currentVideo",
804
+ "script": "return context.variables.videoList[context.variables.i];"
805
+ },
806
+ {
807
+ "type": "tool",
808
+ "name": "处理视频",
809
+ "tool": "ext_call",
810
+ "args": {
811
+ "plugin": "skill:creator",
812
+ "tool": "addClip",
813
+ "args": {
814
+ "videoId": "{{videoId}}",
815
+ "video": "{{currentVideo}}"
816
+ }
817
+ }
818
+ }
819
+ ]
820
+ }
821
+ ]
822
+ }
823
+ ]
824
+ }
825
+ ]
826
+ }
827
+ ```
828
+
829
+ **关键点**:
830
+
831
+ 1. **使用 `type: "tool"` + `tool: "ext_call"`** 调用扩展命令
832
+ 2. **嵌套的 `args` 对象** 包含 `plugin`、`tool`、`args`
833
+ 3. **loop 使用 `maxIterations`** 控制最大循环次数
834
+ 4. **条件判断使用 `condition`** 字段
835
+
836
+ ### 常见错误
837
+
838
+ ```json
839
+ // ❌ 错误 - 使用 action: "ext_call"(不支持的类型)
840
+ {
841
+ "name": "createProject",
842
+ "action": "ext_call",
843
+ "params": {
844
+ "plugin": "skill:creator",
845
+ "tool": "creator",
846
+ "args": { "aspectRatio": "16:9" }
847
+ }
848
+ }
849
+
850
+ // ✅ 正确 - 使用 type: "tool" + tool: "ext_call"
851
+ {
852
+ "name": "createProject",
853
+ "type": "tool",
854
+ "tool": "ext_call",
855
+ "args": {
856
+ "plugin": "skill:creator",
857
+ "tool": "creator",
858
+ "args": { "aspectRatio": "16:9" }
859
+ }
860
+ }
861
+ ```