minimal-agent 0.13.0 → 0.15.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 (474) 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 +536 -0
  103. package/src/advisor/advisorCoordinator.ts +693 -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/quickModelSetup.js +12 -1
  108. package/src/cli/quickModelSetup.tsx +15 -3
  109. package/src/cli/streamJson.js +5 -6
  110. package/src/cli/streamJson.ts +8 -4
  111. package/src/cli/wizards/advisorWizard.js +4 -2
  112. package/src/cli/wizards/advisorWizard.tsx +8 -2
  113. package/src/cli/wizards/contextAdvisorWizard.js +5 -4
  114. package/src/cli/wizards/contextAdvisorWizard.tsx +7 -6
  115. package/src/cli/wizards/providerPresets.js +18 -8
  116. package/src/cli/wizards/providerPresets.ts +18 -8
  117. package/src/collaboration/taskFlow.js +115 -0
  118. package/src/collaboration/taskFlow.ts +169 -0
  119. package/src/config/configDefaults.js +41 -1
  120. package/src/config/configDefaults.ts +43 -1
  121. package/src/config/configDiagnostics.ts +2 -2
  122. package/src/config/configFile.js +40 -9
  123. package/src/config/configFile.ts +60 -11
  124. package/src/config/configService.js +419 -74
  125. package/src/config/configService.ts +703 -145
  126. package/src/config/numericLimits.js +22 -0
  127. package/src/config/numericLimits.ts +24 -0
  128. package/src/config.js +1 -0
  129. package/src/config.ts +3 -2
  130. package/src/context/budgetPlan.js +1 -1
  131. package/src/context/budgetPlan.ts +1 -1
  132. package/src/context/compact.js +7 -2
  133. package/src/context/compact.ts +9 -2
  134. package/src/context/microCompactLite.js +212 -13
  135. package/src/context/microCompactLite.ts +261 -12
  136. package/src/context/sessionRegistry.js +8 -1
  137. package/src/context/sessionRegistry.ts +18 -5
  138. package/src/context/toolResultArchive.js +72 -0
  139. package/src/context/toolResultArchive.ts +95 -0
  140. package/src/goal/errors.js +8 -0
  141. package/src/goal/errors.ts +18 -0
  142. package/src/goal/goalRuntime.js +344 -0
  143. package/src/goal/goalRuntime.ts +466 -0
  144. package/src/goal/goalStore.js +200 -0
  145. package/src/goal/goalStore.ts +219 -0
  146. package/src/goal/index.js +4 -0
  147. package/src/goal/index.ts +4 -0
  148. package/src/goal/statusMapping.js +71 -0
  149. package/src/goal/statusMapping.ts +95 -0
  150. package/src/goal/types.js +7 -0
  151. package/src/goal/types.ts +179 -0
  152. package/src/goal/workflowController.js +306 -0
  153. package/src/goal/workflowController.ts +360 -0
  154. package/src/harness/evidenceLedger.js +2 -0
  155. package/src/harness/evidenceLedger.ts +1 -0
  156. package/src/harness/stallGuard.js +9 -3
  157. package/src/harness/stallGuard.ts +7 -3
  158. package/src/images/imageResolver.js +161 -0
  159. package/src/images/imageResolver.ts +189 -0
  160. package/src/infra/verification.js +34 -5
  161. package/src/infra/verification.ts +39 -4
  162. package/src/llm/client.js +79 -21
  163. package/src/llm/client.ts +182 -35
  164. package/src/llm/gatewayClient.js +201 -0
  165. package/src/llm/gatewayClient.ts +299 -0
  166. package/src/llm/messageProvenance.js +46 -0
  167. package/src/llm/messageProvenance.ts +58 -0
  168. package/src/llm/modelProvider.js +1 -0
  169. package/src/llm/modelProvider.ts +22 -0
  170. package/src/llm/providers/anthropicFormat.js +108 -1
  171. package/src/llm/providers/anthropicFormat.ts +115 -4
  172. package/src/llm/providers/openaiFormat.js +9 -0
  173. package/src/llm/providers/openaiFormat.ts +12 -3
  174. package/src/loop.js +328 -55
  175. package/src/loop.ts +382 -58
  176. package/src/main.js +4 -1
  177. package/src/main.tsx +4 -1
  178. package/src/managedExecution/index.js +2 -0
  179. package/src/managedExecution/index.ts +2 -0
  180. package/src/managedExecution/registry.js +15 -0
  181. package/src/managedExecution/registry.ts +20 -0
  182. package/src/managedExecution/types.js +1 -0
  183. package/src/managedExecution/types.ts +86 -0
  184. package/src/modelRef.js +9 -0
  185. package/src/modelRef.ts +31 -0
  186. package/src/multimodal.js +14 -28
  187. package/src/multimodal.ts +17 -33
  188. package/src/net/lanDiscovery.js +65 -0
  189. package/src/net/lanDiscovery.ts +82 -0
  190. package/src/plugin-sdk.js +28 -3
  191. package/src/plugin-sdk.ts +39 -6
  192. package/src/plugins/pluginApi.ts +16 -1
  193. package/src/plugins/pluginLoader.js +4 -0
  194. package/src/plugins/pluginLoader.ts +6 -0
  195. package/src/plugins/pluginRunner.js +139 -7
  196. package/src/plugins/pluginRunner.ts +173 -9
  197. package/src/plugins/slashFallback.js +113 -0
  198. package/src/plugins/slashFallback.ts +137 -0
  199. package/src/prompts/policyRegistry.js +12 -32
  200. package/src/prompts/policyRegistry.ts +15 -32
  201. package/src/prompts/promptAssembly.js +103 -12
  202. package/src/prompts/promptAssembly.ts +114 -12
  203. package/src/prompts/skillList.js +21 -3
  204. package/src/prompts/skillList.ts +27 -2
  205. package/src/prompts/stableSystemPrompt.js +18 -0
  206. package/src/prompts/stableSystemPrompt.ts +33 -0
  207. package/src/runtime/agentRuntimeContext.js +8 -2
  208. package/src/runtime/agentRuntimeContext.ts +17 -4
  209. package/src/session/runAgentTurn.js +78 -12
  210. package/src/session/runAgentTurn.ts +105 -23
  211. package/src/session/runTurn.js +10 -9
  212. package/src/session/runTurn.ts +17 -8
  213. package/src/session/sessionState.ts +2 -0
  214. package/src/team/auth.js +186 -0
  215. package/src/team/auth.ts +298 -0
  216. package/src/team/cli.js +105 -0
  217. package/src/team/cli.ts +122 -0
  218. package/src/team/onlineToolContract.js +64 -0
  219. package/src/team/onlineToolContract.ts +109 -0
  220. package/src/team/toolPolicy.js +36 -0
  221. package/src/team/toolPolicy.ts +75 -0
  222. package/src/tools/advisor/advisor.js +115 -50
  223. package/src/tools/advisor/advisor.ts +124 -51
  224. package/src/tools/advisor/advisorDecision.js +71 -0
  225. package/src/tools/advisor/advisorDecision.ts +85 -0
  226. package/src/tools/agent/agent.js +18 -5
  227. package/src/tools/agent/agent.ts +21 -7
  228. package/src/tools/agent/agentControl.js +246 -0
  229. package/src/tools/agent/agentControl.ts +284 -0
  230. package/src/tools/agent/agentTaskService.js +40 -1
  231. package/src/tools/agent/agentTaskService.ts +44 -1
  232. package/src/tools/agent/agentTypes.js +14 -2
  233. package/src/tools/agent/agentTypes.ts +15 -2
  234. package/src/tools/applypatch/applyPatch.js +362 -0
  235. package/src/tools/applypatch/applyPatch.ts +428 -0
  236. package/src/tools/bash/bash.js +22 -15
  237. package/src/tools/bash/bash.ts +23 -17
  238. package/src/tools/capabilities.js +10 -5
  239. package/src/tools/capabilities.ts +10 -5
  240. package/src/tools/computeruse/computerIntent.js +32 -0
  241. package/src/tools/computeruse/computerIntent.ts +46 -0
  242. package/src/tools/computeruse/telemetryLog.js +12 -0
  243. package/src/tools/computeruse/telemetryLog.ts +16 -0
  244. package/src/tools/computeruse/vision/telemetry.js +1 -0
  245. package/src/tools/computeruse/vision/telemetry.ts +1 -0
  246. package/src/tools/effectiveToolSet.js +4 -0
  247. package/src/tools/effectiveToolSet.ts +4 -0
  248. package/src/tools/index.js +21 -2
  249. package/src/tools/index.ts +33 -2
  250. package/src/tools/presentresult/presentresult.js +6 -15
  251. package/src/tools/presentresult/presentresult.ts +6 -15
  252. package/src/tools/read/read.js +62 -9
  253. package/src/tools/read/read.ts +63 -9
  254. package/src/tools/shared/fileUtils.js +1 -2
  255. package/src/tools/shared/fileUtils.ts +1 -2
  256. package/src/tools/shared/toolOutputStore.js +23 -1
  257. package/src/tools/shared/toolOutputStore.ts +22 -1
  258. package/src/tools/skill/skill.js +9 -3
  259. package/src/tools/skill/skill.ts +8 -4
  260. package/src/tools/toolPromptGuides.js +125 -0
  261. package/src/tools/toolPromptGuides.ts +146 -0
  262. package/src/tools/webbrowser/agentBrowserPath.js +19 -9
  263. package/src/tools/webbrowser/agentBrowserPath.ts +70 -28
  264. package/src/tools/webbrowser/browser.js +27 -11
  265. package/src/tools/webbrowser/browser.ts +68 -24
  266. package/src/tools/webbrowser/browserAutomation.js +329 -0
  267. package/src/tools/webbrowser/browserAutomation.ts +467 -0
  268. package/src/tools/webbrowser/browserAxState.js +97 -0
  269. package/src/tools/webbrowser/browserAxState.ts +142 -0
  270. package/src/tools/webbrowser/browserBatch.js +1578 -0
  271. package/src/tools/webbrowser/browserBatch.ts +2382 -0
  272. package/src/tools/webbrowser/browserCdp.js +208 -0
  273. package/src/tools/webbrowser/browserCdp.ts +255 -0
  274. package/src/tools/webbrowser/browserConditions.js +24 -0
  275. package/src/tools/webbrowser/browserConditions.ts +45 -0
  276. package/src/tools/webbrowser/browserContent.js +281 -0
  277. package/src/tools/webbrowser/browserContent.ts +438 -0
  278. package/src/tools/webbrowser/browserControl.js +131 -34
  279. package/src/tools/webbrowser/browserControl.ts +210 -56
  280. package/src/tools/webbrowser/browserDaemon.js +22 -14
  281. package/src/tools/webbrowser/browserDaemon.ts +54 -21
  282. package/src/tools/webbrowser/browserFrames.js +47 -0
  283. package/src/tools/webbrowser/browserFrames.ts +54 -0
  284. package/src/tools/webbrowser/browserInteractionResolver.js +17 -0
  285. package/src/tools/webbrowser/browserInteractionResolver.ts +40 -0
  286. package/src/tools/webbrowser/browserLocator.js +140 -0
  287. package/src/tools/webbrowser/browserLocator.ts +194 -0
  288. package/src/tools/webbrowser/browserOutcome.js +10 -17
  289. package/src/tools/webbrowser/browserOutcome.ts +48 -31
  290. package/src/tools/webbrowser/browserRecovery.js +58 -0
  291. package/src/tools/webbrowser/browserRecovery.ts +83 -0
  292. package/src/tools/webbrowser/browserRunRegistry.js +35 -3
  293. package/src/tools/webbrowser/browserRunRegistry.ts +91 -15
  294. package/src/tools/webbrowser/browserService.js +28 -2
  295. package/src/tools/webbrowser/browserService.ts +49 -9
  296. package/src/tools/webbrowser/browserStream.js +132 -33
  297. package/src/tools/webbrowser/browserStream.ts +224 -50
  298. package/src/tools/webbrowser/browserTabs.js +48 -15
  299. package/src/tools/webbrowser/browserTabs.ts +178 -96
  300. package/src/tools/webbrowser/webbrowser.js +679 -144
  301. package/src/tools/webbrowser/webbrowser.ts +975 -236
  302. package/src/tools/webfetch/preapproved.js +0 -2
  303. package/src/tools/webfetch/preapproved.ts +0 -2
  304. package/src/tools/websearch/websearch.js +129 -8
  305. package/src/tools/websearch/websearch.ts +138 -6
  306. package/src/types.ts +459 -40
  307. package/src/ui/App.js +377 -58
  308. package/src/ui/App.tsx +576 -111
  309. package/src/ui/LiveArea.js +14 -8
  310. package/src/ui/LiveArea.tsx +14 -10
  311. package/src/ui/MessageList.js +63 -20
  312. package/src/ui/MessageList.tsx +101 -16
  313. package/src/ui/ModelPicker.js +7 -4
  314. package/src/ui/ModelPicker.tsx +55 -8
  315. package/src/ui/hooks/useChat.js +152 -163
  316. package/src/ui/hooks/useChat.ts +396 -334
  317. package/src/ui/loginCommand.js +56 -0
  318. package/src/ui/loginCommand.ts +63 -0
  319. package/src/ui/toolProgress.js +41 -0
  320. package/src/ui/toolProgress.ts +44 -0
  321. package/src/web/browserBridge.js +20 -2
  322. package/src/web/browserBridge.ts +20 -2
  323. package/src/web/protocol.ts +1897 -194
  324. package/workflows/adaptive-research/workflow.mjs +86 -0
  325. package/workflows/e2e-capabilities/workflow.mjs +102 -0
  326. package/workflows/e2e-llm/workflow.mjs +52 -0
  327. package/workflows/e2e-smoke/workflow.mjs +59 -0
  328. package/workflows/e2e-vision-schema/README.md +48 -0
  329. package/workflows/e2e-vision-schema/workflow.mjs +149 -0
  330. package/workflows/e2e-write-greet/workflow.mjs +37 -0
  331. package/workflows/file-census/README.md +14 -0
  332. package/workflows/file-census/scripts/.gitkeep +2 -0
  333. package/workflows/file-census/workflow.mjs +110 -0
  334. package/workflows/goal/README.md +166 -0
  335. package/workflows/goal/prompts/audit.md +57 -0
  336. package/workflows/goal/prompts/contract.md +56 -0
  337. package/workflows/goal/prompts/iterate.md +37 -0
  338. package/workflows/goal/workflow.mjs +501 -0
  339. package/workflows/illustrate/README.md +90 -0
  340. package/workflows/illustrate/assets/engines.json +20 -0
  341. package/workflows/illustrate/assets/extract-baidu.js +21 -0
  342. package/workflows/illustrate/assets/extract-bing.js +33 -0
  343. package/workflows/illustrate/assets/extract-google.js +31 -0
  344. package/workflows/illustrate/workflow.mjs +301 -0
  345. package/workflows/plan/workflow.mjs +389 -0
  346. package/workflows/question-crops/README.md +35 -0
  347. package/workflows/question-crops/prompts/inventory.md +23 -0
  348. package/workflows/question-crops/scripts/image-ops.mjs +305 -0
  349. package/workflows/question-crops/scripts/image-ops.test.mjs +95 -0
  350. package/workflows/question-crops/workflow.mjs +172 -0
  351. package/workflows/ralph-loop/workflow.mjs +162 -0
  352. package/workflows/research/README.md +74 -0
  353. package/workflows/research/prompts/s0-goal.md +43 -0
  354. package/workflows/research/prompts/s1-early-exit.md +22 -0
  355. package/workflows/research/prompts/s1-map.md +58 -0
  356. package/workflows/research/prompts/s2-options.md +53 -0
  357. package/workflows/research/prompts/s3-deep-dive.md +56 -0
  358. package/workflows/research/prompts/s4-verify.md +74 -0
  359. package/workflows/research/prompts/s5-synthesis.md +81 -0
  360. package/workflows/research/prompts/s5b-fill-gaps.md +32 -0
  361. package/workflows/research/prompts/s6-package.md +32 -0
  362. package/workflows/research/scripts/build-report.mjs +98 -0
  363. package/workflows/research/workflow.mjs +288 -0
  364. package/workflows/wechat-reading-shots/prompts/collect-params.md +16 -0
  365. package/workflows/wechat-reading-shots/prompts/evaluate.md +20 -0
  366. package/workflows/wechat-reading-shots/prompts/open-book.md +28 -0
  367. package/workflows/wechat-reading-shots/prompts/read-page.md +13 -0
  368. package/workflows/wechat-reading-shots/prompts/turn-batch.md +24 -0
  369. package/workflows/wechat-reading-shots/test/control-flow.test.ts +329 -0
  370. package/workflows/wechat-reading-shots/workflow.mjs +266 -0
  371. package/workflows/wrong-question-docx/README.md +55 -0
  372. package/workflows/wrong-question-docx/prompts/figure-qa.md +8 -0
  373. package/workflows/wrong-question-docx/prompts/transcribe.md +25 -0
  374. package/workflows/wrong-question-docx/scripts/workbook.mjs +857 -0
  375. package/workflows/wrong-question-docx/test/control-flow.test.ts +165 -0
  376. package/workflows/wrong-question-docx/test/workbook.test.mjs +303 -0
  377. package/workflows/wrong-question-docx/workflow.mjs +485 -0
  378. package/plugins/workflow-runner/src/agentCommon.js +0 -354
  379. package/plugins/workflow-runner/src/agentCommon.ts +0 -435
  380. package/plugins/workflow-runner/src/controlFlow/branch.js +0 -40
  381. package/plugins/workflow-runner/src/controlFlow/branch.ts +0 -46
  382. package/plugins/workflow-runner/src/controlFlow/loop.js +0 -211
  383. package/plugins/workflow-runner/src/controlFlow/loop.ts +0 -248
  384. package/plugins/workflow-runner/src/controlFlow/pause.js +0 -129
  385. package/plugins/workflow-runner/src/controlFlow/pause.ts +0 -141
  386. package/plugins/workflow-runner/src/controlFlow/signal.js +0 -21
  387. package/plugins/workflow-runner/src/controlFlow/signal.ts +0 -29
  388. package/plugins/workflow-runner/src/controlFlow/types.js +0 -18
  389. package/plugins/workflow-runner/src/controlFlow/types.ts +0 -63
  390. package/plugins/workflow-runner/src/dslManifest.js +0 -72
  391. package/plugins/workflow-runner/src/dslManifest.ts +0 -127
  392. package/plugins/workflow-runner/src/expressions.js +0 -639
  393. package/plugins/workflow-runner/src/expressions.ts +0 -640
  394. package/plugins/workflow-runner/src/loader.js +0 -573
  395. package/plugins/workflow-runner/src/loader.ts +0 -721
  396. package/plugins/workflow-runner/src/multimodal.js +0 -38
  397. package/plugins/workflow-runner/src/multimodal.ts +0 -64
  398. package/plugins/workflow-runner/src/recovery.js +0 -126
  399. package/plugins/workflow-runner/src/recovery.ts +0 -156
  400. package/plugins/workflow-runner/src/stepExecutors/agent.js +0 -173
  401. package/plugins/workflow-runner/src/stepExecutors/agent.ts +0 -234
  402. package/plugins/workflow-runner/src/stepExecutors/assert.js +0 -42
  403. package/plugins/workflow-runner/src/stepExecutors/assert.ts +0 -52
  404. package/plugins/workflow-runner/src/stepExecutors/echo.js +0 -31
  405. package/plugins/workflow-runner/src/stepExecutors/echo.ts +0 -38
  406. package/plugins/workflow-runner/src/stepExecutors/llm.js +0 -99
  407. package/plugins/workflow-runner/src/stepExecutors/llm.ts +0 -133
  408. package/plugins/workflow-runner/src/stepExecutors/set.js +0 -49
  409. package/plugins/workflow-runner/src/stepExecutors/set.ts +0 -56
  410. package/plugins/workflow-runner/src/stepExecutors/skill.js +0 -111
  411. package/plugins/workflow-runner/src/stepExecutors/skill.ts +0 -140
  412. package/plugins/workflow-runner/src/stepExecutors/tool.js +0 -227
  413. package/plugins/workflow-runner/src/stepExecutors/tool.ts +0 -274
  414. package/plugins/workflow-runner/src/stepExecutors/verify.js +0 -61
  415. package/plugins/workflow-runner/src/stepExecutors/verify.ts +0 -72
  416. package/plugins/workflow-runner/src/stepPipeline.js +0 -277
  417. package/plugins/workflow-runner/src/stepPipeline.ts +0 -366
  418. package/plugins/workflow-runner/test/agent.test.ts +0 -587
  419. package/plugins/workflow-runner/test/agentLlmError.test.ts +0 -373
  420. package/plugins/workflow-runner/test/bashBlacklist.sweep.test.ts +0 -65
  421. package/plugins/workflow-runner/test/captureMisbind.test.ts +0 -99
  422. package/plugins/workflow-runner/test/cli.e2e.test.ts +0 -167
  423. package/plugins/workflow-runner/test/context-files.test.ts +0 -320
  424. package/plugins/workflow-runner/test/e2e.test.ts +0 -370
  425. package/plugins/workflow-runner/test/e2eNewLayout.test.ts +0 -314
  426. package/plugins/workflow-runner/test/engineRobustness.test.ts +0 -234
  427. package/plugins/workflow-runner/test/expressions.test.ts +0 -439
  428. package/plugins/workflow-runner/test/foundation.test.ts +0 -126
  429. package/plugins/workflow-runner/test/graceful.test.ts +0 -139
  430. package/plugins/workflow-runner/test/greedyInputs.load.test.ts +0 -47
  431. package/plugins/workflow-runner/test/hostCapability.test.ts +0 -108
  432. package/plugins/workflow-runner/test/illustrate.load.test.ts +0 -183
  433. package/plugins/workflow-runner/test/jsonPayload.test.ts +0 -83
  434. package/plugins/workflow-runner/test/loader.test.ts +0 -617
  435. package/plugins/workflow-runner/test/maxTurnsRetryDelay.test.ts +0 -33
  436. package/plugins/workflow-runner/test/multimodal.test.ts +0 -342
  437. package/plugins/workflow-runner/test/output-schema.test.ts +0 -213
  438. package/plugins/workflow-runner/test/parseWorkflowArgs.test.ts +0 -106
  439. package/plugins/workflow-runner/test/pluginRunner.isolation.test.ts +0 -269
  440. package/plugins/workflow-runner/test/ppt.load.test.ts +0 -1220
  441. package/plugins/workflow-runner/test/ralphLoop.e2e.test.ts +0 -221
  442. package/plugins/workflow-runner/test/recovery.test.ts +0 -265
  443. package/plugins/workflow-runner/test/research.load.test.ts +0 -328
  444. package/plugins/workflow-runner/test/runner.test.ts +0 -911
  445. package/plugins/workflow-runner/test/runnerPreflight.test.ts +0 -436
  446. package/plugins/workflow-runner/test/skillTurnDone.test.ts +0 -71
  447. package/plugins/workflow-runner/test/stateLifecycle.test.ts +0 -198
  448. package/plugins/workflow-runner/test/stepPipeline.test.ts +0 -114
  449. package/plugins/workflow-runner/test/taskArbitration.test.ts +0 -354
  450. package/plugins/workflow-runner/test/taskLifecycle.test.ts +0 -324
  451. package/plugins/workflow-runner/test/toolArtifactOverwrite.test.ts +0 -221
  452. package/plugins/workflow-runner/test/toolCapabilityBoundary.test.ts +0 -29
  453. package/plugins/workflow-runner/test/toolRuntimeIntegration.test.ts +0 -168
  454. package/plugins/workflow-runner/test/webppt.load.test.ts +0 -250
  455. package/plugins/workflow-runner/test/word.load.test.ts +0 -208
  456. package/plugins/workflow-runner/test/workflows.smoke.test.ts +0 -76
  457. package/plugins/workflow-runner/test/yamlGuardConditions.test.ts +0 -207
  458. package/src/advisorState.js +0 -22
  459. package/src/cli/configWizard.js +0 -293
  460. package/src/tools/toolProgressBridge.js +0 -48
  461. package/workflows/adaptive-research.yaml +0 -50
  462. package/workflows/book-review-short.yaml +0 -125
  463. package/workflows/e2e-write-greet.yaml +0 -31
  464. package/workflows/illustrate.yaml +0 -227
  465. package/workflows/plan.yaml +0 -470
  466. package/workflows/ppt.yaml +0 -1670
  467. package/workflows/ralph-loop.yaml +0 -201
  468. package/workflows/research.yaml +0 -873
  469. package/workflows/schema.json +0 -176
  470. package/workflows/webppt.yaml +0 -496
  471. package/workflows/wechat-reading-shots.yaml +0 -315
  472. package/workflows/word.yaml +0 -720
  473. package/workflows/youtube-shorts.yaml +0 -202
  474. /package/workflows/{research.md → research/DESIGN.md} +0 -0
