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
@@ -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
+ });