minimal-agent 0.12.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 (472) hide show
  1. package/README.md +6 -5
  2. package/package.json +62 -5
  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 +204 -185
  16. package/plugins/workflow-runner/src/index.ts +249 -224
  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 +404 -467
  28. package/plugins/workflow-runner/src/runner.ts +491 -535
  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 +172 -152
  54. package/plugins/workflow-runner/src/taskIdentity.ts +233 -200
  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 -105
  58. package/plugins/workflow-runner/src/types.ts +155 -520
  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 +542 -469
  68. package/plugins/workflow-runner/src/workflowState.ts +639 -589
  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/skill-creator/scripts/run_eval.py +3 -2
  92. package/skills/ui-design/SKILL.md +5 -2
  93. package/skills/ui-design/references/layout-composition.md +1 -1
  94. package/skills/workflow-creator/SKILL.md +344 -0
  95. package/skills/workflow-creator/assets/template/workflow.mjs +48 -0
  96. package/skills/workflow-creator/references/api.md +216 -0
  97. package/skills/workflow-creator/references/migration.md +103 -0
  98. package/skills/workflow-creator/references/patterns.md +779 -0
  99. package/skills/workflow-creator/scripts/list-resources.mjs +205 -0
  100. package/skills/workflow-creator/scripts/scaffold.mjs +148 -0
  101. package/skills/workflow-creator/scripts/validate.mjs +275 -0
  102. package/skills/workflow-creator/scripts/workflow-creator.test.mjs +82 -0
  103. package/src/advisor/advisorCoordinator.js +503 -0
  104. package/src/advisor/advisorCoordinator.ts +657 -0
  105. package/src/cli/configMenu.tsx +0 -1
  106. package/src/cli/print.js +44 -6
  107. package/src/cli/print.ts +73 -4
  108. package/src/cli/streamJson.js +5 -6
  109. package/src/cli/streamJson.ts +8 -4
  110. package/src/cli/wizards/advisorWizard.js +4 -2
  111. package/src/cli/wizards/advisorWizard.tsx +8 -2
  112. package/src/cli/wizards/contextAdvisorWizard.js +5 -4
  113. package/src/cli/wizards/contextAdvisorWizard.tsx +7 -6
  114. package/src/collaboration/taskFlow.js +115 -0
  115. package/src/collaboration/taskFlow.ts +169 -0
  116. package/src/config/configDefaults.js +41 -1
  117. package/src/config/configDefaults.ts +43 -1
  118. package/src/config/configDiagnostics.ts +2 -2
  119. package/src/config/configFile.js +40 -9
  120. package/src/config/configFile.ts +60 -11
  121. package/src/config/configService.js +443 -74
  122. package/src/config/configService.ts +723 -142
  123. package/src/config/numericLimits.js +22 -0
  124. package/src/config/numericLimits.ts +24 -0
  125. package/src/config.js +1 -0
  126. package/src/config.ts +3 -2
  127. package/src/context/budgetPlan.js +1 -1
  128. package/src/context/budgetPlan.ts +1 -1
  129. package/src/context/compact.js +7 -2
  130. package/src/context/compact.ts +9 -2
  131. package/src/context/microCompactLite.js +212 -13
  132. package/src/context/microCompactLite.ts +261 -12
  133. package/src/context/sessionRegistry.js +8 -1
  134. package/src/context/sessionRegistry.ts +18 -5
  135. package/src/context/toolResultArchive.js +72 -0
  136. package/src/context/toolResultArchive.ts +95 -0
  137. package/src/goal/errors.js +8 -0
  138. package/src/goal/errors.ts +18 -0
  139. package/src/goal/goalRuntime.js +344 -0
  140. package/src/goal/goalRuntime.ts +466 -0
  141. package/src/goal/goalStore.js +200 -0
  142. package/src/goal/goalStore.ts +219 -0
  143. package/src/goal/index.js +4 -0
  144. package/src/goal/index.ts +4 -0
  145. package/src/goal/statusMapping.js +71 -0
  146. package/src/goal/statusMapping.ts +95 -0
  147. package/src/goal/types.js +7 -0
  148. package/src/goal/types.ts +179 -0
  149. package/src/goal/workflowController.js +306 -0
  150. package/src/goal/workflowController.ts +360 -0
  151. package/src/harness/evidenceLedger.js +2 -0
  152. package/src/harness/evidenceLedger.ts +1 -0
  153. package/src/harness/stallGuard.js +9 -3
  154. package/src/harness/stallGuard.ts +7 -3
  155. package/src/images/imageResolver.js +161 -0
  156. package/src/images/imageResolver.ts +189 -0
  157. package/src/infra/verification.js +56 -20
  158. package/src/infra/verification.ts +87 -20
  159. package/src/llm/client.js +79 -21
  160. package/src/llm/client.ts +182 -35
  161. package/src/llm/gatewayClient.js +201 -0
  162. package/src/llm/gatewayClient.ts +299 -0
  163. package/src/llm/messageProvenance.js +46 -0
  164. package/src/llm/messageProvenance.ts +58 -0
  165. package/src/llm/modelProvider.js +1 -0
  166. package/src/llm/modelProvider.ts +22 -0
  167. package/src/llm/providers/anthropicFormat.js +108 -1
  168. package/src/llm/providers/anthropicFormat.ts +115 -4
  169. package/src/llm/providers/openaiFormat.js +9 -0
  170. package/src/llm/providers/openaiFormat.ts +12 -3
  171. package/src/loop.js +319 -54
  172. package/src/loop.ts +373 -57
  173. package/src/main.js +4 -1
  174. package/src/main.tsx +4 -1
  175. package/src/managedExecution/index.js +2 -0
  176. package/src/managedExecution/index.ts +2 -0
  177. package/src/managedExecution/registry.js +15 -0
  178. package/src/managedExecution/registry.ts +20 -0
  179. package/src/managedExecution/types.js +1 -0
  180. package/src/managedExecution/types.ts +86 -0
  181. package/src/modelRef.js +9 -0
  182. package/src/modelRef.ts +31 -0
  183. package/src/multimodal.js +14 -28
  184. package/src/multimodal.ts +17 -33
  185. package/src/net/lanDiscovery.js +65 -0
  186. package/src/net/lanDiscovery.ts +82 -0
  187. package/src/plugin-sdk.js +28 -3
  188. package/src/plugin-sdk.ts +39 -6
  189. package/src/plugins/pluginApi.ts +16 -1
  190. package/src/plugins/pluginLoader.js +4 -0
  191. package/src/plugins/pluginLoader.ts +6 -0
  192. package/src/plugins/pluginRunner.js +152 -9
  193. package/src/plugins/pluginRunner.ts +186 -8
  194. package/src/plugins/slashFallback.js +113 -0
  195. package/src/plugins/slashFallback.ts +137 -0
  196. package/src/prompts/policyRegistry.js +15 -8
  197. package/src/prompts/policyRegistry.ts +18 -8
  198. package/src/prompts/promptAssembly.js +103 -12
  199. package/src/prompts/promptAssembly.ts +114 -12
  200. package/src/prompts/skillList.js +21 -3
  201. package/src/prompts/skillList.ts +27 -2
  202. package/src/prompts/stableSystemPrompt.js +18 -0
  203. package/src/prompts/stableSystemPrompt.ts +33 -0
  204. package/src/runtime/agentRuntimeContext.js +8 -2
  205. package/src/runtime/agentRuntimeContext.ts +17 -4
  206. package/src/session/runAgentTurn.js +78 -12
  207. package/src/session/runAgentTurn.ts +105 -23
  208. package/src/session/runTurn.js +10 -9
  209. package/src/session/runTurn.ts +17 -8
  210. package/src/session/sessionState.ts +2 -0
  211. package/src/team/auth.js +186 -0
  212. package/src/team/auth.ts +298 -0
  213. package/src/team/cli.js +105 -0
  214. package/src/team/cli.ts +122 -0
  215. package/src/team/onlineToolContract.js +64 -0
  216. package/src/team/onlineToolContract.ts +109 -0
  217. package/src/team/toolPolicy.js +36 -0
  218. package/src/team/toolPolicy.ts +75 -0
  219. package/src/tools/advisor/advisor.js +148 -37
  220. package/src/tools/advisor/advisor.ts +161 -38
  221. package/src/tools/advisor/advisorDecision.js +71 -0
  222. package/src/tools/advisor/advisorDecision.ts +85 -0
  223. package/src/tools/agent/agent.js +18 -5
  224. package/src/tools/agent/agent.ts +21 -7
  225. package/src/tools/agent/agentControl.js +246 -0
  226. package/src/tools/agent/agentControl.ts +284 -0
  227. package/src/tools/agent/agentTaskService.js +40 -1
  228. package/src/tools/agent/agentTaskService.ts +44 -1
  229. package/src/tools/agent/agentTypes.js +14 -2
  230. package/src/tools/agent/agentTypes.ts +15 -2
  231. package/src/tools/applypatch/applyPatch.js +362 -0
  232. package/src/tools/applypatch/applyPatch.ts +428 -0
  233. package/src/tools/bash/bash.js +70 -18
  234. package/src/tools/bash/bash.ts +75 -20
  235. package/src/tools/capabilities.js +10 -5
  236. package/src/tools/capabilities.ts +10 -5
  237. package/src/tools/computeruse/computerIntent.js +32 -0
  238. package/src/tools/computeruse/computerIntent.ts +46 -0
  239. package/src/tools/computeruse/telemetryLog.js +12 -0
  240. package/src/tools/computeruse/telemetryLog.ts +16 -0
  241. package/src/tools/computeruse/vision/telemetry.js +1 -0
  242. package/src/tools/computeruse/vision/telemetry.ts +1 -0
  243. package/src/tools/effectiveToolSet.js +4 -0
  244. package/src/tools/effectiveToolSet.ts +4 -0
  245. package/src/tools/index.js +21 -2
  246. package/src/tools/index.ts +33 -2
  247. package/src/tools/powershell/powershell.js +18 -1
  248. package/src/tools/powershell/powershell.ts +18 -2
  249. package/src/tools/presentresult/presentresult.js +6 -15
  250. package/src/tools/presentresult/presentresult.ts +6 -15
  251. package/src/tools/read/read.js +69 -11
  252. package/src/tools/read/read.ts +70 -11
  253. package/src/tools/shared/fileUtils.js +1 -2
  254. package/src/tools/shared/fileUtils.ts +1 -2
  255. package/src/tools/shared/permanentDeleteGuard.js +34 -3
  256. package/src/tools/shared/permanentDeleteGuard.ts +43 -6
  257. package/src/tools/shared/toolOutputStore.js +23 -1
  258. package/src/tools/shared/toolOutputStore.ts +22 -1
  259. package/src/tools/skill/skill.js +9 -3
  260. package/src/tools/skill/skill.ts +8 -4
  261. package/src/tools/toolPromptGuides.js +117 -0
  262. package/src/tools/toolPromptGuides.ts +137 -0
  263. package/src/tools/webbrowser/agentBrowserPath.js +19 -9
  264. package/src/tools/webbrowser/agentBrowserPath.ts +70 -28
  265. package/src/tools/webbrowser/browser.js +27 -11
  266. package/src/tools/webbrowser/browser.ts +68 -24
  267. package/src/tools/webbrowser/browserAutomation.js +329 -0
  268. package/src/tools/webbrowser/browserAutomation.ts +467 -0
  269. package/src/tools/webbrowser/browserAxState.js +97 -0
  270. package/src/tools/webbrowser/browserAxState.ts +142 -0
  271. package/src/tools/webbrowser/browserBatch.js +1578 -0
  272. package/src/tools/webbrowser/browserBatch.ts +2382 -0
  273. package/src/tools/webbrowser/browserCdp.js +208 -0
  274. package/src/tools/webbrowser/browserCdp.ts +255 -0
  275. package/src/tools/webbrowser/browserConditions.js +24 -0
  276. package/src/tools/webbrowser/browserConditions.ts +45 -0
  277. package/src/tools/webbrowser/browserContent.js +281 -0
  278. package/src/tools/webbrowser/browserContent.ts +438 -0
  279. package/src/tools/webbrowser/browserControl.js +131 -30
  280. package/src/tools/webbrowser/browserControl.ts +210 -50
  281. package/src/tools/webbrowser/browserDaemon.js +22 -14
  282. package/src/tools/webbrowser/browserDaemon.ts +54 -21
  283. package/src/tools/webbrowser/browserFrames.js +47 -0
  284. package/src/tools/webbrowser/browserFrames.ts +54 -0
  285. package/src/tools/webbrowser/browserInteractionResolver.js +17 -0
  286. package/src/tools/webbrowser/browserInteractionResolver.ts +40 -0
  287. package/src/tools/webbrowser/browserLocator.js +140 -0
  288. package/src/tools/webbrowser/browserLocator.ts +194 -0
  289. package/src/tools/webbrowser/browserOutcome.js +10 -17
  290. package/src/tools/webbrowser/browserOutcome.ts +48 -31
  291. package/src/tools/webbrowser/browserRecovery.js +58 -0
  292. package/src/tools/webbrowser/browserRecovery.ts +83 -0
  293. package/src/tools/webbrowser/browserRunRegistry.js +35 -3
  294. package/src/tools/webbrowser/browserRunRegistry.ts +91 -15
  295. package/src/tools/webbrowser/browserService.js +28 -2
  296. package/src/tools/webbrowser/browserService.ts +49 -9
  297. package/src/tools/webbrowser/browserStream.js +132 -33
  298. package/src/tools/webbrowser/browserStream.ts +224 -50
  299. package/src/tools/webbrowser/browserTabs.js +48 -15
  300. package/src/tools/webbrowser/browserTabs.ts +178 -96
  301. package/src/tools/webbrowser/webbrowser.js +683 -144
  302. package/src/tools/webbrowser/webbrowser.ts +979 -236
  303. package/src/tools/webfetch/preapproved.js +0 -2
  304. package/src/tools/webfetch/preapproved.ts +0 -2
  305. package/src/tools/websearch/websearch.js +129 -8
  306. package/src/tools/websearch/websearch.ts +138 -6
  307. package/src/types.ts +450 -42
  308. package/src/ui/App.js +377 -58
  309. package/src/ui/App.tsx +576 -111
  310. package/src/ui/LiveArea.js +14 -8
  311. package/src/ui/LiveArea.tsx +14 -10
  312. package/src/ui/MessageList.js +63 -20
  313. package/src/ui/MessageList.tsx +101 -16
  314. package/src/ui/ModelPicker.js +7 -4
  315. package/src/ui/ModelPicker.tsx +55 -8
  316. package/src/ui/hooks/useChat.js +152 -163
  317. package/src/ui/hooks/useChat.ts +396 -334
  318. package/src/ui/loginCommand.js +56 -0
  319. package/src/ui/loginCommand.ts +63 -0
  320. package/src/ui/toolProgress.js +41 -0
  321. package/src/ui/toolProgress.ts +44 -0
  322. package/src/web/browserBridge.js +20 -2
  323. package/src/web/browserBridge.ts +20 -2
  324. package/src/web/protocol.ts +1897 -194
  325. package/workflows/adaptive-research/workflow.mjs +86 -0
  326. package/workflows/e2e-capabilities/workflow.mjs +102 -0
  327. package/workflows/e2e-llm/workflow.mjs +52 -0
  328. package/workflows/e2e-smoke/workflow.mjs +59 -0
  329. package/workflows/e2e-vision-schema/README.md +48 -0
  330. package/workflows/e2e-vision-schema/workflow.mjs +149 -0
  331. package/workflows/e2e-write-greet/workflow.mjs +37 -0
  332. package/workflows/file-census/README.md +14 -0
  333. package/workflows/file-census/scripts/.gitkeep +2 -0
  334. package/workflows/file-census/workflow.mjs +110 -0
  335. package/workflows/goal/README.md +166 -0
  336. package/workflows/goal/prompts/audit.md +57 -0
  337. package/workflows/goal/prompts/contract.md +56 -0
  338. package/workflows/goal/prompts/iterate.md +37 -0
  339. package/workflows/goal/workflow.mjs +501 -0
  340. package/workflows/illustrate/README.md +90 -0
  341. package/workflows/illustrate/assets/engines.json +20 -0
  342. package/workflows/illustrate/assets/extract-baidu.js +21 -0
  343. package/workflows/illustrate/assets/extract-bing.js +33 -0
  344. package/workflows/illustrate/assets/extract-google.js +31 -0
  345. package/workflows/illustrate/workflow.mjs +301 -0
  346. package/workflows/plan/workflow.mjs +389 -0
  347. package/workflows/question-crops/README.md +35 -0
  348. package/workflows/question-crops/prompts/inventory.md +23 -0
  349. package/workflows/question-crops/scripts/image-ops.mjs +305 -0
  350. package/workflows/question-crops/scripts/image-ops.test.mjs +95 -0
  351. package/workflows/question-crops/workflow.mjs +172 -0
  352. package/workflows/ralph-loop/workflow.mjs +162 -0
  353. package/workflows/research/DESIGN.md +449 -0
  354. package/workflows/research/README.md +74 -0
  355. package/workflows/research/prompts/s0-goal.md +43 -0
  356. package/workflows/research/prompts/s1-early-exit.md +22 -0
  357. package/workflows/research/prompts/s1-map.md +58 -0
  358. package/workflows/research/prompts/s2-options.md +53 -0
  359. package/workflows/research/prompts/s3-deep-dive.md +56 -0
  360. package/workflows/research/prompts/s4-verify.md +74 -0
  361. package/workflows/research/prompts/s5-synthesis.md +81 -0
  362. package/workflows/research/prompts/s5b-fill-gaps.md +32 -0
  363. package/workflows/research/prompts/s6-package.md +32 -0
  364. package/workflows/research/scripts/build-report.mjs +98 -0
  365. package/workflows/research/workflow.mjs +288 -0
  366. package/workflows/wechat-reading-shots/prompts/collect-params.md +16 -0
  367. package/workflows/wechat-reading-shots/prompts/evaluate.md +20 -0
  368. package/workflows/wechat-reading-shots/prompts/open-book.md +28 -0
  369. package/workflows/wechat-reading-shots/prompts/read-page.md +13 -0
  370. package/workflows/wechat-reading-shots/prompts/turn-batch.md +24 -0
  371. package/workflows/wechat-reading-shots/test/control-flow.test.ts +329 -0
  372. package/workflows/wechat-reading-shots/workflow.mjs +266 -0
  373. package/workflows/wrong-question-docx/README.md +55 -0
  374. package/workflows/wrong-question-docx/prompts/figure-qa.md +8 -0
  375. package/workflows/wrong-question-docx/prompts/transcribe.md +25 -0
  376. package/workflows/wrong-question-docx/scripts/workbook.mjs +857 -0
  377. package/workflows/wrong-question-docx/test/control-flow.test.ts +165 -0
  378. package/workflows/wrong-question-docx/test/workbook.test.mjs +303 -0
  379. package/workflows/wrong-question-docx/workflow.mjs +485 -0
  380. package/plugins/workflow-runner/src/agentCommon.js +0 -354
  381. package/plugins/workflow-runner/src/agentCommon.ts +0 -435
  382. package/plugins/workflow-runner/src/controlFlow/branch.js +0 -40
  383. package/plugins/workflow-runner/src/controlFlow/branch.ts +0 -46
  384. package/plugins/workflow-runner/src/controlFlow/loop.js +0 -211
  385. package/plugins/workflow-runner/src/controlFlow/loop.ts +0 -248
  386. package/plugins/workflow-runner/src/controlFlow/pause.js +0 -129
  387. package/plugins/workflow-runner/src/controlFlow/pause.ts +0 -141
  388. package/plugins/workflow-runner/src/controlFlow/signal.js +0 -21
  389. package/plugins/workflow-runner/src/controlFlow/signal.ts +0 -29
  390. package/plugins/workflow-runner/src/controlFlow/types.js +0 -18
  391. package/plugins/workflow-runner/src/controlFlow/types.ts +0 -63
  392. package/plugins/workflow-runner/src/dslManifest.js +0 -72
  393. package/plugins/workflow-runner/src/dslManifest.ts +0 -127
  394. package/plugins/workflow-runner/src/expressions.js +0 -618
  395. package/plugins/workflow-runner/src/expressions.ts +0 -622
  396. package/plugins/workflow-runner/src/loader.js +0 -573
  397. package/plugins/workflow-runner/src/loader.ts +0 -721
  398. package/plugins/workflow-runner/src/multimodal.js +0 -38
  399. package/plugins/workflow-runner/src/multimodal.ts +0 -64
  400. package/plugins/workflow-runner/src/recovery.js +0 -119
  401. package/plugins/workflow-runner/src/recovery.ts +0 -149
  402. package/plugins/workflow-runner/src/stepExecutors/agent.js +0 -173
  403. package/plugins/workflow-runner/src/stepExecutors/agent.ts +0 -234
  404. package/plugins/workflow-runner/src/stepExecutors/assert.js +0 -41
  405. package/plugins/workflow-runner/src/stepExecutors/assert.ts +0 -50
  406. package/plugins/workflow-runner/src/stepExecutors/echo.js +0 -31
  407. package/plugins/workflow-runner/src/stepExecutors/echo.ts +0 -38
  408. package/plugins/workflow-runner/src/stepExecutors/llm.js +0 -99
  409. package/plugins/workflow-runner/src/stepExecutors/llm.ts +0 -133
  410. package/plugins/workflow-runner/src/stepExecutors/set.js +0 -49
  411. package/plugins/workflow-runner/src/stepExecutors/set.ts +0 -56
  412. package/plugins/workflow-runner/src/stepExecutors/skill.js +0 -111
  413. package/plugins/workflow-runner/src/stepExecutors/skill.ts +0 -140
  414. package/plugins/workflow-runner/src/stepExecutors/tool.js +0 -208
  415. package/plugins/workflow-runner/src/stepExecutors/tool.ts +0 -256
  416. package/plugins/workflow-runner/src/stepExecutors/verify.js +0 -58
  417. package/plugins/workflow-runner/src/stepExecutors/verify.ts +0 -68
  418. package/plugins/workflow-runner/src/stepPipeline.js +0 -277
  419. package/plugins/workflow-runner/src/stepPipeline.ts +0 -366
  420. package/plugins/workflow-runner/test/agent.test.ts +0 -587
  421. package/plugins/workflow-runner/test/agentLlmError.test.ts +0 -373
  422. package/plugins/workflow-runner/test/bashBlacklist.sweep.test.ts +0 -65
  423. package/plugins/workflow-runner/test/captureMisbind.test.ts +0 -99
  424. package/plugins/workflow-runner/test/cli.e2e.test.ts +0 -147
  425. package/plugins/workflow-runner/test/context-files.test.ts +0 -320
  426. package/plugins/workflow-runner/test/e2e.test.ts +0 -370
  427. package/plugins/workflow-runner/test/engineRobustness.test.ts +0 -226
  428. package/plugins/workflow-runner/test/expressions.test.ts +0 -397
  429. package/plugins/workflow-runner/test/foundation.test.ts +0 -126
  430. package/plugins/workflow-runner/test/graceful.test.ts +0 -139
  431. package/plugins/workflow-runner/test/greedyInputs.load.test.ts +0 -47
  432. package/plugins/workflow-runner/test/hostCapability.test.ts +0 -108
  433. package/plugins/workflow-runner/test/illustrate.load.test.ts +0 -183
  434. package/plugins/workflow-runner/test/jsonPayload.test.ts +0 -83
  435. package/plugins/workflow-runner/test/loader.test.ts +0 -617
  436. package/plugins/workflow-runner/test/maxTurnsRetryDelay.test.ts +0 -33
  437. package/plugins/workflow-runner/test/multimodal.test.ts +0 -342
  438. package/plugins/workflow-runner/test/output-schema.test.ts +0 -213
  439. package/plugins/workflow-runner/test/parseWorkflowArgs.test.ts +0 -87
  440. package/plugins/workflow-runner/test/pluginRunner.isolation.test.ts +0 -269
  441. package/plugins/workflow-runner/test/ppt.load.test.ts +0 -1220
  442. package/plugins/workflow-runner/test/ralphLoop.e2e.test.ts +0 -220
  443. package/plugins/workflow-runner/test/recovery.test.ts +0 -265
  444. package/plugins/workflow-runner/test/runner.test.ts +0 -911
  445. package/plugins/workflow-runner/test/runnerPreflight.test.ts +0 -379
  446. package/plugins/workflow-runner/test/skillTurnDone.test.ts +0 -71
  447. package/plugins/workflow-runner/test/stateLifecycle.test.ts +0 -150
  448. package/plugins/workflow-runner/test/stepPipeline.test.ts +0 -114
  449. package/plugins/workflow-runner/test/taskArbitration.test.ts +0 -338
  450. package/plugins/workflow-runner/test/taskLifecycle.test.ts +0 -270
  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 -199
  468. package/workflows/schema.json +0 -176
  469. package/workflows/webppt.yaml +0 -496
  470. package/workflows/wechat-reading-shots.yaml +0 -315
  471. package/workflows/word.yaml +0 -720
  472. package/workflows/youtube-shorts.yaml +0 -202
