minimal-agent 0.13.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (470) hide show
  1. package/README.md +6 -5
  2. package/package.json +60 -4
  3. package/plugins/computer_use/.claude-plugin/plugin.json +1 -1
  4. package/plugins/cron-runner/src/commands.js +4 -4
  5. package/plugins/cron-runner/src/commands.ts +4 -4
  6. package/plugins/workflow-runner/.claude-plugin/plugin.json +2 -2
  7. package/plugins/workflow-runner/commands/workflow.md +57 -90
  8. package/plugins/workflow-runner/commands/workflows.md +4 -4
  9. package/plugins/workflow-runner/plugin.js +24 -13
  10. package/plugins/workflow-runner/plugin.ts +28 -13
  11. package/plugins/workflow-runner/src/discovery.js +160 -0
  12. package/plugins/workflow-runner/src/discovery.ts +194 -0
  13. package/plugins/workflow-runner/src/goalAnchor.js +53 -0
  14. package/plugins/workflow-runner/src/goalAnchor.ts +59 -0
  15. package/plugins/workflow-runner/src/index.js +197 -206
  16. package/plugins/workflow-runner/src/index.ts +248 -249
  17. package/plugins/workflow-runner/src/inputCoercion.js +40 -0
  18. package/plugins/workflow-runner/src/inputCoercion.ts +43 -0
  19. package/plugins/workflow-runner/src/journal.js +224 -0
  20. package/plugins/workflow-runner/src/journal.ts +274 -0
  21. package/plugins/workflow-runner/src/jsonSchema.js +132 -0
  22. package/plugins/workflow-runner/src/jsonSchema.ts +162 -0
  23. package/plugins/workflow-runner/src/moduleResolution.js +64 -0
  24. package/plugins/workflow-runner/src/moduleResolution.ts +71 -0
  25. package/plugins/workflow-runner/src/resourceInputs.js +220 -0
  26. package/plugins/workflow-runner/src/resourceInputs.ts +300 -0
  27. package/plugins/workflow-runner/src/runner.js +400 -489
  28. package/plugins/workflow-runner/src/runner.ts +488 -560
  29. package/plugins/workflow-runner/src/runtime/config.js +46 -0
  30. package/plugins/workflow-runner/src/runtime/config.ts +69 -0
  31. package/plugins/workflow-runner/src/runtime/context.js +1304 -0
  32. package/plugins/workflow-runner/src/runtime/context.ts +1786 -0
  33. package/plugins/workflow-runner/src/runtime/exec.js +34 -0
  34. package/plugins/workflow-runner/src/runtime/exec.ts +53 -0
  35. package/plugins/workflow-runner/src/runtime/flow.js +8 -0
  36. package/plugins/workflow-runner/src/runtime/flow.ts +12 -0
  37. package/plugins/workflow-runner/src/runtime/fs.js +27 -0
  38. package/plugins/workflow-runner/src/runtime/fs.ts +41 -0
  39. package/plugins/workflow-runner/src/runtime/model.js +6 -0
  40. package/plugins/workflow-runner/src/runtime/model.ts +8 -0
  41. package/plugins/workflow-runner/src/runtime/output.js +7 -0
  42. package/plugins/workflow-runner/src/runtime/output.ts +21 -0
  43. package/plugins/workflow-runner/src/runtime/scheduler.js +141 -0
  44. package/plugins/workflow-runner/src/runtime/scheduler.ts +166 -0
  45. package/plugins/workflow-runner/src/runtime/state.js +16 -0
  46. package/plugins/workflow-runner/src/runtime/state.ts +19 -0
  47. package/plugins/workflow-runner/src/runtime/tools.js +3 -0
  48. package/plugins/workflow-runner/src/runtime/tools.ts +6 -0
  49. package/plugins/workflow-runner/src/sandbox.js +141 -0
  50. package/plugins/workflow-runner/src/sandbox.ts +182 -0
  51. package/plugins/workflow-runner/src/scriptGuard.d.mts +38 -0
  52. package/plugins/workflow-runner/src/scriptGuard.mjs +449 -0
  53. package/plugins/workflow-runner/src/taskIdentity.js +151 -307
  54. package/plugins/workflow-runner/src/taskIdentity.ts +207 -355
  55. package/plugins/workflow-runner/src/toolRuntime.js +29 -8
  56. package/plugins/workflow-runner/src/toolRuntime.ts +36 -11
  57. package/plugins/workflow-runner/src/types.js +7 -211
  58. package/plugins/workflow-runner/src/types.ts +154 -623
  59. package/plugins/workflow-runner/src/util.js +47 -0
  60. package/plugins/workflow-runner/src/util.ts +51 -0
  61. package/plugins/workflow-runner/src/workflowContext.js +20 -0
  62. package/plugins/workflow-runner/src/workflowContext.ts +58 -0
  63. package/plugins/workflow-runner/src/workflowDependencies.js +36 -0
  64. package/plugins/workflow-runner/src/workflowDependencies.ts +59 -0
  65. package/plugins/workflow-runner/src/workflowFingerprint.js +118 -0
  66. package/plugins/workflow-runner/src/workflowFingerprint.ts +122 -0
  67. package/plugins/workflow-runner/src/workflowState.js +474 -802
  68. package/plugins/workflow-runner/src/workflowState.ts +575 -970
  69. package/plugins/workflow-runner/test/api.test.ts +223 -0
  70. package/plugins/workflow-runner/test/apiCapabilities.test.ts +614 -0
  71. package/plugins/workflow-runner/test/apiConcurrencyGate.test.ts +104 -0
  72. package/plugins/workflow-runner/test/apiEcho.test.ts +210 -0
  73. package/plugins/workflow-runner/test/apiReadText.test.ts +178 -0
  74. package/plugins/workflow-runner/test/apiResourceLedger.test.ts +184 -0
  75. package/plugins/workflow-runner/test/childWorkflow.test.ts +304 -0
  76. package/plugins/workflow-runner/test/discovery.test.ts +234 -0
  77. package/plugins/workflow-runner/test/goalAnchor.test.ts +106 -0
  78. package/plugins/workflow-runner/test/goalController.test.ts +317 -0
  79. package/plugins/workflow-runner/test/journalLanes.test.ts +198 -0
  80. package/plugins/workflow-runner/test/listResources.test.ts +106 -0
  81. package/plugins/workflow-runner/test/resourceInputs.test.ts +294 -0
  82. package/plugins/workflow-runner/test/sandbox.test.ts +126 -0
  83. package/plugins/workflow-runner/test/scheduler.test.ts +70 -0
  84. package/plugins/workflow-runner/test/scriptGuard.test.ts +276 -0
  85. package/plugins/workflow-runner/test/skillDocSync.test.ts +78 -0
  86. package/plugins/workflow-runner/test/taskIdentity.test.ts +288 -179
  87. package/plugins/workflow-runner/test/workflowFingerprint.test.ts +106 -0
  88. package/plugins/workflow-runner/test/workflowState.test.ts +429 -0
  89. package/skills/pptx/examples/assets/cover-bg.svg +23 -0
  90. package/skills/pptx/examples/assets/icon-spark.svg +5 -0
  91. package/skills/ui-design/SKILL.md +5 -2
  92. package/skills/ui-design/references/layout-composition.md +1 -1
  93. package/skills/workflow-creator/SKILL.md +344 -0
  94. package/skills/workflow-creator/assets/template/workflow.mjs +48 -0
  95. package/skills/workflow-creator/references/api.md +216 -0
  96. package/skills/workflow-creator/references/migration.md +103 -0
  97. package/skills/workflow-creator/references/patterns.md +779 -0
  98. package/skills/workflow-creator/scripts/list-resources.mjs +205 -0
  99. package/skills/workflow-creator/scripts/scaffold.mjs +148 -0
  100. package/skills/workflow-creator/scripts/validate.mjs +275 -0
  101. package/skills/workflow-creator/scripts/workflow-creator.test.mjs +82 -0
  102. package/src/advisor/advisorCoordinator.js +503 -0
  103. package/src/advisor/advisorCoordinator.ts +657 -0
  104. package/src/cli/configMenu.tsx +0 -1
  105. package/src/cli/print.js +27 -6
  106. package/src/cli/print.ts +48 -4
  107. package/src/cli/streamJson.js +5 -6
  108. package/src/cli/streamJson.ts +8 -4
  109. package/src/cli/wizards/advisorWizard.js +4 -2
  110. package/src/cli/wizards/advisorWizard.tsx +8 -2
  111. package/src/cli/wizards/contextAdvisorWizard.js +5 -4
  112. package/src/cli/wizards/contextAdvisorWizard.tsx +7 -6
  113. package/src/collaboration/taskFlow.js +115 -0
  114. package/src/collaboration/taskFlow.ts +169 -0
  115. package/src/config/configDefaults.js +41 -1
  116. package/src/config/configDefaults.ts +43 -1
  117. package/src/config/configDiagnostics.ts +2 -2
  118. package/src/config/configFile.js +40 -9
  119. package/src/config/configFile.ts +60 -11
  120. package/src/config/configService.js +419 -74
  121. package/src/config/configService.ts +703 -145
  122. package/src/config/numericLimits.js +22 -0
  123. package/src/config/numericLimits.ts +24 -0
  124. package/src/config.js +1 -0
  125. package/src/config.ts +3 -2
  126. package/src/context/budgetPlan.js +1 -1
  127. package/src/context/budgetPlan.ts +1 -1
  128. package/src/context/compact.js +7 -2
  129. package/src/context/compact.ts +9 -2
  130. package/src/context/microCompactLite.js +212 -13
  131. package/src/context/microCompactLite.ts +261 -12
  132. package/src/context/sessionRegistry.js +8 -1
  133. package/src/context/sessionRegistry.ts +18 -5
  134. package/src/context/toolResultArchive.js +72 -0
  135. package/src/context/toolResultArchive.ts +95 -0
  136. package/src/goal/errors.js +8 -0
  137. package/src/goal/errors.ts +18 -0
  138. package/src/goal/goalRuntime.js +344 -0
  139. package/src/goal/goalRuntime.ts +466 -0
  140. package/src/goal/goalStore.js +200 -0
  141. package/src/goal/goalStore.ts +219 -0
  142. package/src/goal/index.js +4 -0
  143. package/src/goal/index.ts +4 -0
  144. package/src/goal/statusMapping.js +71 -0
  145. package/src/goal/statusMapping.ts +95 -0
  146. package/src/goal/types.js +7 -0
  147. package/src/goal/types.ts +179 -0
  148. package/src/goal/workflowController.js +306 -0
  149. package/src/goal/workflowController.ts +360 -0
  150. package/src/harness/evidenceLedger.js +2 -0
  151. package/src/harness/evidenceLedger.ts +1 -0
  152. package/src/harness/stallGuard.js +9 -3
  153. package/src/harness/stallGuard.ts +7 -3
  154. package/src/images/imageResolver.js +161 -0
  155. package/src/images/imageResolver.ts +189 -0
  156. package/src/infra/verification.js +34 -5
  157. package/src/infra/verification.ts +39 -4
  158. package/src/llm/client.js +79 -21
  159. package/src/llm/client.ts +182 -35
  160. package/src/llm/gatewayClient.js +201 -0
  161. package/src/llm/gatewayClient.ts +299 -0
  162. package/src/llm/messageProvenance.js +46 -0
  163. package/src/llm/messageProvenance.ts +58 -0
  164. package/src/llm/modelProvider.js +1 -0
  165. package/src/llm/modelProvider.ts +22 -0
  166. package/src/llm/providers/anthropicFormat.js +108 -1
  167. package/src/llm/providers/anthropicFormat.ts +115 -4
  168. package/src/llm/providers/openaiFormat.js +9 -0
  169. package/src/llm/providers/openaiFormat.ts +12 -3
  170. package/src/loop.js +319 -54
  171. package/src/loop.ts +373 -57
  172. package/src/main.js +4 -1
  173. package/src/main.tsx +4 -1
  174. package/src/managedExecution/index.js +2 -0
  175. package/src/managedExecution/index.ts +2 -0
  176. package/src/managedExecution/registry.js +15 -0
  177. package/src/managedExecution/registry.ts +20 -0
  178. package/src/managedExecution/types.js +1 -0
  179. package/src/managedExecution/types.ts +86 -0
  180. package/src/modelRef.js +9 -0
  181. package/src/modelRef.ts +31 -0
  182. package/src/multimodal.js +14 -28
  183. package/src/multimodal.ts +17 -33
  184. package/src/net/lanDiscovery.js +65 -0
  185. package/src/net/lanDiscovery.ts +82 -0
  186. package/src/plugin-sdk.js +28 -3
  187. package/src/plugin-sdk.ts +39 -6
  188. package/src/plugins/pluginApi.ts +16 -1
  189. package/src/plugins/pluginLoader.js +4 -0
  190. package/src/plugins/pluginLoader.ts +6 -0
  191. package/src/plugins/pluginRunner.js +139 -7
  192. package/src/plugins/pluginRunner.ts +173 -9
  193. package/src/plugins/slashFallback.js +113 -0
  194. package/src/plugins/slashFallback.ts +137 -0
  195. package/src/prompts/policyRegistry.js +12 -32
  196. package/src/prompts/policyRegistry.ts +15 -32
  197. package/src/prompts/promptAssembly.js +103 -12
  198. package/src/prompts/promptAssembly.ts +114 -12
  199. package/src/prompts/skillList.js +21 -3
  200. package/src/prompts/skillList.ts +27 -2
  201. package/src/prompts/stableSystemPrompt.js +18 -0
  202. package/src/prompts/stableSystemPrompt.ts +33 -0
  203. package/src/runtime/agentRuntimeContext.js +8 -2
  204. package/src/runtime/agentRuntimeContext.ts +17 -4
  205. package/src/session/runAgentTurn.js +78 -12
  206. package/src/session/runAgentTurn.ts +105 -23
  207. package/src/session/runTurn.js +10 -9
  208. package/src/session/runTurn.ts +17 -8
  209. package/src/session/sessionState.ts +2 -0
  210. package/src/team/auth.js +186 -0
  211. package/src/team/auth.ts +298 -0
  212. package/src/team/cli.js +105 -0
  213. package/src/team/cli.ts +122 -0
  214. package/src/team/onlineToolContract.js +64 -0
  215. package/src/team/onlineToolContract.ts +109 -0
  216. package/src/team/toolPolicy.js +36 -0
  217. package/src/team/toolPolicy.ts +75 -0
  218. package/src/tools/advisor/advisor.js +90 -46
  219. package/src/tools/advisor/advisor.ts +100 -47
  220. package/src/tools/advisor/advisorDecision.js +71 -0
  221. package/src/tools/advisor/advisorDecision.ts +85 -0
  222. package/src/tools/agent/agent.js +18 -5
  223. package/src/tools/agent/agent.ts +21 -7
  224. package/src/tools/agent/agentControl.js +246 -0
  225. package/src/tools/agent/agentControl.ts +284 -0
  226. package/src/tools/agent/agentTaskService.js +40 -1
  227. package/src/tools/agent/agentTaskService.ts +44 -1
  228. package/src/tools/agent/agentTypes.js +14 -2
  229. package/src/tools/agent/agentTypes.ts +15 -2
  230. package/src/tools/applypatch/applyPatch.js +362 -0
  231. package/src/tools/applypatch/applyPatch.ts +428 -0
  232. package/src/tools/bash/bash.js +22 -15
  233. package/src/tools/bash/bash.ts +23 -17
  234. package/src/tools/capabilities.js +10 -5
  235. package/src/tools/capabilities.ts +10 -5
  236. package/src/tools/computeruse/computerIntent.js +32 -0
  237. package/src/tools/computeruse/computerIntent.ts +46 -0
  238. package/src/tools/computeruse/telemetryLog.js +12 -0
  239. package/src/tools/computeruse/telemetryLog.ts +16 -0
  240. package/src/tools/computeruse/vision/telemetry.js +1 -0
  241. package/src/tools/computeruse/vision/telemetry.ts +1 -0
  242. package/src/tools/effectiveToolSet.js +4 -0
  243. package/src/tools/effectiveToolSet.ts +4 -0
  244. package/src/tools/index.js +21 -2
  245. package/src/tools/index.ts +33 -2
  246. package/src/tools/presentresult/presentresult.js +6 -15
  247. package/src/tools/presentresult/presentresult.ts +6 -15
  248. package/src/tools/read/read.js +62 -9
  249. package/src/tools/read/read.ts +63 -9
  250. package/src/tools/shared/fileUtils.js +1 -2
  251. package/src/tools/shared/fileUtils.ts +1 -2
  252. package/src/tools/shared/toolOutputStore.js +23 -1
  253. package/src/tools/shared/toolOutputStore.ts +22 -1
  254. package/src/tools/skill/skill.js +9 -3
  255. package/src/tools/skill/skill.ts +8 -4
  256. package/src/tools/toolPromptGuides.js +117 -0
  257. package/src/tools/toolPromptGuides.ts +137 -0
  258. package/src/tools/webbrowser/agentBrowserPath.js +19 -9
  259. package/src/tools/webbrowser/agentBrowserPath.ts +70 -28
  260. package/src/tools/webbrowser/browser.js +27 -11
  261. package/src/tools/webbrowser/browser.ts +68 -24
  262. package/src/tools/webbrowser/browserAutomation.js +329 -0
  263. package/src/tools/webbrowser/browserAutomation.ts +467 -0
  264. package/src/tools/webbrowser/browserAxState.js +97 -0
  265. package/src/tools/webbrowser/browserAxState.ts +142 -0
  266. package/src/tools/webbrowser/browserBatch.js +1578 -0
  267. package/src/tools/webbrowser/browserBatch.ts +2382 -0
  268. package/src/tools/webbrowser/browserCdp.js +208 -0
  269. package/src/tools/webbrowser/browserCdp.ts +255 -0
  270. package/src/tools/webbrowser/browserConditions.js +24 -0
  271. package/src/tools/webbrowser/browserConditions.ts +45 -0
  272. package/src/tools/webbrowser/browserContent.js +281 -0
  273. package/src/tools/webbrowser/browserContent.ts +438 -0
  274. package/src/tools/webbrowser/browserControl.js +131 -34
  275. package/src/tools/webbrowser/browserControl.ts +210 -56
  276. package/src/tools/webbrowser/browserDaemon.js +22 -14
  277. package/src/tools/webbrowser/browserDaemon.ts +54 -21
  278. package/src/tools/webbrowser/browserFrames.js +47 -0
  279. package/src/tools/webbrowser/browserFrames.ts +54 -0
  280. package/src/tools/webbrowser/browserInteractionResolver.js +17 -0
  281. package/src/tools/webbrowser/browserInteractionResolver.ts +40 -0
  282. package/src/tools/webbrowser/browserLocator.js +140 -0
  283. package/src/tools/webbrowser/browserLocator.ts +194 -0
  284. package/src/tools/webbrowser/browserOutcome.js +10 -17
  285. package/src/tools/webbrowser/browserOutcome.ts +48 -31
  286. package/src/tools/webbrowser/browserRecovery.js +58 -0
  287. package/src/tools/webbrowser/browserRecovery.ts +83 -0
  288. package/src/tools/webbrowser/browserRunRegistry.js +35 -3
  289. package/src/tools/webbrowser/browserRunRegistry.ts +91 -15
  290. package/src/tools/webbrowser/browserService.js +28 -2
  291. package/src/tools/webbrowser/browserService.ts +49 -9
  292. package/src/tools/webbrowser/browserStream.js +132 -33
  293. package/src/tools/webbrowser/browserStream.ts +224 -50
  294. package/src/tools/webbrowser/browserTabs.js +48 -15
  295. package/src/tools/webbrowser/browserTabs.ts +178 -96
  296. package/src/tools/webbrowser/webbrowser.js +679 -144
  297. package/src/tools/webbrowser/webbrowser.ts +975 -236
  298. package/src/tools/webfetch/preapproved.js +0 -2
  299. package/src/tools/webfetch/preapproved.ts +0 -2
  300. package/src/tools/websearch/websearch.js +129 -8
  301. package/src/tools/websearch/websearch.ts +138 -6
  302. package/src/types.ts +440 -38
  303. package/src/ui/App.js +377 -58
  304. package/src/ui/App.tsx +576 -111
  305. package/src/ui/LiveArea.js +14 -8
  306. package/src/ui/LiveArea.tsx +14 -10
  307. package/src/ui/MessageList.js +63 -20
  308. package/src/ui/MessageList.tsx +101 -16
  309. package/src/ui/ModelPicker.js +7 -4
  310. package/src/ui/ModelPicker.tsx +55 -8
  311. package/src/ui/hooks/useChat.js +152 -163
  312. package/src/ui/hooks/useChat.ts +396 -334
  313. package/src/ui/loginCommand.js +56 -0
  314. package/src/ui/loginCommand.ts +63 -0
  315. package/src/ui/toolProgress.js +41 -0
  316. package/src/ui/toolProgress.ts +44 -0
  317. package/src/web/browserBridge.js +20 -2
  318. package/src/web/browserBridge.ts +20 -2
  319. package/src/web/protocol.ts +1897 -194
  320. package/workflows/adaptive-research/workflow.mjs +86 -0
  321. package/workflows/e2e-capabilities/workflow.mjs +102 -0
  322. package/workflows/e2e-llm/workflow.mjs +52 -0
  323. package/workflows/e2e-smoke/workflow.mjs +59 -0
  324. package/workflows/e2e-vision-schema/README.md +48 -0
  325. package/workflows/e2e-vision-schema/workflow.mjs +149 -0
  326. package/workflows/e2e-write-greet/workflow.mjs +37 -0
  327. package/workflows/file-census/README.md +14 -0
  328. package/workflows/file-census/scripts/.gitkeep +2 -0
  329. package/workflows/file-census/workflow.mjs +110 -0
  330. package/workflows/goal/README.md +166 -0
  331. package/workflows/goal/prompts/audit.md +57 -0
  332. package/workflows/goal/prompts/contract.md +56 -0
  333. package/workflows/goal/prompts/iterate.md +37 -0
  334. package/workflows/goal/workflow.mjs +501 -0
  335. package/workflows/illustrate/README.md +90 -0
  336. package/workflows/illustrate/assets/engines.json +20 -0
  337. package/workflows/illustrate/assets/extract-baidu.js +21 -0
  338. package/workflows/illustrate/assets/extract-bing.js +33 -0
  339. package/workflows/illustrate/assets/extract-google.js +31 -0
  340. package/workflows/illustrate/workflow.mjs +301 -0
  341. package/workflows/plan/workflow.mjs +389 -0
  342. package/workflows/question-crops/README.md +35 -0
  343. package/workflows/question-crops/prompts/inventory.md +23 -0
  344. package/workflows/question-crops/scripts/image-ops.mjs +305 -0
  345. package/workflows/question-crops/scripts/image-ops.test.mjs +95 -0
  346. package/workflows/question-crops/workflow.mjs +172 -0
  347. package/workflows/ralph-loop/workflow.mjs +162 -0
  348. package/workflows/research/README.md +74 -0
  349. package/workflows/research/prompts/s0-goal.md +43 -0
  350. package/workflows/research/prompts/s1-early-exit.md +22 -0
  351. package/workflows/research/prompts/s1-map.md +58 -0
  352. package/workflows/research/prompts/s2-options.md +53 -0
  353. package/workflows/research/prompts/s3-deep-dive.md +56 -0
  354. package/workflows/research/prompts/s4-verify.md +74 -0
  355. package/workflows/research/prompts/s5-synthesis.md +81 -0
  356. package/workflows/research/prompts/s5b-fill-gaps.md +32 -0
  357. package/workflows/research/prompts/s6-package.md +32 -0
  358. package/workflows/research/scripts/build-report.mjs +98 -0
  359. package/workflows/research/workflow.mjs +288 -0
  360. package/workflows/wechat-reading-shots/prompts/collect-params.md +16 -0
  361. package/workflows/wechat-reading-shots/prompts/evaluate.md +20 -0
  362. package/workflows/wechat-reading-shots/prompts/open-book.md +28 -0
  363. package/workflows/wechat-reading-shots/prompts/read-page.md +13 -0
  364. package/workflows/wechat-reading-shots/prompts/turn-batch.md +24 -0
  365. package/workflows/wechat-reading-shots/test/control-flow.test.ts +329 -0
  366. package/workflows/wechat-reading-shots/workflow.mjs +266 -0
  367. package/workflows/wrong-question-docx/README.md +55 -0
  368. package/workflows/wrong-question-docx/prompts/figure-qa.md +8 -0
  369. package/workflows/wrong-question-docx/prompts/transcribe.md +25 -0
  370. package/workflows/wrong-question-docx/scripts/workbook.mjs +857 -0
  371. package/workflows/wrong-question-docx/test/control-flow.test.ts +165 -0
  372. package/workflows/wrong-question-docx/test/workbook.test.mjs +303 -0
  373. package/workflows/wrong-question-docx/workflow.mjs +485 -0
  374. package/plugins/workflow-runner/src/agentCommon.js +0 -354
  375. package/plugins/workflow-runner/src/agentCommon.ts +0 -435
  376. package/plugins/workflow-runner/src/controlFlow/branch.js +0 -40
  377. package/plugins/workflow-runner/src/controlFlow/branch.ts +0 -46
  378. package/plugins/workflow-runner/src/controlFlow/loop.js +0 -211
  379. package/plugins/workflow-runner/src/controlFlow/loop.ts +0 -248
  380. package/plugins/workflow-runner/src/controlFlow/pause.js +0 -129
  381. package/plugins/workflow-runner/src/controlFlow/pause.ts +0 -141
  382. package/plugins/workflow-runner/src/controlFlow/signal.js +0 -21
  383. package/plugins/workflow-runner/src/controlFlow/signal.ts +0 -29
  384. package/plugins/workflow-runner/src/controlFlow/types.js +0 -18
  385. package/plugins/workflow-runner/src/controlFlow/types.ts +0 -63
  386. package/plugins/workflow-runner/src/dslManifest.js +0 -72
  387. package/plugins/workflow-runner/src/dslManifest.ts +0 -127
  388. package/plugins/workflow-runner/src/expressions.js +0 -639
  389. package/plugins/workflow-runner/src/expressions.ts +0 -640
  390. package/plugins/workflow-runner/src/loader.js +0 -573
  391. package/plugins/workflow-runner/src/loader.ts +0 -721
  392. package/plugins/workflow-runner/src/multimodal.js +0 -38
  393. package/plugins/workflow-runner/src/multimodal.ts +0 -64
  394. package/plugins/workflow-runner/src/recovery.js +0 -126
  395. package/plugins/workflow-runner/src/recovery.ts +0 -156
  396. package/plugins/workflow-runner/src/stepExecutors/agent.js +0 -173
  397. package/plugins/workflow-runner/src/stepExecutors/agent.ts +0 -234
  398. package/plugins/workflow-runner/src/stepExecutors/assert.js +0 -42
  399. package/plugins/workflow-runner/src/stepExecutors/assert.ts +0 -52
  400. package/plugins/workflow-runner/src/stepExecutors/echo.js +0 -31
  401. package/plugins/workflow-runner/src/stepExecutors/echo.ts +0 -38
  402. package/plugins/workflow-runner/src/stepExecutors/llm.js +0 -99
  403. package/plugins/workflow-runner/src/stepExecutors/llm.ts +0 -133
  404. package/plugins/workflow-runner/src/stepExecutors/set.js +0 -49
  405. package/plugins/workflow-runner/src/stepExecutors/set.ts +0 -56
  406. package/plugins/workflow-runner/src/stepExecutors/skill.js +0 -111
  407. package/plugins/workflow-runner/src/stepExecutors/skill.ts +0 -140
  408. package/plugins/workflow-runner/src/stepExecutors/tool.js +0 -227
  409. package/plugins/workflow-runner/src/stepExecutors/tool.ts +0 -274
  410. package/plugins/workflow-runner/src/stepExecutors/verify.js +0 -61
  411. package/plugins/workflow-runner/src/stepExecutors/verify.ts +0 -72
  412. package/plugins/workflow-runner/src/stepPipeline.js +0 -277
  413. package/plugins/workflow-runner/src/stepPipeline.ts +0 -366
  414. package/plugins/workflow-runner/test/agent.test.ts +0 -587
  415. package/plugins/workflow-runner/test/agentLlmError.test.ts +0 -373
  416. package/plugins/workflow-runner/test/bashBlacklist.sweep.test.ts +0 -65
  417. package/plugins/workflow-runner/test/captureMisbind.test.ts +0 -99
  418. package/plugins/workflow-runner/test/cli.e2e.test.ts +0 -167
  419. package/plugins/workflow-runner/test/context-files.test.ts +0 -320
  420. package/plugins/workflow-runner/test/e2e.test.ts +0 -370
  421. package/plugins/workflow-runner/test/e2eNewLayout.test.ts +0 -314
  422. package/plugins/workflow-runner/test/engineRobustness.test.ts +0 -234
  423. package/plugins/workflow-runner/test/expressions.test.ts +0 -439
  424. package/plugins/workflow-runner/test/foundation.test.ts +0 -126
  425. package/plugins/workflow-runner/test/graceful.test.ts +0 -139
  426. package/plugins/workflow-runner/test/greedyInputs.load.test.ts +0 -47
  427. package/plugins/workflow-runner/test/hostCapability.test.ts +0 -108
  428. package/plugins/workflow-runner/test/illustrate.load.test.ts +0 -183
  429. package/plugins/workflow-runner/test/jsonPayload.test.ts +0 -83
  430. package/plugins/workflow-runner/test/loader.test.ts +0 -617
  431. package/plugins/workflow-runner/test/maxTurnsRetryDelay.test.ts +0 -33
  432. package/plugins/workflow-runner/test/multimodal.test.ts +0 -342
  433. package/plugins/workflow-runner/test/output-schema.test.ts +0 -213
  434. package/plugins/workflow-runner/test/parseWorkflowArgs.test.ts +0 -106
  435. package/plugins/workflow-runner/test/pluginRunner.isolation.test.ts +0 -269
  436. package/plugins/workflow-runner/test/ppt.load.test.ts +0 -1220
  437. package/plugins/workflow-runner/test/ralphLoop.e2e.test.ts +0 -221
  438. package/plugins/workflow-runner/test/recovery.test.ts +0 -265
  439. package/plugins/workflow-runner/test/research.load.test.ts +0 -328
  440. package/plugins/workflow-runner/test/runner.test.ts +0 -911
  441. package/plugins/workflow-runner/test/runnerPreflight.test.ts +0 -436
  442. package/plugins/workflow-runner/test/skillTurnDone.test.ts +0 -71
  443. package/plugins/workflow-runner/test/stateLifecycle.test.ts +0 -198
  444. package/plugins/workflow-runner/test/stepPipeline.test.ts +0 -114
  445. package/plugins/workflow-runner/test/taskArbitration.test.ts +0 -354
  446. package/plugins/workflow-runner/test/taskLifecycle.test.ts +0 -324
  447. package/plugins/workflow-runner/test/toolArtifactOverwrite.test.ts +0 -221
  448. package/plugins/workflow-runner/test/toolCapabilityBoundary.test.ts +0 -29
  449. package/plugins/workflow-runner/test/toolRuntimeIntegration.test.ts +0 -168
  450. package/plugins/workflow-runner/test/webppt.load.test.ts +0 -250
  451. package/plugins/workflow-runner/test/word.load.test.ts +0 -208
  452. package/plugins/workflow-runner/test/workflows.smoke.test.ts +0 -76
  453. package/plugins/workflow-runner/test/yamlGuardConditions.test.ts +0 -207
  454. package/src/advisorState.js +0 -22
  455. package/src/cli/configWizard.js +0 -293
  456. package/src/tools/toolProgressBridge.js +0 -48
  457. package/workflows/adaptive-research.yaml +0 -50
  458. package/workflows/book-review-short.yaml +0 -125
  459. package/workflows/e2e-write-greet.yaml +0 -31
  460. package/workflows/illustrate.yaml +0 -227
  461. package/workflows/plan.yaml +0 -470
  462. package/workflows/ppt.yaml +0 -1670
  463. package/workflows/ralph-loop.yaml +0 -201
  464. package/workflows/research.yaml +0 -873
  465. package/workflows/schema.json +0 -176
  466. package/workflows/webppt.yaml +0 -496
  467. package/workflows/wechat-reading-shots.yaml +0 -315
  468. package/workflows/word.yaml +0 -720
  469. package/workflows/youtube-shorts.yaml +0 -202
  470. /package/workflows/{research.md → research/DESIGN.md} +0 -0
