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
@@ -0,0 +1,294 @@
1
+ import { describe, expect, test } from 'bun:test';
2
+ import { mkdir, mkdtemp, readFile, rm, writeFile } from 'node:fs/promises';
3
+ import { tmpdir } from 'node:os';
4
+ import { join } from 'node:path';
5
+
6
+ import type { InvocationResource } from '../../../src/plugin-sdk.js';
7
+ import {
8
+ bindResourceInputs,
9
+ materializeResources,
10
+ } from '../src/resourceInputs.js';
11
+
12
+ const imageDef = {
13
+ name: 'source',
14
+ type: 'resource' as const,
15
+ required: true,
16
+ accepts: ['image/*'],
17
+ allowFile: true,
18
+ allowDirectory: true,
19
+ multiple: true,
20
+ attachmentFallback: true,
21
+ };
22
+
23
+ describe('workflow resource inputs', () => {
24
+ test('binds compatible Desktop attachments and materializes multiple files', async () => {
25
+ const root = await mkdtemp(join(tmpdir(), 'workflow-resource-'));
26
+ try {
27
+ const a = join(root, 'a.jpg');
28
+ const b = join(root, 'b.png');
29
+ await writeFile(a, 'a');
30
+ await writeFile(b, 'b');
31
+ const attachments: InvocationResource[] = [
32
+ {
33
+ id: 'a',
34
+ origin: 'attachment',
35
+ name: 'a.jpg',
36
+ mime: 'image/jpeg',
37
+ size: 1,
38
+ sha256: 'sha-a',
39
+ localPath: a,
40
+ kind: 'file',
41
+ },
42
+ {
43
+ id: 'b',
44
+ origin: 'attachment',
45
+ name: 'b.png',
46
+ mime: 'image/png',
47
+ size: 1,
48
+ sha256: 'sha-b',
49
+ localPath: b,
50
+ kind: 'file',
51
+ },
52
+ ];
53
+ const bound = await bindResourceInputs({
54
+ workflowName: 'wrong-question-docx',
55
+ sessionId: 's1',
56
+ rawInputs: {},
57
+ defs: [imageDef],
58
+ attachments,
59
+ });
60
+ expect(typeof bound.inputs.source).toBe('string');
61
+ expect(bound.resourceMap.source).toHaveLength(2);
62
+ expect(bound.resourceIdentity).toEqual(['source:sha-a', 'source:sha-b']);
63
+ const staged = String(bound.inputs.source);
64
+ expect(await readFile(join(staged, '001-a.jpg'), 'utf8')).toBe('a');
65
+ expect(await readFile(join(staged, '002-b.png'), 'utf8')).toBe('b');
66
+ } finally {
67
+ await rm(root, { recursive: true, force: true });
68
+ }
69
+ });
70
+
71
+ test('explicit path wins over attachments', async () => {
72
+ const root = await mkdtemp(join(tmpdir(), 'workflow-resource-'));
73
+ try {
74
+ const path = join(root, 'paper.jpg');
75
+ await writeFile(path, 'paper');
76
+ const bound = await bindResourceInputs({
77
+ workflowName: 'wrong-question-docx',
78
+ sessionId: 's1',
79
+ rawInputs: { source: path },
80
+ defs: [imageDef],
81
+ attachments: [
82
+ {
83
+ id: 'other',
84
+ origin: 'attachment',
85
+ name: 'other.jpg',
86
+ mime: 'image/jpeg',
87
+ localPath: path,
88
+ kind: 'file',
89
+ },
90
+ ],
91
+ });
92
+ expect(bound.inputs.source).toBe(path);
93
+ expect(bound.resourceMap.source?.[0]?.origin).toBe('path');
94
+ expect(bound.warnings).toHaveLength(0);
95
+ } finally {
96
+ await rm(root, { recursive: true, force: true });
97
+ }
98
+ });
99
+
100
+ test('relative explicit paths resolve from the workflow cwd', async () => {
101
+ const root = await mkdtemp(join(tmpdir(), 'workflow-resource-'));
102
+ try {
103
+ await writeFile(join(root, 'paper.jpg'), 'paper');
104
+ const bound = await bindResourceInputs({
105
+ workflowName: 'wrong-question-docx',
106
+ sessionId: 's1',
107
+ cwd: root,
108
+ rawInputs: { source: 'paper.jpg' },
109
+ defs: [imageDef],
110
+ });
111
+ expect(bound.inputs.source).toBe(join(root, 'paper.jpg'));
112
+ } finally {
113
+ await rm(root, { recursive: true, force: true });
114
+ }
115
+ });
116
+
117
+ test('directory materialization stages even one Desktop file', async () => {
118
+ const root = await mkdtemp(join(tmpdir(), 'workflow-resource-'));
119
+ try {
120
+ const file = join(root, 'one.jpg');
121
+ await writeFile(file, 'one');
122
+ const bound = await bindResourceInputs({
123
+ workflowName: 'e2e-vision-schema',
124
+ sessionId: 's1',
125
+ rawInputs: {},
126
+ defs: [
127
+ {
128
+ ...imageDef,
129
+ name: 'dir',
130
+ allowFile: false,
131
+ materialize: 'directory',
132
+ },
133
+ ],
134
+ attachments: [
135
+ {
136
+ id: 'one',
137
+ origin: 'attachment',
138
+ name: 'one.jpg',
139
+ mime: 'image/jpeg',
140
+ sha256: 'sha-one',
141
+ localPath: file,
142
+ kind: 'file',
143
+ },
144
+ ],
145
+ });
146
+ expect(
147
+ await readFile(join(String(bound.inputs.dir), '001-one.jpg'), 'utf8'),
148
+ ).toBe('one');
149
+ } finally {
150
+ await rm(root, { recursive: true, force: true });
151
+ }
152
+ });
153
+
154
+ test('single Desktop file also uses a stable Runner copy', async () => {
155
+ const root = await mkdtemp(join(tmpdir(), 'workflow-resource-'));
156
+ try {
157
+ const file = join(root, 'one.jpg');
158
+ await writeFile(file, 'one');
159
+ const bound = await bindResourceInputs({
160
+ workflowName: 'wrong-question-docx',
161
+ sessionId: 's1',
162
+ rawInputs: {},
163
+ defs: [{ ...imageDef, multiple: false }],
164
+ attachments: [
165
+ {
166
+ id: 'one',
167
+ origin: 'attachment',
168
+ name: 'one.jpg',
169
+ mime: 'image/jpeg',
170
+ sha256: 'sha-one',
171
+ localPath: file,
172
+ kind: 'file',
173
+ },
174
+ ],
175
+ });
176
+ expect(bound.inputs.source).not.toBe(file);
177
+ expect(await readFile(String(bound.inputs.source), 'utf8')).toBe('one');
178
+ } finally {
179
+ await rm(root, { recursive: true, force: true });
180
+ }
181
+ });
182
+
183
+ test('reference identity uses resource ids instead of content hashes', async () => {
184
+ const root = await mkdtemp(join(tmpdir(), 'workflow-resource-'));
185
+ try {
186
+ const path = join(root, 'paper.jpg');
187
+ await writeFile(path, 'paper');
188
+ const bound = await bindResourceInputs({
189
+ workflowName: 'demo',
190
+ sessionId: 's1',
191
+ rawInputs: { source: path },
192
+ defs: [{ ...imageDef, identity: 'reference' }],
193
+ });
194
+ expect(bound.resourceIdentity).toHaveLength(1);
195
+ expect(bound.resourceIdentity[0]).toMatch(/^source:path-[a-f0-9]{24}$/);
196
+ } finally {
197
+ await rm(root, { recursive: true, force: true });
198
+ }
199
+ });
200
+
201
+ test('content identity notices changes inside an explicit directory', async () => {
202
+ const root = await mkdtemp(join(tmpdir(), 'workflow-resource-'));
203
+ try {
204
+ const source = join(root, 'papers');
205
+ await mkdir(source);
206
+ await writeFile(join(source, 'page.jpg'), 'page-a');
207
+ const options = {
208
+ workflowName: 'wrong-question-docx',
209
+ sessionId: 's1',
210
+ rawInputs: { source },
211
+ defs: [imageDef],
212
+ };
213
+ const first = await bindResourceInputs(options);
214
+ await writeFile(join(source, 'page.jpg'), 'page-b');
215
+ const second = await bindResourceInputs(options);
216
+ expect(first.resourceIdentity).not.toEqual(second.resourceIdentity);
217
+ } finally {
218
+ await rm(root, { recursive: true, force: true });
219
+ }
220
+ });
221
+
222
+ test('rejects incompatible attachments instead of guessing', async () => {
223
+ const bound = await bindResourceInputs({
224
+ workflowName: 'wrong-question-docx',
225
+ sessionId: 's1',
226
+ rawInputs: {},
227
+ defs: [imageDef],
228
+ attachments: [
229
+ {
230
+ id: 'pdf',
231
+ origin: 'attachment',
232
+ name: 'paper.pdf',
233
+ mime: 'application/pdf',
234
+ localPath: '/tmp/paper.pdf',
235
+ kind: 'file',
236
+ },
237
+ ],
238
+ });
239
+ expect(bound.inputs.source).toBeUndefined();
240
+ expect(bound.resourceMap.source).toBeUndefined();
241
+ });
242
+
243
+ test('rejects attachment batches above maxItems', async () => {
244
+ await expect(
245
+ bindResourceInputs({
246
+ workflowName: 'wrong-question-docx',
247
+ sessionId: 's1',
248
+ rawInputs: {},
249
+ defs: [{ ...imageDef, maxItems: 1 }],
250
+ attachments: [
251
+ {
252
+ id: 'a',
253
+ origin: 'attachment',
254
+ name: 'a.jpg',
255
+ mime: 'image/jpeg',
256
+ localPath: '/tmp/a.jpg',
257
+ kind: 'file',
258
+ },
259
+ {
260
+ id: 'b',
261
+ origin: 'attachment',
262
+ name: 'b.jpg',
263
+ mime: 'image/jpeg',
264
+ localPath: '/tmp/b.jpg',
265
+ kind: 'file',
266
+ },
267
+ ],
268
+ }),
269
+ ).rejects.toThrow('最多允许 1 个附件');
270
+ });
271
+
272
+ test('staging path is stable for the same resources', async () => {
273
+ const root = await mkdtemp(join(tmpdir(), 'workflow-resource-'));
274
+ try {
275
+ const file = join(root, 'x.jpg');
276
+ await writeFile(file, 'x');
277
+ const resource: InvocationResource = {
278
+ id: 'x',
279
+ origin: 'attachment',
280
+ name: 'x.jpg',
281
+ mime: 'image/jpeg',
282
+ size: 1,
283
+ sha256: 'sha-x',
284
+ localPath: file,
285
+ kind: 'file',
286
+ };
287
+ expect(await materializeResources('wf', 's', 'source', [resource])).toBe(
288
+ await materializeResources('wf', 's', 'source', [resource]),
289
+ );
290
+ } finally {
291
+ await rm(root, { recursive: true, force: true });
292
+ }
293
+ });
294
+ });
@@ -0,0 +1,126 @@
1
+ import { afterEach, describe, expect, test } from 'bun:test';
2
+ import { mkdtemp, mkdir, rm, writeFile } from 'node:fs/promises';
3
+ import { tmpdir } from 'node:os';
4
+ import { join } from 'node:path';
5
+
6
+ import { WorkflowScriptError, runScript } from '../src/sandbox.js';
7
+ import { validateScript } from '../src/scriptGuard.mjs';
8
+ import type { WorkflowScript } from '../src/types.js';
9
+
10
+ const dirs: string[] = [];
11
+ afterEach(async () => {
12
+ for (const dir of dirs.splice(0)) await rm(dir, { recursive: true, force: true });
13
+ });
14
+
15
+ async function workflow(source: string, name = 'test-flow'): Promise<WorkflowScript> {
16
+ const root = await mkdtemp(join(tmpdir(), 'wf-esm-'));
17
+ dirs.push(root);
18
+ const dir = join(root, name);
19
+ await mkdir(dir, { recursive: true });
20
+ const scriptPath = join(dir, 'workflow.mjs');
21
+ await writeFile(scriptPath, source);
22
+ const verdict = validateScript(source, { filename: scriptPath });
23
+ if (!verdict.ok || verdict.bodyOffset === undefined) {
24
+ throw new Error(verdict.errors.join('; '));
25
+ }
26
+ return {
27
+ name,
28
+ dir,
29
+ scriptPath,
30
+ source,
31
+ meta: { apiVersion: 2, description: 'test' },
32
+ bodyOffset: verdict.bodyOffset,
33
+ };
34
+ }
35
+
36
+ const head = `export const meta = { apiVersion: 2, description: 'test' };\n`;
37
+
38
+ describe('trusted ESM workflow loader', () => {
39
+ test('default run receives an isolated wf object and returns JSON data', async () => {
40
+ const script = await workflow(
41
+ `${head}export default async function run(wf) { return { value: wf.input.values.x }; }`,
42
+ );
43
+ expect(
44
+ await runScript(script, { input: { values: { x: 42 } } }, 'bundle-a'),
45
+ ).toEqual({ value: 42 });
46
+ });
47
+
48
+ test('native relative imports resolve from the workflow directory', async () => {
49
+ const script = await workflow(
50
+ `${head}import { twice } from './scripts/math.mjs';\nexport default async function run(wf) { return twice(6); }`,
51
+ );
52
+ await mkdir(join(script.dir, 'scripts'), { recursive: true });
53
+ await writeFile(
54
+ join(script.dir, 'scripts', 'math.mjs'),
55
+ 'export const twice = (value) => value * 2;\n',
56
+ );
57
+ expect(await runScript(script, {}, 'bundle-b')).toBe(12);
58
+ });
59
+
60
+ test('bundle hash selects a fresh physical ESM graph when a helper changes', async () => {
61
+ const script = await workflow(
62
+ `${head}import { value } from './scripts/value.mjs';\nexport default async function run(wf) { return value; }`,
63
+ );
64
+ const helper = join(script.dir, 'scripts', 'value.mjs');
65
+ await mkdir(join(script.dir, 'scripts'), { recursive: true });
66
+ await writeFile(helper, 'export const value = 1;\n');
67
+ expect(await runScript(script, {}, 'bundle-helper-v1')).toBe(1);
68
+ await writeFile(helper, 'export const value = 2;\n');
69
+ expect(await runScript(script, {}, 'bundle-helper-v2')).toBe(2);
70
+ });
71
+
72
+ test('concurrent instances do not share run-local state', async () => {
73
+ const script = await workflow(
74
+ `${head}export default async function run(wf) { let value = wf.input.values.value; await Promise.resolve(); value += 1; return value; }`,
75
+ );
76
+ expect(
77
+ await Promise.all([
78
+ runScript(script, { input: { values: { value: 1 } } }, 'bundle-c'),
79
+ runScript(script, { input: { values: { value: 9 } } }, 'bundle-c'),
80
+ ]),
81
+ ).toEqual([2, 10]);
82
+ });
83
+
84
+ test('wide concurrent fan-out sharing one bundle hash does not race the ESM cache rename (Windows EPERM regression)', async () => {
85
+ const script = await workflow(
86
+ `${head}export default async function run(wf) { let value = wf.input.values.value; await Promise.resolve(); value += 1; return value; }`,
87
+ );
88
+ const N = 16;
89
+ const results = await Promise.all(
90
+ Array.from({ length: N }, (_, i) =>
91
+ runScript(script, { input: { values: { value: i } } }, 'bundle-wide'),
92
+ ),
93
+ );
94
+ expect(results).toEqual(Array.from({ length: N }, (_, i) => i + 1));
95
+ });
96
+
97
+ test('runtime errors preserve workflow outcome and cause', async () => {
98
+ const script = await workflow(
99
+ `${head}export default async function run(wf) { throw Object.assign(new Error('budget'), { workflowOutcome: 'budget_limited' }); }`,
100
+ );
101
+ const error = await runScript(script, {}, 'bundle-d').catch((value) => value);
102
+ expect(error).toBeInstanceOf(WorkflowScriptError);
103
+ expect(error).toMatchObject({ workflowOutcome: 'budget_limited' });
104
+ expect((error as WorkflowScriptError).cause).toBeInstanceOf(Error);
105
+ });
106
+
107
+ test('AbortError passes through without workflow-failure wrapping', async () => {
108
+ const script = await workflow(
109
+ `${head}export default async function run(wf) { const e = new Error('stop'); e.name = 'AbortError'; throw e; }`,
110
+ );
111
+ const error = await runScript(script, {}, 'bundle-e').catch((value) => value);
112
+ expect((error as Error).name).toBe('AbortError');
113
+ expect(error).not.toBeInstanceOf(WorkflowScriptError);
114
+ });
115
+
116
+ test('module parse failures are reported as module-load failures', async () => {
117
+ const script = await workflow(
118
+ `${head}export default async function run(wf) { return 1; }`,
119
+ );
120
+ const invalid = `${head}export default async function run( {`;
121
+ await writeFile(script.scriptPath, invalid);
122
+ await expect(
123
+ runScript({ ...script, source: invalid }, {}, 'bundle-f-invalid'),
124
+ ).rejects.toThrow(/模块加载失败/);
125
+ });
126
+ });
@@ -0,0 +1,70 @@
1
+ import { describe, expect, test } from 'bun:test';
2
+ import { readWorkflowRuntimeConfig } from '../src/runtime/config.js';
3
+ import { WorkflowScheduler } from '../src/runtime/scheduler.js';
4
+
5
+ const config = (overrides: Partial<ReturnType<typeof readWorkflowRuntimeConfig>> = {}) => ({
6
+ ...readWorkflowRuntimeConfig({} as NodeJS.ProcessEnv),
7
+ ...overrides,
8
+ });
9
+
10
+ describe('WorkflowScheduler', () => {
11
+ test('进程级资源上限覆盖不同根运行', async () => {
12
+ const scheduler = new WorkflowScheduler(config({ modelConcurrency: 2 }));
13
+ let active = 0;
14
+ let peak = 0;
15
+ await Promise.all(
16
+ Array.from({ length: 12 }, (_, index) =>
17
+ scheduler.run('model', `root-${index % 3}`, async () => {
18
+ active++;
19
+ peak = Math.max(peak, active);
20
+ await new Promise((resolve) => setTimeout(resolve, 4));
21
+ active--;
22
+ }),
23
+ ),
24
+ );
25
+ expect(peak).toBe(2);
26
+ });
27
+
28
+ test('根运行之间轮转,不让一个大队列饿死后来的根', async () => {
29
+ const scheduler = new WorkflowScheduler(config({ toolConcurrency: 1 }));
30
+ const first = await scheduler.acquire('tool', 'root-a');
31
+ const order: string[] = [];
32
+ const queued = [
33
+ scheduler.run('tool', 'root-a', async () => void order.push('a1')),
34
+ scheduler.run('tool', 'root-a', async () => void order.push('a2')),
35
+ scheduler.run('tool', 'root-b', async () => void order.push('b1')),
36
+ scheduler.run('tool', 'root-a', async () => void order.push('a3')),
37
+ ];
38
+ first.release();
39
+ await Promise.all(queued);
40
+ expect(order.indexOf('b1')).toBeLessThan(order.indexOf('a3'));
41
+ });
42
+
43
+ test('取消会移除排队项且不占用槽', async () => {
44
+ const scheduler = new WorkflowScheduler(config({ processConcurrency: 1 }));
45
+ const first = await scheduler.acquire('process', 'root-a');
46
+ const controller = new AbortController();
47
+ const cancelled = scheduler.acquire('process', 'root-b', controller.signal);
48
+ controller.abort(Object.assign(new Error('stop'), { name: 'AbortError' }));
49
+ await expect(cancelled).rejects.toMatchObject({ name: 'AbortError' });
50
+ first.release();
51
+ const lease = await scheduler.acquire('process', 'root-c');
52
+ lease.release();
53
+ });
54
+ });
55
+
56
+ describe('workflow runtime environment', () => {
57
+ test('非法值响亮报错,不静默回默认值', () => {
58
+ expect(() =>
59
+ readWorkflowRuntimeConfig({
60
+ MINIMAL_AGENT_WORKFLOW_MODEL_CONCURRENCY: '0',
61
+ } as NodeJS.ProcessEnv),
62
+ ).toThrow(/MINIMAL_AGENT_WORKFLOW_MODEL_CONCURRENCY/);
63
+ expect(() =>
64
+ readWorkflowRuntimeConfig({
65
+ MINIMAL_AGENT_WORKFLOW_PIPELINE_CONCURRENCY: '10',
66
+ MINIMAL_AGENT_WORKFLOW_PIPELINE_MAX_CONCURRENCY: '5',
67
+ } as NodeJS.ProcessEnv),
68
+ ).toThrow(/不能大于/);
69
+ });
70
+ });