@@ -1,61 +1,86 @@
1
1
  /**
2
2
  * ============================================================
3
- * plugins/workflow-runner/src/index.ts —— /workflow 与 /workflows 命令的胶水层
3
+ * plugins/workflow-runner/src/index.ts —— /workflow 与 /workflows 的命令胶水
4
4
  * ------------------------------------------------------------
5
- * 作为 pluginRunner 与 runner 之间的桥:
6
- * - runWorkflowFromCommand:解析 /workflow <name> --input k=v args 调度
7
- * - runWorkflowsList:处理 /workflows 列表展示(yield "text" 事件让 UI 显示)
5
+ * 工作流只有一种形态:`workflows/<name>/workflow.mjs`。
8
6
  *
9
- * R1 红线:本文件只在 pluginRunner 命中 workflow 模式时才被 import。
10
- * 不污染默认 T-A-O-R 路径。
7
+ * 这里曾有一段「找不到就回落到 legacy yaml 引擎」的迁移期分支,随 yaml 引擎
8
+ * 一起删除了 —— 现在找不到就是找不到,直接报错并让用户看 /workflows。
11
9
  * ============================================================
12
10
  */
13
11
 
14
- import {
15
- type LoopEvent,
16
- type Message,
17
- type PluginContext,
18
- type Provider,
19
- type Tool,
20
- buildBaseSystemPrompt,
12
+ import { existsSync } from 'node:fs';
13
+ import { resolve } from 'node:path';
14
+ import { managedCommandController } from '../../../src/managedExecution/registry.js';
15
+ import type {
16
+ AgentRuntimeContext,
17
+ ContextBundle,
18
+ LoopEvent,
19
+ Message,
20
+ PluginContext,
21
+ PromptCacheContext,
22
+ Provider,
23
+ SessionState,
24
+ Tool,
21
25
  } from '../../../src/plugin-sdk.js';
22
- import { findWorkflowByName, listWorkflows } from './loader.js';
23
- import { runWorkflow } from './runner.js';
24
- import type { InputDef, RunContext, WorkflowEvent } from './types.js';
26
+ import { refreshStableSystemPrompt } from '../../../src/plugin-sdk.js';
27
+ import { discoverWorkflows } from './discovery.js';
28
+ import { coerceInputs } from './inputCoercion.js';
29
+ import { bindResourceInputs } from './resourceInputs.js';
30
+ import { runWorkflowScript } from './runner.js';
31
+ import type { InputDef, RunContext } from './types.js';
25
32
 
26
33
  export interface RunWorkflowFromCommandOptions {
27
34
  provider: Provider;
28
- runtimeContext?: import('../../../src/plugin-sdk.js').AgentRuntimeContext;
35
+ runtimeContext?: AgentRuntimeContext;
29
36
  history: Message[];
30
37
  signal?: AbortSignal;
31
- /** 会话状态(驱动 microCompact / reactiveCompact) */
32
- sessionState?: import('../../../src/plugin-sdk.js').SessionState;
33
- /** 当前工作目录(默认 process.cwd()) */
38
+ sessionState?: SessionState;
34
39
  cwd?: string;
35
- /** 宿主过滤后的可用工具列表;缺省为空,绝不在 runner 内恢复全量工具。 */
36
40
  tools?: Tool[];
37
41
  transientContext?: string;
38
- transientBundle?: import('../../../src/plugin-sdk.js').ContextBundle;
39
- promptCache?: import('../../../src/plugin-sdk.js').PromptCacheContext;
42
+ transientBundle?: ContextBundle;
43
+ promptCache?: PromptCacheContext;
40
44
  executeTool?: PluginContext['executeTool'];
41
45
  toolContext?: RunContext['toolContext'];
42
- /**
43
- * 宿主授权上下文(浏览器 / 电脑操控)。
44
- *
45
- * 引擎**不会**无条件把它转给每一步 —— 只有显式写了 `uses:` 的步骤才拿得到对应那片
46
- * (见 `StepDef.uses`)。一份 yaml 无人值守地跑,隐式全权是危险的。
47
- */
48
- host?: import('../../../src/plugin-sdk.js').PluginContext['host'];
46
+ host?: PluginContext['host'];
47
+ inputResources?: PluginContext['inputResources'];
48
+ /** 传给外层控制器的不透明上下文;Workflow Runner 不解释。 */
49
+ managedContext?: unknown;
49
50
  }
50
51
 
51
52
  /**
52
- * 把 "/workflow <name> [pos1 pos2 ...] [--input k=v ...]" 拆成 name + 显式 inputs + 位置参数。
53
- * 简单解析器(不依赖第三方):
54
- * - 第一个非 flag token = name;末尾 ".yaml" / ".yml" 自动剥(便于直接用文件名)
55
- * - 之后所有非 flag token 收进 positional[],由调用方按 def.inputs 声明顺序映射
56
- * - --input k=v 显式 KV,优先级高于位置参数(同名 input 不会被位置参数覆盖)
57
- * - 不识别其他 flag(保守跳过其后一个 token)
53
+ * shell 风格 token 化:引号在 token **任意位置**出现即进入引号模式。
54
+ *
55
+ * 自 legacy 移植。`--input topic="带空格的值"` 里引号在 `=` 之后、token 开头是 `t`,
56
+ * 只认「开头引号」的写法会把值截断并留下引号残留 —— 这是实测过的。
58
57
  */
58
+ function tokenizeArgs(s: string): string[] {
59
+ const out: string[] = [];
60
+ let i = 0;
61
+ while (i < s.length) {
62
+ while (i < s.length && /\s/.test(s[i])) i++;
63
+ if (i >= s.length) break;
64
+ let acc = '';
65
+ while (i < s.length) {
66
+ const c = s[i];
67
+ if (c === '"' || c === "'") {
68
+ const q = c;
69
+ i++;
70
+ while (i < s.length && s[i] !== q) acc += s[i++];
71
+ if (i < s.length) i++;
72
+ } else if (/\s/.test(c)) {
73
+ break;
74
+ } else {
75
+ acc += c;
76
+ i++;
77
+ }
78
+ }
79
+ out.push(acc);
80
+ }
81
+ return out;
82
+ }
83
+
59
84
  export function parseWorkflowArgs(rawArgs: string): {
60
85
  name: string | null;
61
86
  inputs: Record<string, string>;
@@ -71,207 +96,210 @@ export function parseWorkflowArgs(rawArgs: string): {
71
96
  const kv = tokens[i + 1];
72
97
  if (!kv) break;
73
98
  const eq = kv.indexOf('=');
74
- if (eq > 0) {
75
- inputs[kv.slice(0, eq)] = kv.slice(eq + 1);
76
- }
99
+ if (eq > 0) inputs[kv.slice(0, eq)] = kv.slice(eq + 1);
77
100
  i++;
78
101
  continue;
79
102
  }
80
103
  if (t.startsWith('--')) {
81
- // 未知 flag:跳过其后一个 token(保守地认为它带值)
82
- i++;
104
+ i++; // 未知 flag:保守跳过其后一个 token(认为它带值)
83
105
  continue;
84
106
  }
85
- if (name === null) {
86
- name = t.replace(/\.ya?ml$/i, '');
87
- } else {
88
- positional.push(t);
89
- }
107
+ if (name === null) name = t.replace(/\.ya?ml$/i, '');
108
+ else positional.push(t);
90
109
  }
91
110
  return { name, inputs, positional };
92
111
  }
