minimal-agent 0.13.0 → 0.14.0

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 (470) hide show
  1. package/README.md +6 -5
  2. package/package.json +60 -4
  3. package/plugins/computer_use/.claude-plugin/plugin.json +1 -1
  4. package/plugins/cron-runner/src/commands.js +4 -4
  5. package/plugins/cron-runner/src/commands.ts +4 -4
  6. package/plugins/workflow-runner/.claude-plugin/plugin.json +2 -2
  7. package/plugins/workflow-runner/commands/workflow.md +57 -90
  8. package/plugins/workflow-runner/commands/workflows.md +4 -4
  9. package/plugins/workflow-runner/plugin.js +24 -13
  10. package/plugins/workflow-runner/plugin.ts +28 -13
  11. package/plugins/workflow-runner/src/discovery.js +160 -0
  12. package/plugins/workflow-runner/src/discovery.ts +194 -0
  13. package/plugins/workflow-runner/src/goalAnchor.js +53 -0
  14. package/plugins/workflow-runner/src/goalAnchor.ts +59 -0
  15. package/plugins/workflow-runner/src/index.js +197 -206
  16. package/plugins/workflow-runner/src/index.ts +248 -249
  17. package/plugins/workflow-runner/src/inputCoercion.js +40 -0
  18. package/plugins/workflow-runner/src/inputCoercion.ts +43 -0
  19. package/plugins/workflow-runner/src/journal.js +224 -0
  20. package/plugins/workflow-runner/src/journal.ts +274 -0
  21. package/plugins/workflow-runner/src/jsonSchema.js +132 -0
  22. package/plugins/workflow-runner/src/jsonSchema.ts +162 -0
  23. package/plugins/workflow-runner/src/moduleResolution.js +64 -0
  24. package/plugins/workflow-runner/src/moduleResolution.ts +71 -0
  25. package/plugins/workflow-runner/src/resourceInputs.js +220 -0
  26. package/plugins/workflow-runner/src/resourceInputs.ts +300 -0
  27. package/plugins/workflow-runner/src/runner.js +400 -489
  28. package/plugins/workflow-runner/src/runner.ts +488 -560
  29. package/plugins/workflow-runner/src/runtime/config.js +46 -0
  30. package/plugins/workflow-runner/src/runtime/config.ts +69 -0
  31. package/plugins/workflow-runner/src/runtime/context.js +1304 -0
  32. package/plugins/workflow-runner/src/runtime/context.ts +1786 -0
  33. package/plugins/workflow-runner/src/runtime/exec.js +34 -0
  34. package/plugins/workflow-runner/src/runtime/exec.ts +53 -0
  35. package/plugins/workflow-runner/src/runtime/flow.js +8 -0
  36. package/plugins/workflow-runner/src/runtime/flow.ts +12 -0
  37. package/plugins/workflow-runner/src/runtime/fs.js +27 -0
  38. package/plugins/workflow-runner/src/runtime/fs.ts +41 -0
  39. package/plugins/workflow-runner/src/runtime/model.js +6 -0
  40. package/plugins/workflow-runner/src/runtime/model.ts +8 -0
  41. package/plugins/workflow-runner/src/runtime/output.js +7 -0
  42. package/plugins/workflow-runner/src/runtime/output.ts +21 -0
  43. package/plugins/workflow-runner/src/runtime/scheduler.js +141 -0
  44. package/plugins/workflow-runner/src/runtime/scheduler.ts +166 -0
  45. package/plugins/workflow-runner/src/runtime/state.js +16 -0
  46. package/plugins/workflow-runner/src/runtime/state.ts +19 -0
  47. package/plugins/workflow-runner/src/runtime/tools.js +3 -0
  48. package/plugins/workflow-runner/src/runtime/tools.ts +6 -0
  49. package/plugins/workflow-runner/src/sandbox.js +141 -0
  50. package/plugins/workflow-runner/src/sandbox.ts +182 -0
  51. package/plugins/workflow-runner/src/scriptGuard.d.mts +38 -0
  52. package/plugins/workflow-runner/src/scriptGuard.mjs +449 -0
  53. package/plugins/workflow-runner/src/taskIdentity.js +151 -307
  54. package/plugins/workflow-runner/src/taskIdentity.ts +207 -355
  55. package/plugins/workflow-runner/src/toolRuntime.js +29 -8
  56. package/plugins/workflow-runner/src/toolRuntime.ts +36 -11
  57. package/plugins/workflow-runner/src/types.js +7 -211
  58. package/plugins/workflow-runner/src/types.ts +154 -623
  59. package/plugins/workflow-runner/src/util.js +47 -0
  60. package/plugins/workflow-runner/src/util.ts +51 -0
  61. package/plugins/workflow-runner/src/workflowContext.js +20 -0
  62. package/plugins/workflow-runner/src/workflowContext.ts +58 -0
  63. package/plugins/workflow-runner/src/workflowDependencies.js +36 -0
  64. package/plugins/workflow-runner/src/workflowDependencies.ts +59 -0
  65. package/plugins/workflow-runner/src/workflowFingerprint.js +118 -0
  66. package/plugins/workflow-runner/src/workflowFingerprint.ts +122 -0
  67. package/plugins/workflow-runner/src/workflowState.js +474 -802
  68. package/plugins/workflow-runner/src/workflowState.ts +575 -970
  69. package/plugins/workflow-runner/test/api.test.ts +223 -0
  70. package/plugins/workflow-runner/test/apiCapabilities.test.ts +614 -0
  71. package/plugins/workflow-runner/test/apiConcurrencyGate.test.ts +104 -0
  72. package/plugins/workflow-runner/test/apiEcho.test.ts +210 -0
  73. package/plugins/workflow-runner/test/apiReadText.test.ts +178 -0
  74. package/plugins/workflow-runner/test/apiResourceLedger.test.ts +184 -0
  75. package/plugins/workflow-runner/test/childWorkflow.test.ts +304 -0
  76. package/plugins/workflow-runner/test/discovery.test.ts +234 -0
  77. package/plugins/workflow-runner/test/goalAnchor.test.ts +106 -0
  78. package/plugins/workflow-runner/test/goalController.test.ts +317 -0
  79. package/plugins/workflow-runner/test/journalLanes.test.ts +198 -0
  80. package/plugins/workflow-runner/test/listResources.test.ts +106 -0
  81. package/plugins/workflow-runner/test/resourceInputs.test.ts +294 -0
  82. package/plugins/workflow-runner/test/sandbox.test.ts +126 -0
  83. package/plugins/workflow-runner/test/scheduler.test.ts +70 -0
  84. package/plugins/workflow-runner/test/scriptGuard.test.ts +276 -0
  85. package/plugins/workflow-runner/test/skillDocSync.test.ts +78 -0
  86. package/plugins/workflow-runner/test/taskIdentity.test.ts +288 -179
  87. package/plugins/workflow-runner/test/workflowFingerprint.test.ts +106 -0
  88. package/plugins/workflow-runner/test/workflowState.test.ts +429 -0
  89. package/skills/pptx/examples/assets/cover-bg.svg +23 -0
  90. package/skills/pptx/examples/assets/icon-spark.svg +5 -0
  91. package/skills/ui-design/SKILL.md +5 -2
  92. package/skills/ui-design/references/layout-composition.md +1 -1
  93. package/skills/workflow-creator/SKILL.md +344 -0
  94. package/skills/workflow-creator/assets/template/workflow.mjs +48 -0
  95. package/skills/workflow-creator/references/api.md +216 -0
  96. package/skills/workflow-creator/references/migration.md +103 -0
  97. package/skills/workflow-creator/references/patterns.md +779 -0
  98. package/skills/workflow-creator/scripts/list-resources.mjs +205 -0
  99. package/skills/workflow-creator/scripts/scaffold.mjs +148 -0
  100. package/skills/workflow-creator/scripts/validate.mjs +275 -0
  101. package/skills/workflow-creator/scripts/workflow-creator.test.mjs +82 -0
  102. package/src/advisor/advisorCoordinator.js +503 -0
  103. package/src/advisor/advisorCoordinator.ts +657 -0
  104. package/src/cli/configMenu.tsx +0 -1
  105. package/src/cli/print.js +27 -6
  106. package/src/cli/print.ts +48 -4
  107. package/src/cli/streamJson.js +5 -6
  108. package/src/cli/streamJson.ts +8 -4
  109. package/src/cli/wizards/advisorWizard.js +4 -2
  110. package/src/cli/wizards/advisorWizard.tsx +8 -2
  111. package/src/cli/wizards/contextAdvisorWizard.js +5 -4
  112. package/src/cli/wizards/contextAdvisorWizard.tsx +7 -6
  113. package/src/collaboration/taskFlow.js +115 -0
  114. package/src/collaboration/taskFlow.ts +169 -0
  115. package/src/config/configDefaults.js +41 -1
  116. package/src/config/configDefaults.ts +43 -1
  117. package/src/config/configDiagnostics.ts +2 -2
  118. package/src/config/configFile.js +40 -9
  119. package/src/config/configFile.ts +60 -11
  120. package/src/config/configService.js +419 -74
  121. package/src/config/configService.ts +703 -145
  122. package/src/config/numericLimits.js +22 -0
  123. package/src/config/numericLimits.ts +24 -0
  124. package/src/config.js +1 -0
  125. package/src/config.ts +3 -2
  126. package/src/context/budgetPlan.js +1 -1
  127. package/src/context/budgetPlan.ts +1 -1
  128. package/src/context/compact.js +7 -2
  129. package/src/context/compact.ts +9 -2
  130. package/src/context/microCompactLite.js +212 -13
  131. package/src/context/microCompactLite.ts +261 -12
  132. package/src/context/sessionRegistry.js +8 -1
  133. package/src/context/sessionRegistry.ts +18 -5
  134. package/src/context/toolResultArchive.js +72 -0
  135. package/src/context/toolResultArchive.ts +95 -0
  136. package/src/goal/errors.js +8 -0
  137. package/src/goal/errors.ts +18 -0
  138. package/src/goal/goalRuntime.js +344 -0
  139. package/src/goal/goalRuntime.ts +466 -0
  140. package/src/goal/goalStore.js +200 -0
  141. package/src/goal/goalStore.ts +219 -0
  142. package/src/goal/index.js +4 -0
  143. package/src/goal/index.ts +4 -0
  144. package/src/goal/statusMapping.js +71 -0
  145. package/src/goal/statusMapping.ts +95 -0
  146. package/src/goal/types.js +7 -0
  147. package/src/goal/types.ts +179 -0
  148. package/src/goal/workflowController.js +306 -0
  149. package/src/goal/workflowController.ts +360 -0
  150. package/src/harness/evidenceLedger.js +2 -0
  151. package/src/harness/evidenceLedger.ts +1 -0
  152. package/src/harness/stallGuard.js +9 -3
  153. package/src/harness/stallGuard.ts +7 -3
  154. package/src/images/imageResolver.js +161 -0
  155. package/src/images/imageResolver.ts +189 -0
  156. package/src/infra/verification.js +34 -5
  157. package/src/infra/verification.ts +39 -4
  158. package/src/llm/client.js +79 -21
  159. package/src/llm/client.ts +182 -35
  160. package/src/llm/gatewayClient.js +201 -0
  161. package/src/llm/gatewayClient.ts +299 -0
  162. package/src/llm/messageProvenance.js +46 -0
  163. package/src/llm/messageProvenance.ts +58 -0
  164. package/src/llm/modelProvider.js +1 -0
  165. package/src/llm/modelProvider.ts +22 -0
  166. package/src/llm/providers/anthropicFormat.js +108 -1
  167. package/src/llm/providers/anthropicFormat.ts +115 -4
  168. package/src/llm/providers/openaiFormat.js +9 -0
  169. package/src/llm/providers/openaiFormat.ts +12 -3
  170. package/src/loop.js +319 -54
  171. package/src/loop.ts +373 -57
  172. package/src/main.js +4 -1
  173. package/src/main.tsx +4 -1
  174. package/src/managedExecution/index.js +2 -0
  175. package/src/managedExecution/index.ts +2 -0
  176. package/src/managedExecution/registry.js +15 -0
  177. package/src/managedExecution/registry.ts +20 -0
  178. package/src/managedExecution/types.js +1 -0
  179. package/src/managedExecution/types.ts +86 -0
  180. package/src/modelRef.js +9 -0
  181. package/src/modelRef.ts +31 -0
  182. package/src/multimodal.js +14 -28
  183. package/src/multimodal.ts +17 -33
  184. package/src/net/lanDiscovery.js +65 -0
  185. package/src/net/lanDiscovery.ts +82 -0
  186. package/src/plugin-sdk.js +28 -3
  187. package/src/plugin-sdk.ts +39 -6
  188. package/src/plugins/pluginApi.ts +16 -1
  189. package/src/plugins/pluginLoader.js +4 -0
  190. package/src/plugins/pluginLoader.ts +6 -0
  191. package/src/plugins/pluginRunner.js +139 -7
  192. package/src/plugins/pluginRunner.ts +173 -9
  193. package/src/plugins/slashFallback.js +113 -0
  194. package/src/plugins/slashFallback.ts +137 -0
  195. package/src/prompts/policyRegistry.js +12 -32
  196. package/src/prompts/policyRegistry.ts +15 -32
  197. package/src/prompts/promptAssembly.js +103 -12
  198. package/src/prompts/promptAssembly.ts +114 -12
  199. package/src/prompts/skillList.js +21 -3
  200. package/src/prompts/skillList.ts +27 -2
  201. package/src/prompts/stableSystemPrompt.js +18 -0
  202. package/src/prompts/stableSystemPrompt.ts +33 -0
  203. package/src/runtime/agentRuntimeContext.js +8 -2
  204. package/src/runtime/agentRuntimeContext.ts +17 -4
  205. package/src/session/runAgentTurn.js +78 -12
  206. package/src/session/runAgentTurn.ts +105 -23
  207. package/src/session/runTurn.js +10 -9
  208. package/src/session/runTurn.ts +17 -8
  209. package/src/session/sessionState.ts +2 -0
  210. package/src/team/auth.js +186 -0
  211. package/src/team/auth.ts +298 -0
  212. package/src/team/cli.js +105 -0
  213. package/src/team/cli.ts +122 -0
  214. package/src/team/onlineToolContract.js +64 -0
  215. package/src/team/onlineToolContract.ts +109 -0
  216. package/src/team/toolPolicy.js +36 -0
  217. package/src/team/toolPolicy.ts +75 -0
  218. package/src/tools/advisor/advisor.js +90 -46
  219. package/src/tools/advisor/advisor.ts +100 -47
  220. package/src/tools/advisor/advisorDecision.js +71 -0
  221. package/src/tools/advisor/advisorDecision.ts +85 -0
  222. package/src/tools/agent/agent.js +18 -5
  223. package/src/tools/agent/agent.ts +21 -7
  224. package/src/tools/agent/agentControl.js +246 -0
  225. package/src/tools/agent/agentControl.ts +284 -0
  226. package/src/tools/agent/agentTaskService.js +40 -1
  227. package/src/tools/agent/agentTaskService.ts +44 -1
  228. package/src/tools/agent/agentTypes.js +14 -2
  229. package/src/tools/agent/agentTypes.ts +15 -2
  230. package/src/tools/applypatch/applyPatch.js +362 -0
  231. package/src/tools/applypatch/applyPatch.ts +428 -0
  232. package/src/tools/bash/bash.js +22 -15
  233. package/src/tools/bash/bash.ts +23 -17
  234. package/src/tools/capabilities.js +10 -5
  235. package/src/tools/capabilities.ts +10 -5
  236. package/src/tools/computeruse/computerIntent.js +32 -0
  237. package/src/tools/computeruse/computerIntent.ts +46 -0
  238. package/src/tools/computeruse/telemetryLog.js +12 -0
  239. package/src/tools/computeruse/telemetryLog.ts +16 -0
  240. package/src/tools/computeruse/vision/telemetry.js +1 -0
  241. package/src/tools/computeruse/vision/telemetry.ts +1 -0
  242. package/src/tools/effectiveToolSet.js +4 -0
  243. package/src/tools/effectiveToolSet.ts +4 -0
  244. package/src/tools/index.js +21 -2
  245. package/src/tools/index.ts +33 -2
  246. package/src/tools/presentresult/presentresult.js +6 -15
  247. package/src/tools/presentresult/presentresult.ts +6 -15
  248. package/src/tools/read/read.js +62 -9
  249. package/src/tools/read/read.ts +63 -9
  250. package/src/tools/shared/fileUtils.js +1 -2
  251. package/src/tools/shared/fileUtils.ts +1 -2
  252. package/src/tools/shared/toolOutputStore.js +23 -1
  253. package/src/tools/shared/toolOutputStore.ts +22 -1
  254. package/src/tools/skill/skill.js +9 -3
  255. package/src/tools/skill/skill.ts +8 -4
  256. package/src/tools/toolPromptGuides.js +117 -0
  257. package/src/tools/toolPromptGuides.ts +137 -0
  258. package/src/tools/webbrowser/agentBrowserPath.js +19 -9
  259. package/src/tools/webbrowser/agentBrowserPath.ts +70 -28
  260. package/src/tools/webbrowser/browser.js +27 -11
  261. package/src/tools/webbrowser/browser.ts +68 -24
  262. package/src/tools/webbrowser/browserAutomation.js +329 -0
  263. package/src/tools/webbrowser/browserAutomation.ts +467 -0
  264. package/src/tools/webbrowser/browserAxState.js +97 -0
  265. package/src/tools/webbrowser/browserAxState.ts +142 -0
  266. package/src/tools/webbrowser/browserBatch.js +1578 -0
  267. package/src/tools/webbrowser/browserBatch.ts +2382 -0
  268. package/src/tools/webbrowser/browserCdp.js +208 -0
  269. package/src/tools/webbrowser/browserCdp.ts +255 -0
  270. package/src/tools/webbrowser/browserConditions.js +24 -0
  271. package/src/tools/webbrowser/browserConditions.ts +45 -0
  272. package/src/tools/webbrowser/browserContent.js +281 -0
  273. package/src/tools/webbrowser/browserContent.ts +438 -0
  274. package/src/tools/webbrowser/browserControl.js +131 -34
  275. package/src/tools/webbrowser/browserControl.ts +210 -56
  276. package/src/tools/webbrowser/browserDaemon.js +22 -14
  277. package/src/tools/webbrowser/browserDaemon.ts +54 -21
  278. package/src/tools/webbrowser/browserFrames.js +47 -0
  279. package/src/tools/webbrowser/browserFrames.ts +54 -0
  280. package/src/tools/webbrowser/browserInteractionResolver.js +17 -0
  281. package/src/tools/webbrowser/browserInteractionResolver.ts +40 -0
  282. package/src/tools/webbrowser/browserLocator.js +140 -0
  283. package/src/tools/webbrowser/browserLocator.ts +194 -0
  284. package/src/tools/webbrowser/browserOutcome.js +10 -17
  285. package/src/tools/webbrowser/browserOutcome.ts +48 -31
  286. package/src/tools/webbrowser/browserRecovery.js +58 -0
  287. package/src/tools/webbrowser/browserRecovery.ts +83 -0
  288. package/src/tools/webbrowser/browserRunRegistry.js +35 -3
  289. package/src/tools/webbrowser/browserRunRegistry.ts +91 -15
  290. package/src/tools/webbrowser/browserService.js +28 -2
  291. package/src/tools/webbrowser/browserService.ts +49 -9
  292. package/src/tools/webbrowser/browserStream.js +132 -33
  293. package/src/tools/webbrowser/browserStream.ts +224 -50
  294. package/src/tools/webbrowser/browserTabs.js +48 -15
  295. package/src/tools/webbrowser/browserTabs.ts +178 -96
  296. package/src/tools/webbrowser/webbrowser.js +679 -144
  297. package/src/tools/webbrowser/webbrowser.ts +975 -236
  298. package/src/tools/webfetch/preapproved.js +0 -2
  299. package/src/tools/webfetch/preapproved.ts +0 -2
  300. package/src/tools/websearch/websearch.js +129 -8
  301. package/src/tools/websearch/websearch.ts +138 -6
  302. package/src/types.ts +440 -38
  303. package/src/ui/App.js +377 -58
  304. package/src/ui/App.tsx +576 -111
  305. package/src/ui/LiveArea.js +14 -8
  306. package/src/ui/LiveArea.tsx +14 -10
  307. package/src/ui/MessageList.js +63 -20
  308. package/src/ui/MessageList.tsx +101 -16
  309. package/src/ui/ModelPicker.js +7 -4
  310. package/src/ui/ModelPicker.tsx +55 -8
  311. package/src/ui/hooks/useChat.js +152 -163
  312. package/src/ui/hooks/useChat.ts +396 -334
  313. package/src/ui/loginCommand.js +56 -0
  314. package/src/ui/loginCommand.ts +63 -0
  315. package/src/ui/toolProgress.js +41 -0
  316. package/src/ui/toolProgress.ts +44 -0
  317. package/src/web/browserBridge.js +20 -2
  318. package/src/web/browserBridge.ts +20 -2
  319. package/src/web/protocol.ts +1897 -194
  320. package/workflows/adaptive-research/workflow.mjs +86 -0
  321. package/workflows/e2e-capabilities/workflow.mjs +102 -0
  322. package/workflows/e2e-llm/workflow.mjs +52 -0
  323. package/workflows/e2e-smoke/workflow.mjs +59 -0
  324. package/workflows/e2e-vision-schema/README.md +48 -0
  325. package/workflows/e2e-vision-schema/workflow.mjs +149 -0
  326. package/workflows/e2e-write-greet/workflow.mjs +37 -0
  327. package/workflows/file-census/README.md +14 -0
  328. package/workflows/file-census/scripts/.gitkeep +2 -0
  329. package/workflows/file-census/workflow.mjs +110 -0
  330. package/workflows/goal/README.md +166 -0
  331. package/workflows/goal/prompts/audit.md +57 -0
  332. package/workflows/goal/prompts/contract.md +56 -0
  333. package/workflows/goal/prompts/iterate.md +37 -0
  334. package/workflows/goal/workflow.mjs +501 -0
  335. package/workflows/illustrate/README.md +90 -0
  336. package/workflows/illustrate/assets/engines.json +20 -0
  337. package/workflows/illustrate/assets/extract-baidu.js +21 -0
  338. package/workflows/illustrate/assets/extract-bing.js +33 -0
  339. package/workflows/illustrate/assets/extract-google.js +31 -0
  340. package/workflows/illustrate/workflow.mjs +301 -0
  341. package/workflows/plan/workflow.mjs +389 -0
  342. package/workflows/question-crops/README.md +35 -0
  343. package/workflows/question-crops/prompts/inventory.md +23 -0
  344. package/workflows/question-crops/scripts/image-ops.mjs +305 -0
  345. package/workflows/question-crops/scripts/image-ops.test.mjs +95 -0
  346. package/workflows/question-crops/workflow.mjs +172 -0
  347. package/workflows/ralph-loop/workflow.mjs +162 -0
  348. package/workflows/research/README.md +74 -0
  349. package/workflows/research/prompts/s0-goal.md +43 -0
  350. package/workflows/research/prompts/s1-early-exit.md +22 -0
  351. package/workflows/research/prompts/s1-map.md +58 -0
  352. package/workflows/research/prompts/s2-options.md +53 -0
  353. package/workflows/research/prompts/s3-deep-dive.md +56 -0
  354. package/workflows/research/prompts/s4-verify.md +74 -0
  355. package/workflows/research/prompts/s5-synthesis.md +81 -0
  356. package/workflows/research/prompts/s5b-fill-gaps.md +32 -0
  357. package/workflows/research/prompts/s6-package.md +32 -0
  358. package/workflows/research/scripts/build-report.mjs +98 -0
  359. package/workflows/research/workflow.mjs +288 -0
  360. package/workflows/wechat-reading-shots/prompts/collect-params.md +16 -0
  361. package/workflows/wechat-reading-shots/prompts/evaluate.md +20 -0
  362. package/workflows/wechat-reading-shots/prompts/open-book.md +28 -0
  363. package/workflows/wechat-reading-shots/prompts/read-page.md +13 -0
  364. package/workflows/wechat-reading-shots/prompts/turn-batch.md +24 -0
  365. package/workflows/wechat-reading-shots/test/control-flow.test.ts +329 -0
  366. package/workflows/wechat-reading-shots/workflow.mjs +266 -0
  367. package/workflows/wrong-question-docx/README.md +55 -0
  368. package/workflows/wrong-question-docx/prompts/figure-qa.md +8 -0
  369. package/workflows/wrong-question-docx/prompts/transcribe.md +25 -0
  370. package/workflows/wrong-question-docx/scripts/workbook.mjs +857 -0
  371. package/workflows/wrong-question-docx/test/control-flow.test.ts +165 -0
  372. package/workflows/wrong-question-docx/test/workbook.test.mjs +303 -0
  373. package/workflows/wrong-question-docx/workflow.mjs +485 -0
  374. package/plugins/workflow-runner/src/agentCommon.js +0 -354
  375. package/plugins/workflow-runner/src/agentCommon.ts +0 -435
  376. package/plugins/workflow-runner/src/controlFlow/branch.js +0 -40
  377. package/plugins/workflow-runner/src/controlFlow/branch.ts +0 -46
  378. package/plugins/workflow-runner/src/controlFlow/loop.js +0 -211
  379. package/plugins/workflow-runner/src/controlFlow/loop.ts +0 -248
  380. package/plugins/workflow-runner/src/controlFlow/pause.js +0 -129
  381. package/plugins/workflow-runner/src/controlFlow/pause.ts +0 -141
  382. package/plugins/workflow-runner/src/controlFlow/signal.js +0 -21
  383. package/plugins/workflow-runner/src/controlFlow/signal.ts +0 -29
  384. package/plugins/workflow-runner/src/controlFlow/types.js +0 -18
  385. package/plugins/workflow-runner/src/controlFlow/types.ts +0 -63
  386. package/plugins/workflow-runner/src/dslManifest.js +0 -72
  387. package/plugins/workflow-runner/src/dslManifest.ts +0 -127
  388. package/plugins/workflow-runner/src/expressions.js +0 -639
  389. package/plugins/workflow-runner/src/expressions.ts +0 -640
  390. package/plugins/workflow-runner/src/loader.js +0 -573
  391. package/plugins/workflow-runner/src/loader.ts +0 -721
  392. package/plugins/workflow-runner/src/multimodal.js +0 -38
  393. package/plugins/workflow-runner/src/multimodal.ts +0 -64
  394. package/plugins/workflow-runner/src/recovery.js +0 -126
  395. package/plugins/workflow-runner/src/recovery.ts +0 -156
  396. package/plugins/workflow-runner/src/stepExecutors/agent.js +0 -173
  397. package/plugins/workflow-runner/src/stepExecutors/agent.ts +0 -234
  398. package/plugins/workflow-runner/src/stepExecutors/assert.js +0 -42
  399. package/plugins/workflow-runner/src/stepExecutors/assert.ts +0 -52
  400. package/plugins/workflow-runner/src/stepExecutors/echo.js +0 -31
  401. package/plugins/workflow-runner/src/stepExecutors/echo.ts +0 -38
  402. package/plugins/workflow-runner/src/stepExecutors/llm.js +0 -99
  403. package/plugins/workflow-runner/src/stepExecutors/llm.ts +0 -133
  404. package/plugins/workflow-runner/src/stepExecutors/set.js +0 -49
  405. package/plugins/workflow-runner/src/stepExecutors/set.ts +0 -56
  406. package/plugins/workflow-runner/src/stepExecutors/skill.js +0 -111
  407. package/plugins/workflow-runner/src/stepExecutors/skill.ts +0 -140
  408. package/plugins/workflow-runner/src/stepExecutors/tool.js +0 -227
  409. package/plugins/workflow-runner/src/stepExecutors/tool.ts +0 -274
  410. package/plugins/workflow-runner/src/stepExecutors/verify.js +0 -61
  411. package/plugins/workflow-runner/src/stepExecutors/verify.ts +0 -72
  412. package/plugins/workflow-runner/src/stepPipeline.js +0 -277
  413. package/plugins/workflow-runner/src/stepPipeline.ts +0 -366
  414. package/plugins/workflow-runner/test/agent.test.ts +0 -587
  415. package/plugins/workflow-runner/test/agentLlmError.test.ts +0 -373
  416. package/plugins/workflow-runner/test/bashBlacklist.sweep.test.ts +0 -65
  417. package/plugins/workflow-runner/test/captureMisbind.test.ts +0 -99
  418. package/plugins/workflow-runner/test/cli.e2e.test.ts +0 -167
  419. package/plugins/workflow-runner/test/context-files.test.ts +0 -320
  420. package/plugins/workflow-runner/test/e2e.test.ts +0 -370
  421. package/plugins/workflow-runner/test/e2eNewLayout.test.ts +0 -314
  422. package/plugins/workflow-runner/test/engineRobustness.test.ts +0 -234
  423. package/plugins/workflow-runner/test/expressions.test.ts +0 -439
  424. package/plugins/workflow-runner/test/foundation.test.ts +0 -126
  425. package/plugins/workflow-runner/test/graceful.test.ts +0 -139
  426. package/plugins/workflow-runner/test/greedyInputs.load.test.ts +0 -47
  427. package/plugins/workflow-runner/test/hostCapability.test.ts +0 -108
  428. package/plugins/workflow-runner/test/illustrate.load.test.ts +0 -183
  429. package/plugins/workflow-runner/test/jsonPayload.test.ts +0 -83
  430. package/plugins/workflow-runner/test/loader.test.ts +0 -617
  431. package/plugins/workflow-runner/test/maxTurnsRetryDelay.test.ts +0 -33
  432. package/plugins/workflow-runner/test/multimodal.test.ts +0 -342
  433. package/plugins/workflow-runner/test/output-schema.test.ts +0 -213
  434. package/plugins/workflow-runner/test/parseWorkflowArgs.test.ts +0 -106
  435. package/plugins/workflow-runner/test/pluginRunner.isolation.test.ts +0 -269
  436. package/plugins/workflow-runner/test/ppt.load.test.ts +0 -1220
  437. package/plugins/workflow-runner/test/ralphLoop.e2e.test.ts +0 -221
  438. package/plugins/workflow-runner/test/recovery.test.ts +0 -265
  439. package/plugins/workflow-runner/test/research.load.test.ts +0 -328
  440. package/plugins/workflow-runner/test/runner.test.ts +0 -911
  441. package/plugins/workflow-runner/test/runnerPreflight.test.ts +0 -436
  442. package/plugins/workflow-runner/test/skillTurnDone.test.ts +0 -71
  443. package/plugins/workflow-runner/test/stateLifecycle.test.ts +0 -198
  444. package/plugins/workflow-runner/test/stepPipeline.test.ts +0 -114
  445. package/plugins/workflow-runner/test/taskArbitration.test.ts +0 -354
  446. package/plugins/workflow-runner/test/taskLifecycle.test.ts +0 -324
  447. package/plugins/workflow-runner/test/toolArtifactOverwrite.test.ts +0 -221
  448. package/plugins/workflow-runner/test/toolCapabilityBoundary.test.ts +0 -29
  449. package/plugins/workflow-runner/test/toolRuntimeIntegration.test.ts +0 -168
  450. package/plugins/workflow-runner/test/webppt.load.test.ts +0 -250
  451. package/plugins/workflow-runner/test/word.load.test.ts +0 -208
  452. package/plugins/workflow-runner/test/workflows.smoke.test.ts +0 -76
  453. package/plugins/workflow-runner/test/yamlGuardConditions.test.ts +0 -207
  454. package/src/advisorState.js +0 -22
  455. package/src/cli/configWizard.js +0 -293
  456. package/src/tools/toolProgressBridge.js +0 -48
  457. package/workflows/adaptive-research.yaml +0 -50
  458. package/workflows/book-review-short.yaml +0 -125
  459. package/workflows/e2e-write-greet.yaml +0 -31
  460. package/workflows/illustrate.yaml +0 -227
  461. package/workflows/plan.yaml +0 -470
  462. package/workflows/ppt.yaml +0 -1670
  463. package/workflows/ralph-loop.yaml +0 -201
  464. package/workflows/research.yaml +0 -873
  465. package/workflows/schema.json +0 -176
  466. package/workflows/webppt.yaml +0 -496
  467. package/workflows/wechat-reading-shots.yaml +0 -315
  468. package/workflows/word.yaml +0 -720
  469. package/workflows/youtube-shorts.yaml +0 -202
  470. /package/workflows/{research.md → research/DESIGN.md} +0 -0