@@ -1,167 +0,0 @@
1
- /**
2
- * ============================================================
3
- * plugins/workflow-runner/test/cli.e2e.test.ts
4
- * ------------------------------------------------------------
5
- * 最外层 CLI 端到端:拉子进程跑 `bun src/main.tsx -p "/workflow ..."`,
6
- * 验证 stdout / stderr / 退出码 / 文件副作用 全链路。
7
- *
8
- * 覆盖 3 个用例:
9
- * 1. golden path:/workflow cli-e2e --input topic=world → exit 0 + 文件落盘
10
- * 2. /workflows 列出 cli-e2e
11
- * 3. 缺必填 input → exit 1 + 错误信息含 "topic"
12
- *
13
- * fake provider env:workflow 是 tool-only,永不调 API;fake env 仅满足
14
- * main.tsx 的 provider 配置校验。
15
- * ============================================================
16
- */
17
-
18
- import { afterEach, beforeEach, describe, expect, it } from 'bun:test';
19
- import {
20
- copyFileSync,
21
- existsSync,
22
- mkdirSync,
23
- mkdtempSync,
24
- readFileSync,
25
- rmSync,
26
- } from 'node:fs';
27
- import { tmpdir } from 'node:os';
28
- import { join, resolve } from 'node:path';
29
-
30
- const REPO_ROOT = resolve(import.meta.dir, '..', '..', '..');
31
- const FIXTURE = join(import.meta.dir, 'fixtures', 'cli-e2e.yaml');
32
- const FIXTURE_ASK = join(import.meta.dir, 'fixtures', 'cli-ask-e2e.yaml');
33
- const FIXTURE_GREEDY = join(import.meta.dir, 'fixtures', 'greedy-e2e.yaml');
34
-
35
- const SPAWN_TIMEOUT = 60_000;
36
-
37
- interface SpawnResult {
38
- exitCode: number;
39
- stdout: string;
40
- stderr: string;
41
- }
42
-
43
- async function spawnMain(promptArg: string, cwd: string): Promise<SpawnResult> {
44
- const proc = Bun.spawn(
45
- ['bun', 'src/main.tsx', '-d', cwd, '-p', promptArg],
46
- {
47
- cwd: REPO_ROOT,
48
- env: {
49
- ...process.env,
50
- MINIMAL_AGENT_BASE_URL: 'http://fake.invalid',
51
- MINIMAL_AGENT_API_KEY: 'fake-key',
52
- MINIMAL_AGENT_MODEL: 'fake-model',
53
- MINIMAL_AGENT_CONTEXT_WINDOW: '128000',
54
- },
55
- stdout: 'pipe',
56
- stderr: 'pipe',
57
- },
58
- );
59
-
60
- const [stdout, stderr, exitCode] = await Promise.all([
61
- new Response(proc.stdout).text(),
62
- new Response(proc.stderr).text(),
63
- proc.exited,
64
- ]);
65
-
66
- return { exitCode, stdout, stderr };
67
- }
68
-
69
- describe('CLI 端到端 /workflow(拉子进程跑 main.tsx)', () => {
70
- let tmp: string;
71
-
72
- beforeEach(() => {
73
- tmp = mkdtempSync(join(tmpdir(), 'cli-e2e-'));
74
- mkdirSync(join(tmp, 'workflows'), { recursive: true });
75
- copyFileSync(FIXTURE, join(tmp, 'workflows', 'cli-e2e.yaml'));
76
- copyFileSync(FIXTURE_ASK, join(tmp, 'workflows', 'cli-ask-e2e.yaml'));
77
- copyFileSync(FIXTURE_GREEDY, join(tmp, 'workflows', 'greedy-e2e.yaml'));
78
- });
79
-
80
- afterEach(() => {
81
- rmSync(tmp, { recursive: true, force: true });
82
- });
83
-
84
- it(
85
- 'golden path:跑完 + 文件落盘 + exit 0',
86
- async () => {
87
- const r = await spawnMain(
88
- '/workflow cli-e2e --input topic=world',
89
- tmp,
90
- );
91
- expect(r.exitCode).toBe(0);
92
- const filePath = join(tmp, 'out', 'world', 'note.txt');
93
- expect(existsSync(filePath)).toBe(true);
94
- expect(readFileSync(filePath, 'utf8')).toBe('topic=world ok');
95
- },
96
- SPAWN_TIMEOUT,
97
- );
98
-
99
- it(
100
- '/workflows 列出 cli-e2e',
101
- async () => {
102
- const r = await spawnMain('/workflows', tmp);
103
- expect(r.exitCode).toBe(0);
104
- expect(r.stdout).toContain('cli-e2e');
105
- },
106
- SPAWN_TIMEOUT,
107
- );
108
-
109
- it(
110
- '缺必填 input → exit 1 + 错误信息含 "topic"',
111
- async () => {
112
- const r = await spawnMain('/workflow cli-e2e', tmp);
113
- expect(r.exitCode).toBe(1);
114
- expect(r.stderr).toContain('topic');
115
- },
116
- SPAWN_TIMEOUT,
117
- );
118
-
119
- // -p 非交互下「含 AskUserQuestion 的工作流」也能跑通:askBridge 自动选推荐项、不挂起。
120
- // 这是 ppt 工作流 stage0「样式推荐」在 -p / 宿主 spawn 下自动兜底那条路径的最小复现。
121
- it(
122
- '含 AskUserQuestion 的工作流在 -p 下自动选推荐项、不挂起、跑完 exit 0',
123
- async () => {
124
- const r = await spawnMain('/workflow cli-ask-e2e', tmp);
125
- expect(r.exitCode).toBe(0);
126
- // askBridge 非交互兜底:自动选每题首项(推荐项),stderr 注记
127
- expect(r.stderr).toContain('自动选推荐项');
128
- // echo 文本经 text 事件 + 末尾 turn_done 正常回到 -p stdout
129
- expect(r.stdout).toContain('ASK-E2E-DONE');
130
- },
131
- SPAWN_TIMEOUT,
132
- );
133
-
134
- // 贪婪首参:命令行里 workflow 名之后的整句(含空格分隔段)被 join 进首个 input,
135
- // 不逐位拆映射、不撞后面的 number/enum 输入。这是 ppt「打一句话自然语言就能跑」
136
- // 的根因修复——曾因严格 posN↔inputs[N] 把整句拆碎、pos2 撞 number 报「必须是数字」。
137
- it(
138
- 'greedy 首参把整句位置参数 join 进首个 input(不拆碎、不撞类型)',
139
- async () => {
140
- const r = await spawnMain('/workflow greedy-e2e 收集 资料 浅色', tmp);
141
- expect(r.exitCode).toBe(0);
142
- // 三段位置参数被空格 join 还原成整句进 brief,echo 原样回显
143
- expect(r.stdout).toContain('GREEDY-BRIEF=[收集 资料 浅色]');
144
- },
145
- SPAWN_TIMEOUT,
146
- );
147
-
148
- // B7:用户 shell 习惯写 --input brief=A B C(没加引号),shell 拆成 --input brief=A + B + C
149
- // 三个 token;引擎识别为首参已由 --input 提供、但仍存在散落位置参数,按贪婪语义自动拼回,
150
- // 不丢 B、C(之前 B/C 被当占位参数映射给后续非贪婪 input,或直接静默丢弃)。
151
- it(
152
- 'B7:贪婪首参用 --input 提供但没加引号被拆 → 位置参数自动拼回首参',
153
- async () => {
154
- // 注意:命令字符串本身在这里是单条 input,但引擎 tokenize 后是:
155
- // [/workflow, greedy-e2e, --input, brief=做, 一个, 小玩具]
156
- // 即 greedy-e2e 之后的内容中,--input brief=做 是首参赋值,「一个」「小玩具」
157
- // 是被 shell-like 拆分出来的位置参数,B7 修复后必须自动拼回为「做 一个 小玩具」。
158
- const r = await spawnMain('/workflow greedy-e2e --input brief=做 一个 小玩具', tmp);
159
- expect(r.exitCode).toBe(0);
160
- expect(r.stdout).toContain('GREEDY-BRIEF=[做 一个 小玩具]');
161
- // 修复附带的用户提示:告诉用户下次记得加引号(-p 模式 warning 走 stderr 或 stdout 都算)
162
- const combined = r.stdout + '\n' + r.stderr;
163
- expect(combined).toContain('已自动拼回');
164
- },
165
- SPAWN_TIMEOUT,
166
- );
167
- });
@@ -1,320 +0,0 @@
1
- /**
2
- * ============================================================
3
- * test/context-files.test.ts —— ADR-05 阶段 4 miniReAct 验证
4
- * ------------------------------------------------------------
5
- * 覆盖 execLlmStep + miniReAct 子循环(context_files 路径):
6
- * case 1: 基本 Read 引用 — 第一轮 tool_call,第二轮纯文本收敛
7
- * case 2: maxTurns 上限 — 永不收敛 → 抛错
8
- * case 3: output_schema + tools 组合 — 走 [json+tools] 前缀
9
- *
10
- * 策略:
11
- * - mock '../../../src/llm/client.js' → 按调用次数依次返回不同流
12
- * - mock '../../../src/tools/index.js' → executeTool 返回固定内容;
13
- * 同时透传 ALL_TOOLS / getToolByName(llm.ts 还要靠 ALL_TOOLS 过滤白名单)
14
- * - 不真跑 Read,避免文件系统耦合
15
- * ============================================================
16
- */
17
-
18
- import {
19
- afterAll,
20
- beforeAll,
21
- beforeEach,
22
- describe,
23
- expect,
24
- it,
25
- mock,
26
- } from 'bun:test';
27
-
28
- import type { Provider, Tool } from '../../../src/types.js';
29
- import { execLlmStep } from '../src/stepExecutors/llm.js';
30
- import { VarStack } from '../src/types.js';
31
- import type { RunContext, StepDef } from '../src/types.js';
32
-
33
- const fakeProvider: Provider = {
34
- name: 'test',
35
- baseURL: '',
36
- apiKey: '',
37
- model: 'm',
38
- contextWindow: 128000,
39
- };
40
-
41
- /** execLlmStep 现为 AsyncGenerator:drain 取最终 return 值(yield 的事件直接丢弃)。 */
42
- async function drainLlm<R>(gen: AsyncGenerator<unknown, R, void>): Promise<R> {
43
- let r = await gen.next();
44
- while (!r.done) r = await gen.next();
45
- return r.value;
46
- }
47
-
48
- // ---------------- mock 基础设施 ----------------
49
-
50
- interface ChatCallRecord {
51
- messages: unknown[];
52
- tools: unknown[];
53
- responseFormat?: unknown;
54
- }
55
-
56
- /** 每次 chat() 调用记录的参数 */
57
- const capturedChatArgs: ChatCallRecord[] = [];
58
- /** mock 流脚本:每轮一个;用尽后报错(避免无限循环) */
59
- type MockTurn =
60
- | { kind: 'text'; text: string }
61
- | {
62
- kind: 'tool_call';
63
- callId: string;
64
- name: string;
65
- argsJson: string;
66
- /** 该轮 assistant 同时附带的可选文本 */
67
- text?: string;
68
- };
69
- let mockTurns: MockTurn[] = [];
70
- let mockTurnIdx = 0;
71
-
72
- interface ExecuteToolCall {
73
- name: string;
74
- rawArguments: string;
75
- }
76
- const capturedExecuteToolCalls: ExecuteToolCall[] = [];
77
- /** mock executeTool 返回值脚本(按调用顺序);用尽则回退到 { ok:true, content:'OK' } */
78
- let mockToolResults: Array<
79
- { ok: true; content: string } | { ok: false; error: string }
80
- > = [];
81
-
82
- import { chat as realChatImport } from '../../../src/llm/client.js';
83
- // 复用真实的 ALL_TOOLS / getToolByName(llm.ts 的白名单过滤要用),
84
- // 只把 executeTool 替换成 mock 版本。
85
- //
86
- // 注:bun 的 mock.module 是 process-global 且无内建 restore。即便其它文件的
87
- // 测试 case 没被本文件触发,只要 top-level 执行了 mock.module,整个进程的
88
- // 模块解析就被替换了。所以放在 beforeAll/afterAll 内成对挂钩,确保最小作用域。
89
- import {
90
- ALL_TOOLS as REAL_ALL_TOOLS,
91
- executeTool as realExecuteTool,
92
- getToolByName as realGetToolByName,
93
- } from '../../../src/tools/index.js';
94
-
95
- // 在 mock 安装前把真实 chat 函数引用拷到值变量,避免 ESM live binding
96
- // 在 mock.module 后跟着变成 mock 版本(afterAll 复原才能拿到真函数)
97
- const ORIGINAL_CHAT = realChatImport;
98
- const ORIGINAL_EXECUTE_TOOL = realExecuteTool;
99
-
100
- beforeAll(() => {
101
- installChatMock();
102
- mock.module('../../../src/tools/index.js', () => ({
103
- ALL_TOOLS: REAL_ALL_TOOLS,
104
- getToolByName: realGetToolByName,
105
- executeTool: async (name: string, rawArguments: string) => {
106
- capturedExecuteToolCalls.push({ name, rawArguments });
107
- const next = mockToolResults.shift();
108
- return next ?? { ok: true, content: 'OK' };
109
- },
110
- }));
111
- });
112
-
113
- afterAll(() => {
114
- // 复原 chat 为真实实现,避免污染下游 e2e / runner 等不 mock chat 的测试文件
115
- // 必须用 ORIGINAL_CHAT(mock 前抓到的值快照),不能用 realChatImport(已被 mock 替换的 live binding)
116
- mock.module('../../../src/llm/client.js', () => ({ chat: ORIGINAL_CHAT }));
117
- // 复原 executeTool 为真实实现
118
- mock.module('../../../src/tools/index.js', () => ({
119
- ALL_TOOLS: REAL_ALL_TOOLS,
120
- getToolByName: realGetToolByName,
121
- executeTool: ORIGINAL_EXECUTE_TOOL,
122
- }));
123
- });
124
-
125
- // chat mock 也放进 beforeAll,避免 top-level 副作用污染其它文件
126
- function installChatMock(): void {
127
- mock.module('../../../src/llm/client.js', () => ({
128
- chat: async function* (args: ChatCallRecord) {
129
- capturedChatArgs.push({
130
- messages: args.messages,
131
- tools: args.tools,
132
- responseFormat: args.responseFormat,
133
- });
134
- const turn = mockTurns[mockTurnIdx];
135
- mockTurnIdx++;
136
- if (!turn) {
137
- throw new Error(
138
- `mock chat: 用尽脚本(共 ${mockTurns.length} 轮,调用第 ${mockTurnIdx} 次)`,
139
- );
140
- }
141
- if (turn.kind === 'text') {
142
- yield { type: 'text_delta', delta: turn.text };
143
- } else {
144
- if (turn.text) yield { type: 'text_delta', delta: turn.text };
145
- yield {
146
- type: 'tool_call_delta',
147
- index: 0,
148
- id: turn.callId,
149
- name: turn.name,
150
- argumentsDelta: turn.argsJson,
151
- };
152
- }
153
- yield {
154
- type: 'done',
155
- stopReason: turn.kind === 'tool_call' ? 'tool_calls' : 'stop',
156
- };
157
- },
158
- }));
159
- }
160
-
161
- // ---------------- 测试 ----------------
162
-
163
- describe('workflow-runner context_files (ADR-05 阶段 4)', () => {
164
- let ctx: RunContext;
165
-
166
- beforeEach(() => {
167
- capturedChatArgs.length = 0;
168
- capturedExecuteToolCalls.length = 0;
169
- mockTurns = [];
170
- mockTurnIdx = 0;
171
- mockToolResults = [];
172
- ctx = {
173
- provider: fakeProvider,
174
- history: [],
175
- cwd: process.cwd(),
176
- tools: [],
177
- };
178
- });
179
-
180
- it('pure llm 不下发工具,避免单轮设计类步骤误调工具后撞 maxTurns=1', async () => {
181
- mockTurns = [{ kind: 'text', text: 'design doc' }];
182
-
183
- const step: StepDef = {
184
- id: 'pure-design',
185
- llm: 'please design',
186
- };
187
-
188
- const result = await drainLlm(execLlmStep(step, new VarStack(), ctx));
189
-
190
- expect(result.raw).toEqual({ text: 'design doc', result: 'design doc' });
191
- expect(capturedChatArgs.length).toBe(1);
192
- expect(capturedChatArgs[0].tools).toEqual([]);
193
- });
194
-
195
- it('case 1: 基本 Read 引用 — tool_call 一轮 + 纯文本一轮', async () => {
196
- ctx.tools = [{ name: 'Read' } as Tool];
197
- mockTurns = [
198
- {
199
- kind: 'tool_call',
200
- callId: 'call_1',
201
- name: 'Read',
202
- argsJson: '{"file_path":"/tmp/x.txt"}',
203
- },
204
- { kind: 'text', text: 'got it' },
205
- ];
206
- mockToolResults = [{ ok: true, content: 'file content here' }];
207
-
208
- const step: StepDef = {
209
- id: 'read-and-answer',
210
- llm: 'please summarize',
211
- context_files: [{ path: '/tmp/x.txt', hint: 'source data' }],
212
- // context_files 经 runQuery(TAOR) 执行;步骤白名单与宿主有效工具集取交集。
213
- allowed_tools: ['Read'],
214
- };
215
-
216
- const result = await drainLlm(execLlmStep(step, new VarStack(), ctx));
217
-
218
- // 返回值断言
219
- expect(result.raw).toEqual({ text: 'got it', result: 'got it' });
220
- expect(result.preview).toBe('got it');
221
-
222
- // chat 被调了 2 次
223
- expect(capturedChatArgs.length).toBe(2);
224
- // executeTool 被调了 1 次,参数透传正确
225
- expect(capturedExecuteToolCalls.length).toBe(1);
226
- expect(capturedExecuteToolCalls[0].name).toBe('Read');
227
- const parsedArgs = JSON.parse(capturedExecuteToolCalls[0].rawArguments) as {
228
- file_path: string;
229
- };
230
- expect(parsedArgs.file_path).toBe('/tmp/x.txt');
231
-
232
- // 第一轮 user message 包含路径和 hint
233
- const firstUserMsg = (
234
- capturedChatArgs[0].messages as Array<{ role: string; content: string }>
235
- ).find((m) => m.role === 'user');
236
- expect(firstUserMsg).toBeDefined();
237
- expect(firstUserMsg!.content).toContain('/tmp/x.txt');
238
- expect(firstUserMsg!.content).toContain('source data');
239
-
240
- // tools 数组只含 Read(白名单生效)
241
- const tools0 = capturedChatArgs[0].tools as Array<{ name: string }>;
242
- expect(tools0.length).toBe(1);
243
- expect(tools0[0].name).toBe('Read');
244
- });
245
-
246
- it('case 2: 永不收敛(每轮都调工具)→ 被 maxTurns 严格兜住,不无限循环', async () => {
247
- ctx.tools = [{ name: 'Read' } as Tool];
248
- // v0.9 重构移除了 miniReAct 的"重复工具调用早停",改由主 TAOR 引擎(runQuery)的
249
- // maxTurns 硬上限兜底。本用例验证安全属性:模型每轮都调工具、永不收敛时,chat 调用
250
- // 次数被 maxTurns 严格限制(不会无限循环),不再依赖已移除的重复检测。
251
- mockTurns = [
252
- {
253
- kind: 'tool_call',
254
- callId: 'c1',
255
- name: 'Read',
256
- argsJson: '{"file_path":"/a"}',
257
- },
258
- {
259
- kind: 'tool_call',
260
- callId: 'c2',
261
- name: 'Read',
262
- argsJson: '{"file_path":"/a"}',
263
- },
264
- ];
265
- mockToolResults = [
266
- { ok: true, content: 'A' },
267
- { ok: true, content: 'A' },
268
- ];
269
-
270
- const step: StepDef = {
271
- id: 'never-converge',
272
- llm: 'go',
273
- context_files: [{ path: '/a' }],
274
- maxTurns: 2,
275
- };
276
-
277
- // 不无限循环:chat 调用次数被 maxTurns(=2) 严格兜住。
278
- // 撞顶后的半截产出不可信,execLlmStep 必须抛错触发 runner retry/halt。
279
- await expect(
280
- drainLlm(execLlmStep(step, new VarStack(), ctx)),
281
- ).rejects.toThrow('达到最大轮数 2 被截断');
282
- expect(capturedChatArgs.length).toBe(2);
283
- });
284
-
285
- it('case 3: output_schema + tools — 走 [json+tools] 前缀', async () => {
286
- ctx.tools = [{ name: 'Read' } as Tool];
287
- mockTurns = [
288
- {
289
- kind: 'tool_call',
290
- callId: 'call_1',
291
- name: 'Read',
292
- argsJson: '{"file_path":"/tmp/y.txt"}',
293
- },
294
- { kind: 'text', text: '{"findings":["a","b"]}' },
295
- ];
296
- mockToolResults = [{ ok: true, content: 'raw content' }];
297
-
298
- const step: StepDef = {
299
- id: 'structured-with-tools',
300
- llm: 'find',
301
- context_files: [{ path: '/tmp/y.txt' }],
302
- output_schema: {
303
- type: 'object',
304
- properties: { findings: { type: 'array', items: { type: 'string' } } },
305
- required: ['findings'],
306
- },
307
- };
308
-
309
- const result = await drainLlm(execLlmStep(step, new VarStack(), ctx));
310
-
311
- // raw 是 parsed JSON
312
- expect(result.raw).toEqual({ findings: ['a', 'b'] });
313
- // v0.9:output_schema 走 prompt 内嵌 + extractJsonPayload 解析,preview 统一 [json] 前缀
314
- // (不再有独立的 [json+tools] 路径,也不再走 provider-native responseFormat)。
315
- expect(result.preview.startsWith('[json] ')).toBe(true);
316
-
317
- // chat 被调两轮(读文件一轮 + 出 JSON 一轮)
318
- expect(capturedChatArgs.length).toBe(2);
319
- });
320
- });