93
112
 
94
- /** 简单 token 化:双引号包裹的整体当一个 token;其它按空白切。 */
95
- function tokenizeArgs(s: string): string[] {
96
- const out: string[] = [];
97
- let i = 0;
98
- while (i < s.length) {
99
- while (i < s.length && /\s/.test(s[i])) i++;
100
- if (i >= s.length) break;
101
- if (s[i] === '"' || s[i] === "'") {
102
- const q = s[i];
103
- i++;
104
- let acc = '';
105
- while (i < s.length && s[i] !== q) {
106
- acc += s[i++];
107
- }
108
- if (i < s.length) i++;
109
- out.push(acc);
110
- } else {
111
- let acc = '';
112
- while (i < s.length && !/\s/.test(s[i])) {
113
- acc += s[i++];
114
- }
115
- out.push(acc);
116
- }
117
- }
118
- return out;
119
- }
120
-
121
113
  /**
122
- * 把字符串形态的 input 值按 InputDef.type 转成合适的 JS 类型 + 校验。
123
- * 校验失败抛 Error,pluginRunner 会把它转成 error event。
114
+ * 位置参数 → inputs 映射。
115
+ * **贪婪首参**(`inputs[0].greedy`):名后全部位置参数空格 join 进首参,不逐位拆。
116
+ * 存在理由是真实事故:不贪婪时用户打一句自然语言会被空格拆碎,第二段撞上
117
+ * number 类型的输入报「必须是数字」。
124
118
  */