@@ -1,436 +0,0 @@
1
- /**
2
- * ============================================================
3
- * test/runnerPreflight.test.ts —— Runner Pre-flight & Self-heal 单元测试
4
- * ------------------------------------------------------------
5
- * 覆盖 runWorkflow 的前置流程和自愈重试机制:
6
- *
7
- * Pre-flight(任务身份判定 + 断点续执行):
8
- * - fresh 模式:正常启动,无恢复信息
9
- * - completed 模式:返回已完成提示(需手动构造状态)
10
- * - resume 模式:回放 capture 变量 + 跳过已完成步骤
11
- * - goalAnchor 构建与注入
12
- * - archive 成功后清理状态目录
13
- *
14
- * Self-heal / Retry:
15
- * - step 失败后自动 retry(max_retries 控制)
16
- * - backoff 回退 N 步重跑
17
- * - step.max_retries 覆盖全局配置
18
- * - retry 用尽后走 onError 逻辑
19
- *
20
- * 设计原则:
21
- * - 用 assert step 构造成功/失败路径(无需 mock LLM)
22
- * - 通过 runWorkflow 集成测试验证行为(避免直接实例化 WorkflowState 的 Bun 兼容性问题)
23
- * - 观察事件流判断内部状态转换是否正确
24
- * ============================================================ */
25
-
26
- import { afterEach, beforeEach, describe, expect, it, mock } from 'bun:test';
27
- import {
28
- existsSync,
29
- mkdirSync,
30
- mkdtempSync,
31
- readdirSync,
32
- readFileSync,
33
- rmSync,
34
- writeFileSync,
35
- } from 'node:fs';
36
- import { tmpdir } from 'node:os';
37
- import { join } from 'node:path';
38
-
39
- import { _resetWorkingDir } from '../../../src/bootstrap/workingDir.js';
40
- import { createAgentRuntimeContext } from '../../../src/plugin-sdk.js';
41
- import { ALL_TOOLS } from '../../../src/tools/index.js';
42
- import { runWorkflow } from '../src/runner.js';
43
- import type { LoopEvent, Provider } from '../../../src/types.js';
44
- import type { RunContext, WorkflowDef, WorkflowEvent } from '../src/types.js';
45
-
46
- type WfOrLoop = WorkflowEvent | LoopEvent;
47
-
48
- const DEFAULT_SESSION = 'test-session';
49
-
50
- function findInstanceDir(base: string, wfName: string, suffix = ''): string | null {
51
- const wfDir = join(base, '.minimal-agent-workflow', wfName);
52
- if (!existsSync(wfDir)) {
53
- const legacyDir = suffix
54
- ? join(base, '.minimal-agent-workflow', wfName + suffix)
55
- : wfDir;
56
- if (existsSync(legacyDir)) return legacyDir;
57
- return null;
58
- }
59
-
60
- // Phase 3:session 化——实例目录名 = sessionId(默认 'default')
61
- const sessionDir = suffix
62
- ? join(wfDir, DEFAULT_SESSION + suffix)
63
- : join(wfDir, DEFAULT_SESSION);
64
- if (existsSync(sessionDir)) return sessionDir;
65
-
66
- // 旧布局兼容:wfDir 本身有 current.json(无子实例目录时判定为 legacy)
67
- if (!suffix && existsSync(join(wfDir, 'current.json'))) {
68
- try {
69
- const entries = readdirSync(wfDir, { withFileTypes: true });
70
- const hasInstanceSubdir = entries.some(
71
- (e) => e.isDirectory() && /^[0-9a-f]{16}$/.test(e.name),
72
- );
73
- if (!hasInstanceSubdir) return wfDir;
74
- } catch {
75
- return wfDir;
76
- }
77
- }
78
- return null;
79
- }
80
-
81
- function hasInstance(base: string, wfName: string, suffix = ''): boolean {
82
- return findInstanceDir(base, wfName, suffix) !== null;
83
- }
84
-
85
- const fakeProvider: Provider = {
86
- name: 'test',
87
- baseURL: '',
88
- apiKey: '',
89
- model: 'm',
90
- contextWindow: 128000,
91
- };
92
-
93
- async function collect(
94
- gen: AsyncGenerator<WfOrLoop, void, void>,
95
- ): Promise<WfOrLoop[]> {
96
- const out: WfOrLoop[] = [];
97
- for await (const ev of gen) out.push(ev);
98
- return out;
99
- }
100
-
101
- describe('runner::pre-flight fresh 模式', () => {
102
- let tmp: string;
103
- let ctx: RunContext;
104
-
105
- beforeEach(() => {
106
- tmp = mkdtempSync(join(tmpdir(), 'wf-preflight-'));
107
- process.env.MINIMAL_AGENT_CWD = tmp;
108
- _resetWorkingDir();
109
- mock.module('../../../src/bootstrap/workingDir.js', () => ({
110
- getWorkingDir: () => tmp,
111
- initWorkingDir: () => tmp,
112
- _resetWorkingDir: () => {},
113
- }));
114
- ctx = {
115
- provider: fakeProvider,
116
- history: [],
117
- cwd: tmp,
118
- tools: [],
119
- runtimeContext: createAgentRuntimeContext({ surface: 'workflow', profile: 'main', cwd: tmp, sessionId: DEFAULT_SESSION, owner: 'local-owner', interactiveAsk: false }),
120
- };
121
- });
122
-
123
- afterEach(() => {
124
- delete process.env.MINIMAL_AGENT_CWD;
125
- _resetWorkingDir();
126
- rmSync(tmp, { recursive: true, force: true });
127
- });
128
-
129
- it('首次运行 → workflow_start + 正常执行 + workflow_done', async () => {
130
- const def: WorkflowDef = {
131
- name: 'fresh-test',
132
- description: 'd',
133
- steps: [{ id: 's1', type: 'assert', condition: 'true' }],
134
- };
135
- const events = await collect(runWorkflow(def, {}, ctx));
136
- expect(events.some((e) => e.type === 'workflow_start')).toBe(true);
137
- expect(events.some((e) => e.type === 'workflow_done')).toBe(true);
138
- // 不应有 completed 提示
139
- expect(events.find((e) => e.type === 'text' && String(e).includes('已完成'))).toBeUndefined();
140
- });
141
- });
142
-
143
- describe('runner::pre-flight completed 模式(架构说明)', () => {
144
- // ⚠️ 注意:completed 模式的集成测试需要精确匹配 taskId hash,
145
- // 而 taskId 由 taskIdentity.ts::computeTaskId() 计算(含归一化 + SHA256 截断)。
146
- // 直接构造匹配的 current.json 脆且容易因归一化规则调整而断裂。
147
- //
148
- // 已有覆盖:
149
- // - taskIdentity.test.ts: 完整测试 computeTaskId 的 hash / 时间窗口 / 匹配逻辑
150
- // - stateLifecycle.test.ts: 通过 runWorkflow 成功→archive 验证状态目录生命周期
151
- // - 本文件 resume 测试: 验证失败后重跑进入 resume 模式
152
- //
153
- // 结论:completed 分支的正确性由上述测试联合保证,无需再写一个脆弱的集成测试。
154
-
155
- it('占位:completed 模式已由 taskIdentity.test.ts + stateLifecycle.test.ts 联合覆盖', () => {
156
- expect(true).toBe(true);
157
- });
158
- });
159
-
160
- describe('runner::resume 与断点续执行', () => {
161
- let tmp: string;
162
- let ctx: RunContext;
163
-
164
- beforeEach(() => {
165
- tmp = mkdtempSync(join(tmpdir(), 'wf-resume-'));
166
- process.env.MINIMAL_AGENT_CWD = tmp;
167
- _resetWorkingDir();
168
- mock.module('../../../src/bootstrap/workingDir.js', () => ({
169
- getWorkingDir: () => tmp,
170
- initWorkingDir: () => tmp,
171
- _resetWorkingDir: () => {},
172
- }));
173
- ctx = {
174
- provider: fakeProvider,
175
- history: [],
176
- cwd: tmp,
177
- tools: ALL_TOOLS,
178
- runtimeContext: createAgentRuntimeContext({ surface: 'workflow', profile: 'main', cwd: tmp, sessionId: DEFAULT_SESSION, owner: 'local-owner', interactiveAsk: false }),
179
- };
180
- });
181
-
182
- afterEach(() => {
183
- delete process.env.MINIMAL_AGENT_CWD;
184
- _resetWorkingDir();
185
- rmSync(tmp, { recursive: true, force: true });
186
- });
187
-
188
- it('失败后重跑 → 进入 resume 模式 → 跳过已完成步骤', async () => {
189
- const def: WorkflowDef = {
190
- name: 'resume-test',
191
- description: 'd',
192
- self_heal: { backoff: 0, max_retries: 0 }, // 禁用 retry 让它自然 halt
193
- steps: [
194
- { id: 'write', tool: 'Write', args: { file_path: 'data.txt', content: 'hello' }, capture: { content: 'captured_text' } },
195
- { id: 'check', type: 'assert', condition: "captured_text == 'hello'" },
196
- { id: 'fail', type: 'assert', condition: 'false', onFail: 'intentional fail' },
197
- { id: 'after_fail', type: 'assert', condition: 'true' },
198
- ],
199
- };
200
-
201
- // 第一次运行:前两步成功,第三步失败
202
- const events1 = await collect(runWorkflow(def, { goal: 'target' }, ctx));
203
- expect(events1.some((e) => e.type === 'error')).toBe(true); // halt
204
- expect(events1.some((e) => e.type === 'workflow_done')).toBe(false);
205
-
206
- // 第二次运行:应进入 resume 模式(时间窗口内同一任务)
207
- const events2 = await collect(runWorkflow(def, { goal: 'target' }, ctx));
208
-
209
- // 应有某种恢复相关的事件(text 或 warning)
210
- const hasResumeInfo =
211
- events2.some((e) => e.type === 'text' && String(e).includes('未完成')) ||
212
- events2.some((e) => e.type === 'text' && String(e).includes('恢复'));
213
-
214
- // 已完成的步骤可能被跳过(取决于实现细节)
215
- const skippedIds = events2
216
- .filter((e): e is Extract<WorkflowEvent, { type: 'workflow_step_skipped' }> =>
217
- e.type === 'workflow_step_skipped')
218
- .map((e) => e.id);
219
-
220
- // 最终仍会失败(因为 fail 步骤仍然失败且 retry=0)
221
- expect(events2.some((e) => e.type === 'error')).toBe(true);
222
- });
223
- });
224
-
225
- describe('runner::goalAnchor 构建', () => {
226
- it('inputs.goal 存在 → workflow 正常运行(间接验证 goalAnchor 不报错)', async () => {
227
- const tmp = mkdtempSync(join(tmpdir(), 'wf-goal-'));
228
- process.env.MINIMAL_AGENT_CWD = tmp;
229
- _resetWorkingDir();
230
- mock.module('../../../src/bootstrap/workingDir.js', () => ({
231
- getWorkingDir: () => tmp,
232
- initWorkingDir: () => tmp,
233
- _resetWorkingDir: () => {},
234
- }));
235
-
236
- try {
237
- const def: WorkflowDef = {
238
- name: 'goal-test',
239
- description: 'd',
240
- inputs: [{ name: 'goal', type: 'string', required: true }],
241
- steps: [{ id: 's1', type: 'assert', condition: 'true' }],
242
- };
243
-
244
- const ctx: RunContext = {
245
- provider: fakeProvider,
246
- history: [],
247
- cwd: tmp,
248
- tools: [],
249
- };
250
-
251
- const events = await collect(runWorkflow(def, { goal: '实现用户认证模块' }, ctx));
252
- expect(events.some((e) => e.type === 'workflow_done')).toBe(true);
253
- } finally {
254
- delete process.env.MINIMAL_AGENT_CWD;
255
- _resetWorkingDir();
256
- rmSync(tmp, { recursive: true, force: true });
257
- }
258
- });
259
-
260
- it('无 string 类型 inputs → goalAnchor 为空(不报错)', async () => {
261
- const tmp = mkdtempSync(join(tmpdir(), 'wf-nogoal-'));
262
- process.env.MINIMAL_AGENT_CWD = tmp;
263
- _resetWorkingDir();
264
- mock.module('../../../src/bootstrap/workingDir.js', () => ({
265
- getWorkingDir: () => tmp,
266
- initWorkingDir: () => tmp,
267
- _resetWorkingDir: () => {},
268
- }));
269
-
270
- try {
271
- const def: WorkflowDef = {
272
- name: 'no-goal-test',
273
- description: 'd',
274
- inputs: [{ name: 'count', type: 'number' }],
275
- steps: [{ id: 's1', type: 'assert', condition: 'true' }],
276
- };
277
-
278
- const ctx: RunContext = {
279
- provider: fakeProvider,
280
- history: [],
281
- cwd: tmp,
282
- tools: [],
283
- };
284
-
285
- const events = await collect(runWorkflow(def, { count: 42 }, ctx));
286
- expect(events.some((e) => e.type === 'workflow_done')).toBe(true);
287
- } finally {
288
- delete process.env.MINIMAL_AGENT_CWD;
289
- _resetWorkingDir();
290
- rmSync(tmp, { recursive: true, force: true });
291
- }
292
- });
293
- });
294
-
295
- describe('runner::self_heal retry 机制', () => {
296
- let tmp: string;
297
- let ctx: RunContext;
298
-
299
- beforeEach(() => {
300
- tmp = mkdtempSync(join(tmpdir(), 'wf-retry-'));
301
- process.env.MINIMAL_AGENT_CWD = tmp;
302
- _resetWorkingDir();
303
- mock.module('../../../src/bootstrap/workingDir.js', () => ({
304
- getWorkingDir: () => tmp,
305
- initWorkingDir: () => tmp,
306
- _resetWorkingDir: () => {},
307
- }));
308
- ctx = {
309
- provider: fakeProvider,
310
- history: [],
311
- cwd: tmp,
312
- tools: [],
313
- runtimeContext: createAgentRuntimeContext({ surface: 'workflow', profile: 'main', cwd: tmp, sessionId: DEFAULT_SESSION, owner: 'local-owner', interactiveAsk: false }),
314
- };
315
- });
316
-
317
- afterEach(() => {
318
- delete process.env.MINIMAL_AGENT_CWD;
319
- _resetWorkingDir();
320
- rmSync(tmp, { recursive: true, force: true });
321
- });
322
-
323
- it('self_heal.backoff 控制回退步数(失败时回退重跑)', async () => {
324
- const def: WorkflowDef = {
325
- name: 'backoff-test',
326
- description: 'd',
327
- self_heal: { backoff: 2, max_retries: 1 },
328
- steps: [
329
- { id: 'setup', tool: 'Write', args: { file_path: 'setup.txt', content: 'init' } },
330
- { id: 'work', type: 'assert', condition: 'true' },
331
- { id: 'flaky', type: 'assert', condition: 'false', onFail: 'fail' },
332
- { id: 'cleanup', type: 'assert', condition: 'true' },
333
- ],
334
- };
335
-
336
- const events = await collect(runWorkflow(def, {}, ctx));
337
- // flaky 失败后应触发 retry 机制(backoff=2 回退到 work 步骤重跑)
338
- // 最终仍会失败(因为 flaky 总是 false)
339
- expect(events.some((e) => e.type === 'error')).toBe(true);
340
-
341
- // 验证 setup 步骤被重新执行(backoff=2 导致从 work 重跑,work 之前的是 setup)
342
- // 所以 setup 应该出现多次
343
- const setupStartCount = events.filter(
344
- (e) => e.type === 'workflow_step_start' && (e as {id:string}).id === 'setup',
345
- ).length;
346
- expect(setupStartCount).toBeGreaterThanOrEqual(1); // 至少执行一次
347
- });
348
-
349
- it('step.max_retries 覆盖全局 self_heal.max_retries', async () => {
350
- const def: WorkflowDef = {
351
- name: 'override-retry',
352
- description: 'd',
353
- self_heal: { backoff: 0, max_retries: 5 }, // 全局允许 5 次
354
- steps: [
355
- {
356
- id: 'limited',
357
- type: 'assert',
358
- condition: 'false',
359
- onFail: 'always fails',
360
- max_retries: 1, // 但这步只允许 1 次
361
- },
362
- { id: 'next', type: 'assert', condition: 'true' },
363
- ],
364
- };
365
-
366
- const events = await collect(runWorkflow(def, {}, ctx));
367
- // limited 步骤只 retry 1 次(共尝试 2 次),然后halt
368
- expect(events.some((e) => e.type === 'error')).toBe(true);
369
- // next 不应被执行
370
- const startedIds = events
371
- .filter((e): e is Extract<WorkflowEvent, { type: 'workflow_step_start' }> =>
372
- e.type === 'workflow_step_start')
373
- .map((e) => e.id);
374
- expect(startedIds).not.toContain('next');
375
- });
376
-
377
- it('retry 用尽后走 onError:halt(默认)→ 整个 workflow 停止', async () => {
378
- const def: WorkflowDef = {
379
- name: 'retry-halt',
380
- description: 'd',
381
- self_heal: { backoff: 0, max_retries: 1 },
382
- steps: [
383
- {
384
- id: 'fail_step',
385
- type: 'assert',
386
- condition: 'false',
387
- onFail: 'fails',
388
- // 默认 onError='halt'
389
- },
390
- { id: 'next', type: 'assert', condition: 'true' },
391
- ],
392
- };
393
-
394
- const events = await collect(runWorkflow(def, {}, ctx));
395
- expect(events.some((e) => e.type === 'error')).toBe(true);
396
- expect(events.some((e) => e.type === 'workflow_done')).toBe(false);
397
- // next 不应执行
398
- expect(events.some((e) => e.type === 'workflow_step_start' && (e as {id:string}).id === 'next')).toBe(false);
399
- });
400
-
401
- it('正常成功路径 → archive 清理状态目录', async () => {
402
- const def: WorkflowDef = {
403
- name: 'archive-test',
404
- description: 'd',
405
- steps: [{ id: 's1', type: 'assert', condition: 'true' }],
406
- };
407
-
408
- await collect(runWorkflow(def, {}, ctx));
409
-
410
- // 成功后应 archive(活动实例目录改名 .done;workflow 级父目录保留)
411
- expect(hasInstance(tmp, 'archive-test')).toBe(false);
412
- expect(hasInstance(tmp, 'archive-test', '.done')).toBe(true);
413
- });
414
-
415
- it('失败路径 → 保留状态目录供排查', async () => {
416
- const def: WorkflowDef = {
417
- name: 'keep-state',
418
- description: 'd',
419
- self_heal: { backoff: 0, max_retries: 0 },
420
- steps: [
421
- { id: 'fail', type: 'assert', condition: 'false', onFail: 'boom' },
422
- ],
423
- };
424
-
425
- await collect(runWorkflow(def, {}, ctx));
426
-
427
- // 失败时应保留状态目录(workflow 级父目录 + 实例目录)
428
- expect(hasInstance(tmp, 'keep-state')).toBe(true);
429
- // progress.md 应包含失败步骤信息
430
- const instDir = findInstanceDir(tmp, 'keep-state');
431
- if (instDir) {
432
- const progress = readFileSync(join(instDir, 'progress.md'), 'utf8');
433
- expect(progress).toContain('fail');
434
- }
435
- });
436
- });
@@ -1,71 +0,0 @@
1
- /**
2
- * ============================================================
3
- * test/skillTurnDone.test.ts —— skill 节点不外泄子 runQuery 的 turn_done
4
- * ------------------------------------------------------------
5
- * 端到端实测发现:critic(skill) 子循环结束时 yield 的 turn_done 漏进 workflow 事件流,
6
- * 导致把 turn_done 当终结的消费者(-p --output-format json / gateway broker)在
7
- * workflow 中途(critic 之后、verify 之前)误判结束。execSkillStep 现过滤之。
8
- *
9
- * 策略:mock plugin-sdk 的 runQuery 吐 [text, turn_done],断言 execSkillStep 不外泄
10
- * turn_done,但保留 text 并正常 capture。
11
- * ============================================================
12
- */
13
-
14
- import { describe, expect, it } from 'bun:test';
15
- import { mkdirSync, mkdtempSync, writeFileSync } from 'node:fs';
16
- import { tmpdir } from 'node:os';
17
- import { join } from 'node:path';
18
-
19
- import type { LoopEvent } from '../../../src/types.js';
20
- import type { RunContext } from '../src/types.js';
21
- import { VarStack } from '../src/types.js';
22
- // 临时 skills 目录:myskill/SKILL.md
23
- const tmpProject = mkdtempSync(join(tmpdir(), 'wf-skillTD-'));
24
- const tmpSkills = join(tmpProject, 'skills');
25
- mkdirSync(join(tmpSkills, 'myskill'), { recursive: true });
26
- writeFileSync(
27
- join(tmpSkills, 'myskill', 'SKILL.md'),
28
- '---\nname: myskill\n---\n做点事。\n',
29
- );
30
-
31
- import { execSkillStep } from '../src/stepExecutors/skill.js';
32
-
33
- const fakeCtx: RunContext = {
34
- provider: {
35
- name: 't',
36
- baseURL: '',
37
- apiKey: '',
38
- model: 'm',
39
- contextWindow: 1_000_000,
40
- },
41
- history: [],
42
- cwd: tmpProject,
43
- tools: [],
44
- // DI:stub chat,让真实 runQuery 真推 'hello' 进 history + 单轮收尾 yield turn_done。
45
- chat: async function* () {
46
- yield { type: 'text_delta', delta: 'hello' };
47
- yield { type: 'done', stopReason: 'stop' };
48
- },
49
- };
50
-
51
- describe('execSkillStep turn_done 不外泄', () => {
52
- it('过滤 turn_done,保留 text/stage_change,正常 capture 文本', async () => {
53
- const evs: LoopEvent[] = [];
54
- const gen = execSkillStep(
55
- { id: 's', skill: 'myskill', input: 'go' },
56
- new VarStack(),
57
- fakeCtx,
58
- );
59
- let r = await gen.next();
60
- while (!r.done) {
61
- evs.push(r.value as LoopEvent);
62
- r = await gen.next();
63
- }
64
- const result = r.value;
65
-
66
- expect(evs.some((e) => e.type === 'turn_done')).toBe(false); // 关键:不外泄
67
- expect(evs.some((e) => e.type === 'text')).toBe(true); // 其它事件保留
68
- expect(evs.some((e) => e.type === 'stage_change')).toBe(true);
69
- expect(result.raw.text).toBe('hello'); // 文本仍正常 capture
70
- });
71
- });