@@ -1,211 +0,0 @@
1
- /**
2
- * ============================================================
3
- * controlFlow/loop.ts —— 循环(while / for-each)
4
- * ------------------------------------------------------------
5
- * 从 `runner.ts::runSteps` 的内联块整体搬出(原 223 行,占 runSteps 的 29%)。
6
- * 逐行忠实搬运,只把「递归执行子块」换成注入的 `deps.runBlock`(见 types.ts 头注)。
7
- *
8
- * 三形态共存,缺一不可:
9
- * · **while**(无 `over:`)—— `max_iterations` 支持 `${}` 模板;用于重做/重试
10
- * · **for-each**(有 `over:`)—— 逐元素迭代
11
- * · **resume** —— 中断在迭代中间时恢复到「该迭代 + 迭代内断点」
12
- *
13
- * 四条实测换来的不变量,改动时先读完再动:
14
- * ① `max_iterations` 模板解析失败**响亮 halt**:曾有模板字符串不插值直接参与
15
- * `<` 比较 → NaN → 静默 0 次迭代(工作流"跑完了"但什么都没做)
16
- * ② 迭代变量用 `pushIteration/setIteration`,循环体里 capture/set 的作者变量
17
- * 必须**活到循环之外**(否则刚成功翻到目标页的运行会被判失败)
18
- * ③ while 模式第 2+ 轮发**持久 warning**:状态行 progress 会被首步 title 立即
19
- * 覆盖,用户感知不到「循环重来了」—— 曾被误读成死循环。for-each 的逐元素
20
- * 推进是正常的,不发
21
- * ④ 循环整体完成要记**自身 checkpoint**:否则中断在循环之后的步骤时,
22
- * resume 会误把整条循环从头重跑
23
- * ============================================================
24
- */
25
- import { evalExpr, interpolate } from '../expressions.js';
26
- import { collectCaptured } from '../stepPipeline.js';
27
- import { loopCheckpointName } from '../workflowState.js';
28
- const WF_PLUGIN_ID = 'workflow-runner';
29
- export async function* execLoopStep(step, vars, deps,
30
- /** 顶层传入的循环恢复信息;匹配本循环 id 时消费一次。 */
31
- loopResume) {
32
- const { ctx, state, cp } = deps;
33
- const isWhileMode = step.over === undefined;
34
- // max_iterations 支持 ${} 模板(如 "${inputs.max_iterations}"):插值 + coerce;
35
- // 失败响亮 halt——曾有模板字符串不插值直接参与 < 比较 → NaN → 静默 0 次迭代。
36
- let maxIter = 200; // while 模式安全上限(缺省)
37
- if (step.max_iterations !== undefined) {
38
- const raw = step.max_iterations;
39
- const n = typeof raw === 'number' ? raw : Number(interpolate(String(raw), vars).trim());
40
- if (!Number.isFinite(n) || n <= 0) {
41
- const errMsg = `loop "${step.id}" 的 max_iterations 解析失败:${JSON.stringify(raw)} → "${typeof raw === 'string' ? interpolate(String(raw), vars) : raw}" 不是正数(检查变量是否存在,裸名请用 inputs.<name>)`;
42
- yield { type: 'workflow_step_end', id: step.id, ok: false, error: errMsg };
43
- yield { type: 'error', error: `Workflow halted at step "${step.id}": ${errMsg}` };
44
- return { kind: 'halted' };
45
- }
46
- maxIter = Math.floor(n);
47
- }
48
- const useFreshContext = step.fresh_context === true;
49
- // fresh context:循环开始时 snapshot 当前 history
50
- let baseHistorySnapshot = null;
51
- if (useFreshContext)
52
- baseHistorySnapshot = ctx.history.slice();
53
- // loop resume:恢复信息匹配本循环时消费一次——从中断时的迭代号起跑,
54
- // 该迭代内已完成的步经 innerStartFrom 跳过(变量已由 runWorkflow 回放快照)。
55
- let resumeIterStart = 0;
56
- let pendingInnerStart = 0;
57
- if (loopResume && loopResume.loopId === step.id) {
58
- resumeIterStart = loopResume.iteration;
59
- pendingInnerStart = loopResume.innerStartFrom;
60
- yield {
61
- type: 'warning',
62
- message: `♻ 循环 ${step.id} 从第 ${resumeIterStart + 1} 轮迭代第 ${pendingInnerStart + 1} 步续跑。`,
63
- };
64
- }
65
- // 顶层 loop 的 do[] 步记复合 checkpoint(loopId@@迭代号@@stepId),
66
- // resume 可恢复到迭代中间;更深嵌套不再下钻(descendIntoLoop=false)。
67
- const innerCpFor = (iter) => cp?.descendIntoLoop
68
- ? {
69
- name: (id) => loopCheckpointName(step.id, iter, id),
70
- descendIntoLoop: false,
71
- }
72
- : undefined;
73
- if (isWhileMode) {
74
- // ===== WHILE 循环模式 =====
75
- const asName = step.as ?? '_iter';
76
- let iterCount = resumeIterStart;
77
- let shouldBreak = false;
78
- while (iterCount < maxIter) {
79
- if (ctx.signal?.aborted) {
80
- yield { type: 'interrupted' };
81
- return { kind: 'halted' };
82
- }
83
- // 注入迭代变量:用 pushIteration/setIteration —— 只有这两个变量该随迭代消失,
84
- // 循环体里 capture/set 出来的作者变量必须活到循环之外(见 VarStack 头注)。
85
- vars.pushIteration();
86
- vars.setIteration(asName, iterCount);
87
- vars.setIteration(`${asName}_idx`, iterCount);
88
- // fresh context:每轮重置 history 到循环入口快照
89
- if (useFreshContext && baseHistorySnapshot) {
90
- ctx.history.length = 0;
91
- ctx.history.push(...baseHistorySnapshot);
92
- }
93
- // 迭代序号对用户有真实意义(第几轮重做),title 步也保留,只换人话名。
94
- yield {
95
- type: 'plugin_progress',
96
- pluginId: WF_PLUGIN_ID,
97
- current: iterCount + 1,
98
- max: maxIter,
99
- message: step.title
100
- ? `${interpolate(step.title, vars)}·第 ${iterCount + 1}/${maxIter} 轮`
101
- : `while-loop ${step.id} 迭代 ${iterCount + 1}/${maxIter}`,
102
- };
103
- // 第 2+ 轮额外发持久 warning:上面的状态行 progress 会被首步 title 立即
104
- // 覆盖(驻留一瞬),用户感知不到「循环重来了」——曾有 plan 工作流验收
105
- // 打回静默重启,被用户误读成死循环。while 模式的多轮 = 重做/重试,
106
- // 值得进 MessageList 留痕;for-each 的逐元素迭代是正常推进,不发。
107
- if (iterCount > 0) {
108
- yield {
109
- type: 'warning',
110
- message: `♻ 循环「${step.title ? interpolate(step.title, vars) : step.id}」进入第 ${iterCount + 1}/${maxIter} 轮`,
111
- };
112
- }
113
- const innerStart = pendingInnerStart;
114
- pendingInnerStart = 0; // 仅 resume 后的首个迭代生效
115
- const r = yield* deps.runBlock(step.do ?? [], vars, innerCpFor(iterCount), innerStart);
116
- vars.pop();
117
- iterCount++;
118
- // halt(error/interrupt/onError:halt)→ 真正向上中止整个工作流。
119
- if (r === 'halted')
120
- return { kind: 'halted' };
121
- if (typeof r === 'object') {
122
- // 带 target 且不是本循环 → 穿透上抛给外层循环
123
- if (r.target !== undefined && r.target !== step.id) {
124
- return { kind: 'flow', signal: r };
125
- }
126
- if (r.signal === 'break') {
127
- shouldBreak = true;
128
- break;
129
- }
130
- // continue → 跳到下一轮迭代(什么都不做,自然进入下一轮)
131
- }
132
- }
133
- const whyEnd = shouldBreak ? 'break 退出' : `达到上限 ${maxIter}`;
134
- await state.appendProgress(`✓ ${step.id} (while ×${iterCount}, ${whyEnd})`);
135
- await state.writeVars(vars.snapshot());
136
- // 循环完成记自身 checkpoint:resume 据此判定「循环已整体完成」(否则
137
- // 中断在循环之后的步骤时,resume 会误把整条循环从头重跑)。
138
- if (cp) {
139
- await state.recordCheckpoint(cp.name(step.id), `while loop ${iterCount} iterations (${whyEnd})`, collectCaptured(step.capture, vars), vars.snapshot());
140
- }
141
- yield {
142
- type: 'workflow_step_end',
143
- id: step.id,
144
- ok: true,
145
- output: `while loop ${iterCount} iterations (${whyEnd})`,
146
- };
147
- return { kind: 'next' };
148
- }
149
- // ===== FOR-EACH 循环模式 =====
150
- let arr;
151
- try {
152
- arr = evalExpr(step.over ?? '[]', vars);
153
- }
154
- catch (e) {
155
- const errMsg = `loop over 表达式错误: ${e.message}`;
156
- await state.appendProgress(`✗ ${step.id}: ${errMsg}`);
157
- yield { type: 'workflow_step_end', id: step.id, ok: false, error: errMsg };
158
- yield { type: 'error', error: `Workflow halted at step "${step.id}": ${errMsg}` };
159
- return { kind: 'halted' };
160
- }
161
- if (!Array.isArray(arr)) {
162
- const errMsg = `loop over 必须求值为数组,得到 ${typeof arr}`;
163
- await state.appendProgress(`✗ ${step.id}: ${errMsg}`);
164
- yield { type: 'workflow_step_end', id: step.id, ok: false, error: errMsg };
165
- yield { type: 'error', error: `Workflow halted at step "${step.id}": ${errMsg}` };
166
- return { kind: 'halted' };
167
- }
168
- const asName = step.as ?? 'item';
169
- let iterCount = 0;
170
- for (let idx = resumeIterStart; idx < arr.length; idx++) {
171
- if (ctx.signal?.aborted) {
172
- yield { type: 'interrupted' };
173
- return { kind: 'halted' };
174
- }
175
- vars.pushIteration();
176
- vars.setIteration(asName, arr[idx]);
177
- vars.setIteration(`${asName}_idx`, idx);
178
- // fresh context 也支持 for-each 模式
179
- if (useFreshContext && baseHistorySnapshot) {
180
- ctx.history.length = 0;
181
- ctx.history.push(...baseHistorySnapshot);
182
- }
183
- const innerStart = pendingInnerStart;
184
- pendingInnerStart = 0;
185
- const r = yield* deps.runBlock(step.do ?? [], vars, innerCpFor(idx), innerStart);
186
- vars.pop();
187
- iterCount++;
188
- if (r === 'halted')
189
- return { kind: 'halted' };
190
- if (typeof r === 'object') {
191
- if (r.target !== undefined && r.target !== step.id) {
192
- return { kind: 'flow', signal: r }; // 穿透上抛
193
- }
194
- if (r.signal === 'break')
195
- break; // 跳出 for-each,循环后兄弟步继续
196
- // continue → 下一个元素
197
- }
198
- }
199
- await state.appendProgress(`✓ ${step.id} (loop ×${iterCount})`);
200
- await state.writeVars(vars.snapshot());
201
- if (cp) {
202
- await state.recordCheckpoint(cp.name(step.id), `loop ${iterCount} 次`, collectCaptured(step.capture, vars), vars.snapshot());
203
- }
204
- yield {
205
- type: 'workflow_step_end',
206
- id: step.id,
207
- ok: true,
208
- output: `loop ${iterCount} 次`,
209
- };
210
- return { kind: 'next' };
211
- }
@@ -1,248 +0,0 @@
1
- /**
2
- * ============================================================
3
- * controlFlow/loop.ts —— 循环(while / for-each)
4
- * ------------------------------------------------------------
5
- * 从 `runner.ts::runSteps` 的内联块整体搬出(原 223 行,占 runSteps 的 29%)。
6
- * 逐行忠实搬运,只把「递归执行子块」换成注入的 `deps.runBlock`(见 types.ts 头注)。
7
- *
8
- * 三形态共存,缺一不可:
9
- * · **while**(无 `over:`)—— `max_iterations` 支持 `${}` 模板;用于重做/重试
10
- * · **for-each**(有 `over:`)—— 逐元素迭代
11
- * · **resume** —— 中断在迭代中间时恢复到「该迭代 + 迭代内断点」
12
- *
13
- * 四条实测换来的不变量,改动时先读完再动:
14
- * ① `max_iterations` 模板解析失败**响亮 halt**:曾有模板字符串不插值直接参与
15
- * `<` 比较 → NaN → 静默 0 次迭代(工作流"跑完了"但什么都没做)
16
- * ② 迭代变量用 `pushIteration/setIteration`,循环体里 capture/set 的作者变量
17
- * 必须**活到循环之外**(否则刚成功翻到目标页的运行会被判失败)
18
- * ③ while 模式第 2+ 轮发**持久 warning**:状态行 progress 会被首步 title 立即
19
- * 覆盖,用户感知不到「循环重来了」—— 曾被误读成死循环。for-each 的逐元素
20
- * 推进是正常的,不发
21
- * ④ 循环整体完成要记**自身 checkpoint**:否则中断在循环之后的步骤时,
22
- * resume 会误把整条循环从头重跑
23
- * ============================================================
24
- */
25
-
26
- import type { LoopEvent } from '../../../../src/plugin-sdk.js';
27
- import type { Message } from '../../../../src/types.js';
28
- import { evalExpr, interpolate } from '../expressions.js';
29
- import { collectCaptured, type CpScope } from '../stepPipeline.js';
30
- import type { StepDef, VarStack, WorkflowEvent } from '../types.js';
31
- import { loopCheckpointName, type LoopResumeInfo } from '../workflowState.js';
32
- import type { ControlDeps, ControlOutcome } from './types.js';
33
-
34
- const WF_PLUGIN_ID = 'workflow-runner';
35
-
36
- export async function* execLoopStep(
37
- step: StepDef,
38
- vars: VarStack,
39
- deps: ControlDeps,
40
- /** 顶层传入的循环恢复信息;匹配本循环 id 时消费一次。 */
41
- loopResume?: LoopResumeInfo,
42
- ): AsyncGenerator<WorkflowEvent | LoopEvent, ControlOutcome, void> {
43
- const { ctx, state, cp } = deps;
44
- const isWhileMode = step.over === undefined;
45
- // max_iterations 支持 ${} 模板(如 "${inputs.max_iterations}"):插值 + coerce;
46
- // 失败响亮 halt——曾有模板字符串不插值直接参与 < 比较 → NaN → 静默 0 次迭代。
47
- let maxIter = 200; // while 模式安全上限(缺省)
48
- if (step.max_iterations !== undefined) {
49
- const raw = step.max_iterations;
50
- const n =
51
- typeof raw === 'number' ? raw : Number(interpolate(String(raw), vars).trim());
52
- if (!Number.isFinite(n) || n <= 0) {
53
- const errMsg = `loop "${step.id}" 的 max_iterations 解析失败:${JSON.stringify(raw)} → "${typeof raw === 'string' ? interpolate(String(raw), vars) : raw}" 不是正数(检查变量是否存在,裸名请用 inputs.<name>)`;
54
- yield { type: 'workflow_step_end', id: step.id, ok: false, error: errMsg };
55
- yield { type: 'error', error: `Workflow halted at step "${step.id}": ${errMsg}` };
56
- return { kind: 'halted' };
57
- }
58
- maxIter = Math.floor(n);
59
- }
60
- const useFreshContext = step.fresh_context === true;
61
-
62
- // fresh context:循环开始时 snapshot 当前 history
63
- let baseHistorySnapshot: Message[] | null = null;
64
- if (useFreshContext) baseHistorySnapshot = ctx.history.slice();
65
-
66
- // loop resume:恢复信息匹配本循环时消费一次——从中断时的迭代号起跑,
67
- // 该迭代内已完成的步经 innerStartFrom 跳过(变量已由 runWorkflow 回放快照)。
68
- let resumeIterStart = 0;
69
- let pendingInnerStart = 0;
70
- if (loopResume && loopResume.loopId === step.id) {
71
- resumeIterStart = loopResume.iteration;
72
- pendingInnerStart = loopResume.innerStartFrom;
73
- yield {
74
- type: 'warning',
75
- message: `♻ 循环 ${step.id} 从第 ${resumeIterStart + 1} 轮迭代第 ${pendingInnerStart + 1} 步续跑。`,
76
- };
77
- }
78
-
79
- // 顶层 loop 的 do[] 步记复合 checkpoint(loopId@@迭代号@@stepId),
80
- // resume 可恢复到迭代中间;更深嵌套不再下钻(descendIntoLoop=false)。
81
- const innerCpFor = (iter: number): CpScope | undefined =>
82
- cp?.descendIntoLoop
83
- ? {
84
- name: (id: string) => loopCheckpointName(step.id, iter, id),
85
- descendIntoLoop: false,
86
- }
87
- : undefined;
88
-
89
- if (isWhileMode) {
90
- // ===== WHILE 循环模式 =====
91
- const asName = step.as ?? '_iter';
92
- let iterCount = resumeIterStart;
93
- let shouldBreak = false;
94
-
95
- while (iterCount < maxIter) {
96
- if (ctx.signal?.aborted) {
97
- yield { type: 'interrupted' };
98
- return { kind: 'halted' };
99
- }
100
-
101
- // 注入迭代变量:用 pushIteration/setIteration —— 只有这两个变量该随迭代消失,
102
- // 循环体里 capture/set 出来的作者变量必须活到循环之外(见 VarStack 头注)。
103
- vars.pushIteration();
104
- vars.setIteration(asName, iterCount);
105
- vars.setIteration(`${asName}_idx`, iterCount);
106
-
107
- // fresh context:每轮重置 history 到循环入口快照
108
- if (useFreshContext && baseHistorySnapshot) {
109
- ctx.history.length = 0;
110
- ctx.history.push(...baseHistorySnapshot);
111
- }
112
-
113
- // 迭代序号对用户有真实意义(第几轮重做),title 步也保留,只换人话名。
114
- yield {
115
- type: 'plugin_progress',
116
- pluginId: WF_PLUGIN_ID,
117
- current: iterCount + 1,
118
- max: maxIter,
119
- message: step.title
120
- ? `${interpolate(step.title, vars)}·第 ${iterCount + 1}/${maxIter} 轮`
121
- : `while-loop ${step.id} 迭代 ${iterCount + 1}/${maxIter}`,
122
- };
123
- // 第 2+ 轮额外发持久 warning:上面的状态行 progress 会被首步 title 立即
124
- // 覆盖(驻留一瞬),用户感知不到「循环重来了」——曾有 plan 工作流验收
125
- // 打回静默重启,被用户误读成死循环。while 模式的多轮 = 重做/重试,
126
- // 值得进 MessageList 留痕;for-each 的逐元素迭代是正常推进,不发。
127
- if (iterCount > 0) {
128
- yield {
129
- type: 'warning',
130
- message: `♻ 循环「${step.title ? interpolate(step.title, vars) : step.id}」进入第 ${iterCount + 1}/${maxIter} 轮`,
131
- };
132
- }
133
-
134
- const innerStart = pendingInnerStart;
135
- pendingInnerStart = 0; // 仅 resume 后的首个迭代生效
136
- const r = yield* deps.runBlock(
137
- step.do ?? [],
138
- vars,
139
- innerCpFor(iterCount),
140
- innerStart,
141
- );
142
- vars.pop();
143
- iterCount++;
144
-
145
- // halt(error/interrupt/onError:halt)→ 真正向上中止整个工作流。
146
- if (r === 'halted') return { kind: 'halted' };
147
- if (typeof r === 'object') {
148
- // 带 target 且不是本循环 → 穿透上抛给外层循环
149
- if (r.target !== undefined && r.target !== step.id) {
150
- return { kind: 'flow', signal: r };
151
- }
152
- if (r.signal === 'break') {
153
- shouldBreak = true;
154
- break;
155
- }
156
- // continue → 跳到下一轮迭代(什么都不做,自然进入下一轮)
157
- }
158
- }
159
-
160
- const whyEnd = shouldBreak ? 'break 退出' : `达到上限 ${maxIter}`;
161
- await state.appendProgress(`✓ ${step.id} (while ×${iterCount}, ${whyEnd})`);
162
- await state.writeVars(vars.snapshot());
163
- // 循环完成记自身 checkpoint:resume 据此判定「循环已整体完成」(否则
164
- // 中断在循环之后的步骤时,resume 会误把整条循环从头重跑)。
165
- if (cp) {
166
- await state.recordCheckpoint(
167
- cp.name(step.id),
168
- `while loop ${iterCount} iterations (${whyEnd})`,
169
- collectCaptured(step.capture, vars),
170
- vars.snapshot(),
171
- );
172
- }
173
- yield {
174
- type: 'workflow_step_end',
175
- id: step.id,
176
- ok: true,
177
- output: `while loop ${iterCount} iterations (${whyEnd})`,
178
- };
179
- return { kind: 'next' };
180
- }
181
-
182
- // ===== FOR-EACH 循环模式 =====
183
- let arr: unknown;
184
- try {
185
- arr = evalExpr(step.over ?? '[]', vars);
186
- } catch (e) {
187
- const errMsg = `loop over 表达式错误: ${(e as Error).message}`;
188
- await state.appendProgress(`✗ ${step.id}: ${errMsg}`);
189
- yield { type: 'workflow_step_end', id: step.id, ok: false, error: errMsg };
190
- yield { type: 'error', error: `Workflow halted at step "${step.id}": ${errMsg}` };
191
- return { kind: 'halted' };
192
- }
193
- if (!Array.isArray(arr)) {
194
- const errMsg = `loop over 必须求值为数组,得到 ${typeof arr}`;
195
- await state.appendProgress(`✗ ${step.id}: ${errMsg}`);
196
- yield { type: 'workflow_step_end', id: step.id, ok: false, error: errMsg };
197
- yield { type: 'error', error: `Workflow halted at step "${step.id}": ${errMsg}` };
198
- return { kind: 'halted' };
199
- }
200
- const asName = step.as ?? 'item';
201
- let iterCount = 0;
202
- for (let idx = resumeIterStart; idx < arr.length; idx++) {
203
- if (ctx.signal?.aborted) {
204
- yield { type: 'interrupted' };
205
- return { kind: 'halted' };
206
- }
207
- vars.pushIteration();
208
- vars.setIteration(asName, arr[idx]);
209
- vars.setIteration(`${asName}_idx`, idx);
210
-
211
- // fresh context 也支持 for-each 模式
212
- if (useFreshContext && baseHistorySnapshot) {
213
- ctx.history.length = 0;
214
- ctx.history.push(...baseHistorySnapshot);
215
- }
216
-
217
- const innerStart = pendingInnerStart;
218
- pendingInnerStart = 0;
219
- const r = yield* deps.runBlock(step.do ?? [], vars, innerCpFor(idx), innerStart);
220
- vars.pop();
221
- iterCount++;
222
- if (r === 'halted') return { kind: 'halted' };
223
- if (typeof r === 'object') {
224
- if (r.target !== undefined && r.target !== step.id) {
225
- return { kind: 'flow', signal: r }; // 穿透上抛
226
- }
227
- if (r.signal === 'break') break; // 跳出 for-each,循环后兄弟步继续
228
- // continue → 下一个元素
229
- }
230
- }
231
- await state.appendProgress(`✓ ${step.id} (loop ×${iterCount})`);
232
- await state.writeVars(vars.snapshot());
233
- if (cp) {
234
- await state.recordCheckpoint(
235
- cp.name(step.id),
236
- `loop ${iterCount} 次`,
237
- collectCaptured(step.capture, vars),
238
- vars.snapshot(),
239
- );
240
- }
241
- yield {
242
- type: 'workflow_step_end',
243
- id: step.id,
244
- ok: true,
245
- output: `loop ${iterCount} 次`,
246
- };
247
- return { kind: 'next' };
248
- }
@@ -1,129 +0,0 @@
1
- /**
2
- * ============================================================
3
- * controlFlow/pause.ts —— 真 HITL 审批闸门
4
- * ------------------------------------------------------------
5
- * 经 AskUserQuestion/askBridge 实现**真停等**:TUI 弹选择界面、用户拍板后继续;
6
- * 非交互宿主(-p / gateway / 测试)askBridge 自动选推荐项(继续执行)且 stderr
7
- * 注记,**绝不挂起** —— 与 `-p` 单行 JSON 契约兼容。「等用户」骑在既有
8
- * tool_call→tool_result 回路上(同 AskUserQuestion 工具),引擎零新通道。
9
- *
10
- * 两条踩过坑的判定规则,改动前先读:
11
- * ① **只解析【答案行】(`A1: …`)**。回执里 Q 行带着问题原文,而工作流的 pause
12
- * 提示语常含「停止」字样(如 plan.yaml 的说明文字)—— 看整个 content 会把
13
- * 用户选的「继续」误判成停止。**曾是真事故。**
14
- * ② **审批门上的含糊 = 不批准**。明确选「继续」才放行;选「停止」、取消提问(ESC)、
15
- * 或自由输入其它内容(= 用户想先改点什么)一律不放行。只有**桥本身异常**才
16
- * 兜底放行(保持可用性)并响亮警告。
17
- * ============================================================
18
- */
19
- import { executeTool } from '../../../../src/plugin-sdk.js';
20
- import { truncate } from '../agentCommon.js';
21
- import { interpolate } from '../expressions.js';
22
- import { commitStep } from '../stepPipeline.js';
23
- const WF_PLUGIN_ID = 'workflow-runner';
24
- export async function* execPauseStep(step, vars, deps) {
25
- const { ctx, state, cp } = deps;
26
- const msg = step.prompt
27
- ? interpolate(step.prompt, vars)
28
- : '工作流暂停点:请确认是否继续执行后续步骤。';
29
- await state.appendProgress(`- ${step.id} pause: 等待用户确认`);
30
- // pause 会驻留状态行很久(等用户),title 步同样不带块内序号防误读。
31
- if (step.title) {
32
- yield {
33
- type: 'plugin_progress',
34
- pluginId: WF_PLUGIN_ID,
35
- message: `⏸ ${interpolate(step.title, vars)}:等待用户确认…`,
36
- };
37
- }
38
- else {
39
- yield {
40
- type: 'plugin_progress',
41
- pluginId: WF_PLUGIN_ID,
42
- current: deps.index + 1,
43
- max: deps.total,
44
- message: `⏸ 审批闸门 ${step.id}:等待用户确认…`,
45
- };
46
- }
47
- const exec = ctx.executeTool ?? executeTool;
48
- let approved = true;
49
- let askFailed = false;
50
- let freeText = '';
51
- const freeTextMode = step.free_text ?? 'halt';
52
- try {
53
- const r = await exec('AskUserQuestion', JSON.stringify({
54
- questions: [
55
- {
56
- question: truncate(msg, 400),
57
- header: '审批闸门',
58
- options: [
59
- { label: '继续执行 (推荐)', description: '放行后续步骤' },
60
- {
61
- label: '停止(保留现场)',
62
- description: '中止本次运行;同任务重跑可从断点 resume',
63
- },
64
- ],
65
- },
66
- ],
67
- }), ctx.signal);
68
- // ⚠️ 只解析【答案行】——见文件头注规则 ①。
69
- const answerText = r.ok
70
- ? r.content
71
- .split('\n')
72
- .map((l) => l.trim())
73
- .filter((l) => /^A\d+[::]/.test(l))
74
- .join('\n')
75
- : '';
76
- if (!r.ok || answerText.includes('停止')) {
77
- approved = false;
78
- }
79
- else if (answerText.includes('继续')) {
80
- approved = true;
81
- }
82
- else {
83
- // 自由输入(「其他」逃生项):用户想先调整 → 不放行,把原话带进 halt 文案
84
- freeText = answerText.replace(/^A\d+[::]\s*/, '');
85
- approved = freeTextMode === 'approve';
86
- }
87
- }
88
- catch {
89
- askFailed = true; // 桥不可用 → 放行 + 响亮警告(保持旧"不挂起"行为)
90
- }
91
- if (askFailed) {
92
- yield {
93
- type: 'warning',
94
- message: `⚠ pause "${step.id}" 审批闸门不可用(提问桥异常),已自动放行。提示:${msg}`,
95
- };
96
- }
97
- if (!approved) {
98
- const why = freeText
99
- ? `用户在审批闸门 "${step.id}" 给出指示「${truncate(freeText, 120)}」——未放行(现场已保留,按指示调整后重跑同目标可从断点续跑)`
100
- : `用户在审批闸门 "${step.id}" 选择停止(现场已保留,重跑同目标可从断点续跑)`;
101
- await state.appendProgress(`■ ${step.id}: ${why}`);
102
- if (cp)
103
- await state.recordFailure(step.id, why);
104
- yield { type: 'workflow_step_end', id: step.id, ok: false, error: why };
105
- yield { type: 'error', error: `Workflow halted at step "${step.id}": ${why}` };
106
- return { kind: 'halted' };
107
- }
108
- // 带补充要求的放行:自由输入并入贯穿目标(后续每步都看到,不止 capture 变量)
109
- if (freeText)
110
- await deps.addGoalSupplement(freeText);
111
- const pauseResult = {
112
- raw: { result: freeText, text: freeText, approved: true, free_text: freeText },
113
- preview: freeText
114
- ? `审批通过:继续执行;补充要求:${truncate(freeText, 120)}`
115
- : '审批通过:继续执行',
116
- };
117
- yield* commitStep({
118
- step,
119
- result: pauseResult,
120
- kind: 'pause',
121
- vars,
122
- ctx,
123
- state,
124
- ...(cp ? { cp } : {}),
125
- progressLine: `✓ ${step.id} (pause: 已确认继续)`,
126
- addGoalSupplement: deps.addGoalSupplement,
127
- });
128
- return { kind: 'next' };
129
- }