125
- function coerceInputs(
126
- raw: Record<string, string>,
119
+ function mapPositional(
120
+ rawInputs: Record<string, string>,
121
+ positional: string[],
127
122
  defs: InputDef[] | undefined,
128
- ): Record<string, unknown> {
129
- const out: Record<string, unknown> = {};
130
- if (!defs) return { ...raw };
123
+ cwd = process.cwd(),
124
+ ): string[] {
125
+ const warnings: string[] = [];
126
+ if (!defs || positional.length === 0) return warnings;
131
127
 
132
- for (const def of defs) {
133
- const rawVal = raw[def.name];
134
- if (rawVal === undefined) {
135
- if (def.required) {
136
- throw new Error(`缺少必填 input: ${def.name}`);
137
- }
138
- if (def.default !== undefined) {
139
- out[def.name] = def.default;
128
+ if (defs[0]?.greedy === true) {
129
+ const name = defs[0].name;
130
+ if (defs[0].type === 'resource' && !(name in rawInputs)) {
131
+ // A Desktop invocation commonly has a natural-language tail after the
132
+ // command and no textual path. Do not mistake that tail for a file.
133
+ const first = positional[0] ?? '';
134
+ const looksLikePath =
135
+ existsSync(resolve(cwd, first)) ||
136
+ first.startsWith('/') ||
137
+ first.startsWith('\\') ||
138
+ /^[A-Za-z]:[\\/]/.test(first) ||
139
+ first.startsWith('~/') ||
140
+ first.startsWith('~\\') ||
141
+ first.startsWith('./') ||
142
+ first.startsWith('.\\') ||
143
+ first.startsWith('../') ||
144
+ first.startsWith('..\\') ||
145
+ /\.[A-Za-z0-9]{1,16}$/.test(first);
146
+ if (!looksLikePath) {
147
+ if (positional.length) rawInputs.requestText = positional.join(' ');
148
+ return warnings;
140
149
  }
141
- continue;
150
+ rawInputs[name] = first;
151
+ if (positional.length > 1)
152
+ rawInputs.requestText = positional.slice(1).join(' ');
153
+ return warnings;
154
+ }
155
+ if (defs[0]?.type === 'resource' && name in rawInputs) {
156
+ if (positional.length) rawInputs.requestText = positional.join(' ');
157
+ return warnings;
158
+ }
159
+ if (name in rawInputs) {
160
+ // 含空格的值没加引号会被 shell 拆开(只有第一段进 KV,其余散落成位置参数)。
161
+ // 静默丢弃曾把整段中文主题截成半句,连锁触发仲裁误判。这里拼回去并告警。
162
+ rawInputs[name] = [rawInputs[name], ...positional].join(' ');
163
+ warnings.push(
164
+ `${name}:--input 值未加引号被拆成 ${positional.length} 段,已自动拼回(下次请写 --input "${name}=完整值")`,
165
+ );
166
+ } else {
167
+ rawInputs[name] = positional.join(' ');
142
168
  }
143
- if (def.type === 'number') {
144
- const n = Number.parseFloat(rawVal);
145
- if (Number.isNaN(n))
146
- throw new Error(`input ${def.name} 必须是数字,收到 "${rawVal}"`);
147
- out[def.name] = n;
148
- } else if (def.type === 'enum') {
149
- if (!def.values?.includes(rawVal)) {
150
- throw new Error(
151
- `input ${def.name} 必须是 [${def.values?.join(', ')}] 之一,收到 "${rawVal}"`,
169
+ return warnings;
170
+ }
171
+
172
+ const max = Math.min(positional.length, defs.length);
173
+ for (let i = 0; i < max; i++) {
174
+ const def = defs[i];
175
+ if (def.name in rawInputs) {
176
+ if (rawInputs[def.name] !== positional[i]) {
177
+ warnings.push(
178
+ `--input 优先级高于位置参数:${def.name} 取 ${JSON.stringify(rawInputs[def.name])},位置参数 ${JSON.stringify(positional[i])} 被忽略`,
152
179
  );
153
180
  }
154
- out[def.name] = rawVal;
155
181
  } else {
156
- out[def.name] = rawVal;
182
+ rawInputs[def.name] = positional[i];
157
183
  }
158
184
  }
159
- // 未声明的 input 也透传(让 yaml 里可以引用 ad-hoc 变量)
160
- for (const k of Object.keys(raw)) {
161
- if (!(k in out)) out[k] = raw[k];
162
- }
163
- return out;
164
- }
165
-
166
- async function refreshWorkflowSystemPrompt(
167
- history: Message[],
168
- cwd: string,
169
- tools: Tool[],
170
- ): Promise<void> {
171
- // 只刷稳定层:workflow 一跑就是几十步,system 消息若含日期/记忆等易变内容,
172
- // 每步都会重写 history[0]、把 provider 前缀缓存打散(见 prompts/system.ts)。
173
- const content = await buildBaseSystemPrompt(cwd, tools);
174
- const systemIndex = history.findIndex(
175
- (m) => m.role === 'system' && !m._ephemeral,
176
- );
177
- const fresh: Message = { role: 'system', content };
178
-
179
- if (systemIndex === 0) {
180
- history[0] = fresh;
181
- return;
185
+ if (positional.length > defs.length) {
186
+ const dropped = positional.slice(defs.length);
187
+ warnings.push(
188
+ `忽略了 ${dropped.length} 个多余位置参数:${dropped.map((d) => JSON.stringify(d)).join(' ')}`,
189
+ );
182
190
  }
183
-
184
- if (systemIndex > 0) history.splice(systemIndex, 1);
185
- history.unshift(fresh);
191
+ return warnings;
186
192
  }
187
193
 
188
- /** /workflow <name> [pos...] [--input k=v] —— 主入口,由 pluginRunner 调用。 */
194
+ /** `/workflow <name> …` 主入口。 */
189
195
  export async function* runWorkflowFromCommand(
190
196
  rawArgs: string,
191
197
  opts: RunWorkflowFromCommandOptions,
192
- ): AsyncGenerator<WorkflowEvent | LoopEvent, void, void> {
198
+ ): AsyncGenerator<LoopEvent, void, void> {
193
199
  const { name, inputs: rawInputs, positional } = parseWorkflowArgs(rawArgs);
194
200
  if (!name) {
195
201
  yield {
196
202
  type: 'error',
197
203
  error:
198
- '/workflow 用法: /workflow <name> [val ...] [--input key=val ...]\n输入 /workflows 查看可用工作流。',
199
- };
200
- return;
201
- }
202
- const def = await findWorkflowByName(name);
203
- if (!def) {
204
- yield {
205
- type: 'error',
206
- error: `未找到 workflow "${name}"。输入 /workflows 查看可用列表。`,
204
+ '/workflow 用法:/workflow <name> [值 ...] [--input key=值 ...]\n输入 /workflows 查看可用工作流。',
207
205
  };
208
206
  return;
209
207
  }
210
208
 
211
209
  const cwd = opts.cwd ?? process.cwd();
212
210
  const tools = opts.tools ?? [];
213
- await refreshWorkflowSystemPrompt(opts.history, cwd, tools);
211
+ const { workflows, failures } = await discoverWorkflows(cwd);
212
+ const script = workflows.find((w) => w.name === name);
214
213
 
215
- // 位置参数映射,两种模式:
216
- // - 贪婪首参(def.inputs[0].greedy===true):把【全部】位置参数用空格 join 成整句写进
217
- // 首个 input(自然语言 brief 不被空格拆碎、也不会撞上后面的 number/enum 输入),
218
- // 其余 input 只走 --input。用户「打一句话」即可(见 webppt.yaml::topic)。
219
- // - 默认:严格按"第 i 个位置参数 ↔ def.inputs[i]"对应。
220
- // --input k=v 显式优先:已显式的 input 不被位置参数覆盖(对应位置参数被丢弃,会 warn)。
221
- const overriddenByKV: string[] = [];
222
- const greedyFirst = def.inputs?.[0]?.greedy === true;
223
- if (greedyFirst && def.inputs && positional.length > 0) {
224
- const greedyName = def.inputs[0].name;
225
- if (greedyName in rawInputs) {
226
- // 首参已被 --input 占位 → 整串位置参数被忽略
227
- overriddenByKV.push(
228
- `${greedyName}=${JSON.stringify(rawInputs[greedyName])} (位置参数 ${JSON.stringify(positional.join(' '))} 被忽略)`,
229
- );
230
- } else {
231
- // 贪婪吸收:整句进首参(空格 join 还原用户原话,不逐位拆映射)
232
- rawInputs[greedyName] = positional.join(' ');
233
- }
234
- } else if (positional.length > 0 && def.inputs) {
235
- const max = Math.min(positional.length, def.inputs.length);
236
- for (let i = 0; i < max; i++) {
237
- const inputDef = def.inputs[i];
238
- if (inputDef.name in rawInputs) {
239
- // 已被 --input 占位,位置参数被丢弃
240
- if (rawInputs[inputDef.name] !== positional[i]) {
241
- overriddenByKV.push(
242
- `${inputDef.name}=${JSON.stringify(rawInputs[inputDef.name])} (位置参数 ${JSON.stringify(positional[i])} 被忽略)`,
243
- );
244
- }
245
- } else {
246
- rawInputs[inputDef.name] = positional[i];
247
- }
214
+ if (!script) {
215
+ const broken = failures.find((f) => f.name === name);
216
+ if (broken) {
217
+ // 「有但写错了」与「没有」必须区分开 —— 否则用户会去找一个并不存在的拼写问题。
218
+ yield {
219
+ type: 'error',
220
+ error: `工作流「${name}」存在但写错了:\n${broken.errors.map((e) => ` · ${e}`).join('\n')}`,
221
+ };
222
+ return;
248
223
  }
249
- }
250
-
251
- // warn:超量位置参数(仅非 greedy 模式;greedy 全部吸收进首参,不算多余)
252
- if (!greedyFirst && def.inputs && positional.length > def.inputs.length) {
253
- const dropped = positional.slice(def.inputs.length);
254
224
  yield {
255
- type: 'warning',
256
- message: `⚠ 忽略了 ${dropped.length} 个多余位置参数: ${dropped.map((d) => JSON.stringify(d)).join(' ')}(workflow "${name}" 只声明了 ${def.inputs.length} 个 input)`,
225
+ type: 'error',
226
+ error: `未找到工作流「${name}」。输入 /workflows 查看可用列表。`,
257
227
  };
228
+ return;
258
229
  }
259
- // warn:位置参数被 --input 覆盖
260
- if (overriddenByKV.length > 0) {
261
- yield {
262
- type: 'warning',
263
- message: `⚠ --input 优先级高于位置参数,以下位置参数被覆盖:${overriddenByKV.join('; ')}`,
264
- };
230
+
231
+ await refreshStableSystemPrompt(opts.history, cwd, tools);
232
+
233
+ for (const w of mapPositional(
234
+ rawInputs,
235
+ positional,
236
+ script.meta.inputs,
237
+ cwd,
238
+ )) {
239
+ yield { type: 'warning', message: `⚠ ${w}` };
265
240
  }
266
241
 
267
- let coerced: Record<string, unknown>;
242
+ const sessionId = opts.runtimeContext?.sessionId ?? 'default';
243
+ let inputs: Record<string, unknown>;
244
+ let inputResourceMap: Record<
245
+ string,
246
+ import('../../../src/plugin-sdk.js').InvocationResource[]
247
+ > = {};
248
+ let resourceFingerprint = '';
268
249
  try {
269
- coerced = coerceInputs(rawInputs, def.inputs);
250
+ const bound = await bindResourceInputs({
251
+ workflowName: script.name,
252
+ sessionId,
253
+ cwd,
254
+ rawInputs,
255
+ defs: script.meta.inputs,
256
+ attachments: opts.inputResources,
257
+ });
258
+ for (const warning of bound.warnings)
259
+ yield {
260
+ type: 'plugin_progress',
261
+ pluginId: 'workflow-runner',
262
+ message: warning,
263
+ };
264
+ inputResourceMap = bound.resourceMap as typeof inputResourceMap;
265
+ resourceFingerprint = bound.resourceIdentity.join('|');
266
+ if (resourceFingerprint)
267
+ bound.inputs.__resource_fingerprint = resourceFingerprint;
268
+ inputs = coerceInputs(
269
+ bound.inputs as Record<string, string>,
270
+ script.meta.inputs,
271
+ );
270
272
  } catch (e) {
271
273
  yield { type: 'error', error: (e as Error).message };
272
274
  return;
273
275
  }
274
276
 
277
+ let preparedManaged:
278
+ | import('../../../src/managedExecution/types.js').PreparedManagedCommand
279
+ | undefined;
280
+ if (script.meta.managedRuntime) {
281
+ const controller = managedCommandController(script.meta.managedRuntime);
282
+ if (!controller) {
283
+ yield {
284
+ type: 'error',
285
+ error: `未知 managedRuntime:${script.meta.managedRuntime}`,
286
+ };
287
+ return;
288
+ }
289
+ preparedManaged = await controller(inputs, {
290
+ cwd,
291
+ runtimeContext: opts.runtimeContext,
292
+ context: opts.managedContext,
293
+ });
294
+ for (const event of preparedManaged.events) yield event;
295
+ if (preparedManaged.handled) return;
296
+ inputs = preparedManaged.inputs;
297
+ // A managed controller may normalize/replace public inputs, but it must not
298
+ // erase the resource component of task identity.
299
+ if (resourceFingerprint && !inputs.__resource_fingerprint)
300
+ inputs.__resource_fingerprint = resourceFingerprint;
301
+ }
302
+
275
303
  const ctx: RunContext = {
276
304
  provider: opts.provider,
277
305
  runtimeContext: opts.runtimeContext,
@@ -286,53 +314,50 @@ export async function* runWorkflowFromCommand(
286
314
  promptCache: opts.promptCache,
287
315
  executeTool: opts.executeTool,
288
316
  toolContext: opts.toolContext,
317
+ managedExecution: preparedManaged?.execution,
318
+ managedBridge: preparedManaged?.bridge,
319
+ inputResources: opts.inputResources,
320
+ inputResourceMap,
289
321
  };
290
322
 
291
- // 透传 runWorkflow 的事件,并观察是否出现终结事件(error / interrupted = 失败或中断,
292
- // 与 gateway broker 的 TERMINAL 判定同一套逻辑)。成功(没见到终结事件)则在末尾补一条
293
- // 通用 `turn_done`,让对外流式协议以通用终结事件收口——否则成功 workflow 只发私有
294
- // workflow_done:gateway TERMINAL 不认它 → 子进程关闭时误补 interrupted;
295
- // `-p --output-format json` 因无 turn_done → stop_reason 兜底 error → ok:false(成功却报失败)。
296
- // 与 runWorkflowsList 末尾的 turn_done 是同一约定;失败/中断不补(error/interrupted 已是终结)。
297
- let sawTerminal = false;
298
- for await (const ev of runWorkflow(def, coerced, ctx)) {
299
- if (ev.type === 'error' || ev.type === 'interrupted') sawTerminal = true;
300
- yield ev;
301
- }
302
- if (!sawTerminal) yield { type: 'turn_done' };
323
+ yield* runWorkflowScript(script, { ctx, inputs });
303
324
  }
304
325
 
305
- /** /workflows —— 列出可用 workflow。yield 一条 text 事件让 UI 显示。 */
306
- export async function* runWorkflowsList(): AsyncGenerator<
307
- LoopEvent,
308
- void,
309
- void
310
- > {
311
- const list = await listWorkflows();
312
- if (list.length === 0) {
313
- yield {
314
- type: 'text',
315
- delta:
316
- '当前没有可用工作流。在 cwd/workflows/ 下放 *.yaml 即可(参考 workflows/schema.json 或 docs/workflow-design.md)。\n',
317
- };
318
- yield { type: 'turn_done' };
319
- return;
326
+ /** `/workflows` —— 列出可用工作流,并如实报出写错的那些。 */
327
+ export async function* runWorkflowsList(
328
+ cwd?: string,
329
+ ): AsyncGenerator<LoopEvent, void, void> {
330
+ const { workflows, failures } = await discoverWorkflows(cwd);
331
+ const lines: string[] = [];
332
+
333
+ if (workflows.length > 0) {
334
+ lines.push('可用工作流:');
335
+ for (const w of workflows) {
336
+ lines.push(
337
+ ` /workflow ${w.name} — ${w.meta.description.split('\n')[0].trim()}`,
338
+ );
339
+ }
320
340
  }
321
- const lines = ['可用工作流:'];
322
- for (const w of list) {
341
+
342
+ if (workflows.length === 0) {
323
343
  lines.push(
324
- ` /workflow ${w.name} — ${w.description.split('\n')[0].trim()}`,
344
+ '当前没有可用工作流。在 workflows/<名字>/workflow.mjs 放一个脚本即可(`/skill workflow-creator` 会带你写)。',
325
345
  );
326
346
  }
347
+
348
+ // 写错的工作流必须报出来 —— 静默消失会让用户以为「我的工作流不见了」。
349
+ if (failures.length > 0) {
350
+ lines.push('');
351
+ lines.push(`⚠ 有 ${failures.length} 个工作流写错了,未能载入:`);
352
+ for (const f of failures) {
353
+ lines.push(` · ${f.name}:${f.errors[0]}`);
354
+ }
355
+ }
356
+
327
357
  lines.push('');
328
- lines.push('运行示例:');
329
- lines.push(
330
- ' /workflow <name> <val> 位置参数(按 inputs 声明顺序,第一个 input 直接写值)',
331
- );
332
- lines.push(' /workflow <name>.yaml <val> .yaml 后缀可省');
333
- lines.push(
334
- ' /workflow <name> --input k=v 显式 KV(多 input 或想跳过中间 input 时用)',
335
- );
358
+ lines.push('运行示例:');
359
+ lines.push(' /workflow <name> <值> 位置参数(按 inputs 声明顺序)');
360
+ lines.push(' /workflow <name> --input k=v 显式 KV');
336
361
  yield { type: 'text', delta: `${lines.join('\n')}\n` };
337
362
  yield { type: 'turn_done' };
338
363
  }
@@ -0,0 +1,40 @@
1
+ export function coerceInputs(raw, defs) {
2
+ const out = {};
3
+ if (!defs)
4
+ return { ...raw };
5
+ for (const def of defs) {
6
+ const rawVal = raw[def.name];
7
+ if (rawVal === undefined) {
8
+ if (def.required)
9
+ throw new Error(`缺少必填 input: ${def.name}`);
10
+ if (def.default !== undefined)
11
+ out[def.name] = def.default;
12
+ continue;
13
+ }
14
+ if (def.type === 'number') {
15
+ const n = typeof rawVal === 'number' || typeof rawVal === 'string'
16
+ ? Number(rawVal)
17
+ : Number.NaN;
18
+ if (!Number.isFinite(n) ||
19
+ (typeof rawVal === 'string' && !rawVal.trim())) {
20
+ throw new Error(`input ${def.name} 必须是数字,收到 "${rawVal}"`);
21
+ }
22
+ out[def.name] = n;
23
+ }
24
+ else if (def.type === 'enum') {
25
+ if (typeof rawVal !== 'string' || !def.values?.includes(rawVal)) {
26
+ throw new Error(`input ${def.name} 必须是 [${def.values?.join(', ')}] 之一,收到 "${rawVal}"`);
27
+ }
28
+ out[def.name] = rawVal;
29
+ }
30
+ else {
31
+ if (typeof rawVal !== 'string')
32
+ throw new Error(`input ${def.name} 必须是字符串`);
33
+ out[def.name] = rawVal;
34
+ }
35
+ }
36
+ for (const k of Object.keys(raw))
37
+ if (!(k in out))
38
+ out[k] = raw[k];
39
+ return out;
40
+ }
@@ -0,0 +1,43 @@
1
+ import type { InputDef } from './types.js';
2
+
3
+ export function coerceInputs(
4
+ raw: Record<string, unknown>,
5
+ defs: InputDef[] | undefined,
6
+ ): Record<string, unknown> {
7
+ const out: Record<string, unknown> = {};
8
+ if (!defs) return { ...raw };
9
+ for (const def of defs) {
10
+ const rawVal = raw[def.name];
11
+ if (rawVal === undefined) {
12
+ if (def.required) throw new Error(`缺少必填 input: ${def.name}`);
13
+ if (def.default !== undefined) out[def.name] = def.default;
14
+ continue;
15
+ }
16
+ if (def.type === 'number') {
17
+ const n =
18
+ typeof rawVal === 'number' || typeof rawVal === 'string'
19
+ ? Number(rawVal)
20
+ : Number.NaN;
21
+ if (
22
+ !Number.isFinite(n) ||
23
+ (typeof rawVal === 'string' && !rawVal.trim())
24
+ ) {
25
+ throw new Error(`input ${def.name} 必须是数字,收到 "${rawVal}"`);
26
+ }
27
+ out[def.name] = n;
28
+ } else if (def.type === 'enum') {
29
+ if (typeof rawVal !== 'string' || !def.values?.includes(rawVal)) {
30
+ throw new Error(
31
+ `input ${def.name} 必须是 [${def.values?.join(', ')}] 之一,收到 "${rawVal}"`,
32
+ );
33
+ }
34
+ out[def.name] = rawVal;
35
+ } else {
36
+ if (typeof rawVal !== 'string')
37
+ throw new Error(`input ${def.name} 必须是字符串`);
38
+ out[def.name] = rawVal;
39
+ }
40
+ }
41
+ for (const k of Object.keys(raw)) if (!(k in out)) out[k] = raw[k];
42
+ return out;
43
+ }