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,168 +0,0 @@
1
- import { describe, expect, test } from 'bun:test';
2
-
3
- import {
4
- ALL_TOOLS,
5
- type LoopEvent,
6
- type Provider,
7
- type ToolCallContext,
8
- type ToolResult,
9
- createAgentRuntimeContext,
10
- createSessionState,
11
- } from '../../../src/plugin-sdk.js';
12
- import { execToolStep } from '../src/stepExecutors/tool.js';
13
- import { type RunContext, type StepResult, VarStack } from '../src/types.js';
14
-
15
- const provider: Provider = {
16
- name: 'workflow-tool-test',
17
- baseURL: '',
18
- apiKey: '',
19
- model: 'fixture',
20
- contextWindow: 128_000,
21
- };
22
-
23
- async function collect(
24
- generator: AsyncGenerator<LoopEvent, StepResult, void>,
25
- ): Promise<{ events: LoopEvent[]; result: StepResult }> {
26
- const events: LoopEvent[] = [];
27
- while (true) {
28
- const next = await generator.next();
29
- if (next.done) return { events, result: next.value };
30
- events.push(next.value);
31
- }
32
- }
33
-
34
- function makeContext(
35
- executeTool: NonNullable<RunContext['executeTool']>,
36
- ): RunContext {
37
- const sessionState = createSessionState();
38
- sessionState.activeWorktree = {
39
- id: 'wt_test',
40
- path: '/tmp/workflow-active-worktree',
41
- branch: 'workflow/test',
42
- baseSha: 'deadbeef',
43
- gitRoot: '/tmp/workflow-root',
44
- };
45
- return {
46
- provider,
47
- history: [],
48
- cwd: '/tmp/workflow-root',
49
- tools: ALL_TOOLS,
50
- sessionState,
51
- runtimeContext: createAgentRuntimeContext({
52
- surface: 'workflow',
53
- profile: 'main',
54
- cwd: '/tmp/workflow-root',
55
- workspaceId: 'workspace_test',
56
- sessionId: 'session_test',
57
- owner: 'local-owner',
58
- memoryAccess: 'read-only',
59
- interactiveAsk: false,
60
- }),
61
- promptCache: {
62
- scopeKey: 'workflow-test-scope',
63
- conversationKey: 'workflow-test-conversation',
64
- },
65
- executeTool,
66
- };
67
- }
68
-
69
- describe('workflow deterministic tool runtime', () => {
70
- test('all registered tools use the same generic deterministic node dispatcher', async () => {
71
- const dispatched: string[] = [];
72
- const ctx = makeContext(async (name) => {
73
- dispatched.push(name);
74
- return { ok: true, content: `${name} ok` };
75
- });
76
-
77
- for (const tool of ALL_TOOLS) {
78
- const { result } = await collect(
79
- execToolStep(
80
- { id: `catalog_${tool.name}`, tool: tool.name, args: {} },
81
- new VarStack(),
82
- ctx,
83
- ),
84
- );
85
- expect(result.raw).toMatchObject({ content: `${tool.name} ok` });
86
- }
87
-
88
- expect(dispatched).toEqual(ALL_TOOLS.map((tool) => tool.name));
89
- expect(new Set(dispatched).size).toBe(ALL_TOOLS.length);
90
- });
91
-
92
- test('passes canonical runtime context and follows the active worktree cwd', async () => {
93
- let captured: ToolCallContext | undefined;
94
- const ctx = makeContext(async (_name, _args, _signal, context) => {
95
- captured = context;
96
- return { ok: true, content: 'ok' };
97
- });
98
-
99
- await collect(
100
- execToolStep(
101
- { id: 'context', tool: 'Read', args: { file_path: 'README.md' } },
102
- new VarStack(),
103
- ctx,
104
- ),
105
- );
106
-
107
- expect(captured).toBeDefined();
108
- expect(captured?.provider).toBe(provider);
109
- expect(captured?.history).toBe(ctx.history);
110
- expect(captured?.sessionState).toBe(ctx.sessionState);
111
- expect(captured?.workspaceId).toBe('workspace_test');
112
- expect(captured?.sessionId).toBe('session_test');
113
- expect(captured?.memoryAccess).toBe('read-only');
114
- expect(captured?.cwd).toBe('/tmp/workflow-active-worktree');
115
- expect(captured?.toolCallId).toBe('wf_context');
116
- expect(captured?.promptCache).toBe(ctx.promptCache);
117
- });
118
-
119
- test('streams tool progress and preserves structured result fields', async () => {
120
- const metadata = {
121
- kind: 'process_execution' as const,
122
- shell: 'bash' as const,
123
- mode: 'foreground' as const,
124
- commandKind: 'test' as const,
125
- status: 'completed' as const,
126
- exitCode: 0,
127
- };
128
- const ctx = makeContext(async (_name, _args, _signal, context) => {
129
- context?.reportProgress?.('running tests');
130
- await Promise.resolve();
131
- return {
132
- ok: true,
133
- content: 'tests passed',
134
- metadata,
135
- recovery: 'none',
136
- sensitivity: 'local',
137
- visionNote: 'verification image',
138
- } satisfies ToolResult;
139
- });
140
-
141
- const { events, result } = await collect(
142
- execToolStep(
143
- { id: 'progress', tool: 'Bash', args: { command: 'bun test' } },
144
- new VarStack(),
145
- ctx,
146
- ),
147
- );
148
-
149
- expect(events.map((event) => event.type)).toEqual([
150
- 'tool_start',
151
- 'tool_progress',
152
- 'tool_end',
153
- ]);
154
- expect(events[1]).toMatchObject({
155
- type: 'tool_progress',
156
- toolName: 'Bash',
157
- toolCallId: 'wf_progress',
158
- message: 'running tests',
159
- });
160
- expect(events[2]).toMatchObject({ type: 'tool_end', metadata });
161
- expect(result.raw).toMatchObject({
162
- metadata,
163
- recovery: 'none',
164
- sensitivity: 'local',
165
- visionNote: 'verification image',
166
- });
167
- });
168
- });
@@ -1,250 +0,0 @@
1
- /**
2
- * test/webppt.load.test.ts
3
- * ------------------------------------------------------------
4
- * 锁定 workflows/webppt.yaml(网页设计驱动版)的「可解析 + 关键骨架」:
5
- * - loader 校验通过(含 type:loop while 模式 + do[] + break 嵌套)
6
- * - 11 个顶层步、title 分母 /11、inputs 含 topic(greedy)/style/mode/illustrations/out
7
- * - 新流程三段:设计文档(design.json/md+img_plan) → 对抗评审 → 分批生成 loop(deck_pages_check 收口)
8
- * - 复用段衔接正确:img_route_gate 吃 design.json、生图先于闸门、export 只查重叠+每页≤3次+页数兜底
9
- * - 所有 ${} 表达式可被引擎解析(防 bash 参数扩展等畸形语法)
10
- *
11
- * 定位法:packageRoot/workflows/webppt.yaml + parseWorkflowFile。
12
- * 注意:webppt(topic 驱动)与 ppt(文档素材驱动,见 ppt.load.test.ts)是**两个并列的独立工作流**,
13
- * 内部 name 分别为 webppt / ppt,互不影响——改 ppt 时绝不动 webppt(用户红线)。
14
- */
15
-
16
- import { describe, expect, it } from 'bun:test';
17
- import { join } from 'node:path';
18
-
19
- import { interpolate } from '../src/expressions.js';
20
- import { parseWorkflowFile } from '../src/loader.js';
21
- import { VarStack } from '../src/types.js';
22
- import type { StepDef } from '../src/types.js';
23
-
24
- const webpptPath = join(
25
- import.meta.dir.replace(/[/\\]test$/, ''), // plugins/workflow-runner
26
- '..', // plugins
27
- '..', // 仓库根
28
- 'workflows',
29
- 'webppt.yaml',
30
- );
31
-
32
- describe('workflows/webppt.yaml', () => {
33
- it('解析通过且 11 步骨架正确', async () => {
34
- const def = await parseWorkflowFile(webpptPath);
35
-
36
- expect(def.name).toBe('webppt');
37
- expect(typeof def.description).toBe('string');
38
-
39
- // inputs:topic(greedy, 首位) + 高级覆盖项
40
- const inputNames = (def.inputs ?? []).map((i) => i.name);
41
- expect(inputNames).toEqual(
42
- expect.arrayContaining(['topic', 'illustrations', 'style', 'mode', 'out', 'image_intensity']),
43
- );
44
- expect(inputNames[0]).toBe('topic');
45
- // AI 生图积极性配置(2026-06-19):enum minimal/balanced/rich,默认 balanced
46
- const intensity = (def.inputs ?? []).find((i) => i.name === 'image_intensity');
47
- expect(intensity?.default).toBe('balanced');
48
- expect((def.inputs ?? []).find((i) => i.name === 'topic')?.greedy).toBe(true);
49
- expect(inputNames).not.toContain('pages'); // 页数内容驱动,不是输入
50
-
51
- // 11 个顶层步 + title 分母 /11
52
- const ids = def.steps.map((s) => s.id);
53
- for (const id of [
54
- 'stage0_clarify',
55
- 'stage_research',
56
- 'stage_design_doc',
57
- 'stage_design_review',
58
- 'stage_build_loop',
59
- 'stage_img_route_gate',
60
- 'stage_gen_images',
61
- 'stage_export',
62
- 'verify_output',
63
- 'cleanup_intermediates',
64
- 'final_report',
65
- ]) {
66
- expect(ids).toContain(id);
67
- }
68
- expect(def.steps.length).toBe(11);
69
- for (const s of def.steps) {
70
- expect(String(s.title)).toContain('/11');
71
- }
72
-
73
- // 收尾报告 echo;artifacts 只列最终交付物、不在被 rm 的 out/webppt/${session}/build 下
74
- expect(def.steps.find((s) => s.id === 'final_report')?.type).toBe('echo');
75
- const declared = def.artifacts ?? [];
76
- expect(declared).toContain('out/webppt/${session}/deck.pptx');
77
- for (const a of declared) expect(a.startsWith('out/webppt/${session}/build')).toBe(false);
78
- });
79
-
80
- it('需求分析步:style 为空时必问视觉样式(VI 选项 + 自定义输入),AskUserQuestion 可用', async () => {
81
- const def = await parseWorkflowFile(webpptPath);
82
- const s0 = def.steps.find((s) => s.id === 'stage0_clarify');
83
- expect(s0?.allowed_tools).toContain('AskUserQuestion');
84
- const a = String(s0?.agent);
85
- // 样式问是「必做」的强约束(防回归:弱模型曾跳过样式题直接进下一步)。
86
- expect(a).toContain('必须调用一次 AskUserQuestion');
87
- expect(a).toContain('style 为空');
88
- expect(a).toContain('替用户拍板样式');
89
- // 仍提供几个最贴合主题的 VI 选项 + 自定义输入。
90
- expect(a).toContain('最贴合本主题');
91
- expect(a).toContain('自定义');
92
- });
93
-
94
- it('设计文档步:产 design.md/json + img_plan,含构图法/渲染决策/呼应提示词/背景变化', async () => {
95
- const def = await parseWorkflowFile(webpptPath);
96
- const dd = def.steps.find((s) => s.id === 'stage_design_doc');
97
- expect(typeof dd?.agent).toBe('string');
98
- const a = String(dd?.agent);
99
- expect(a).toContain('design.md');
100
- expect(a).toContain('design.json');
101
- expect(a).toContain('img_plan.json');
102
- expect(a).toContain('composition'); // 空间构图法
103
- expect(a).toContain('render'); // 元素级渲染决策
104
- expect(a).toContain('呼应'); // 生图提示词与文案呼应(治"搬文案")
105
- expect(a).toContain('背景'); // 页面级背景变化
106
- expect(a).toContain('每页 ≥1 视觉元素'); // 区别于 Word
107
- // 配色解耦(用户裁决):VI 管底,图表分类色 + 插图内容色
108
- expect(a).toContain('配色解耦');
109
- expect(a).toContain('分类色');
110
- // 保留 visual.{route,note} 字段名 → 下游 image_plan_lint 兼容
111
- expect(a).toContain('visual');
112
- expect(a).toContain('route');
113
- // AI 生图积极性配置接入设计步(2026-06-19)
114
- expect(a).toContain('${inputs.image_intensity}'); // 积极性配置驱动配图分流
115
- expect(a).toContain('积极性');
116
- // design.json 紧凑单行(治 doubao 推理模型写大 JSON 尾部截断 Unterminated string)
117
- expect(a).toContain('紧凑单行');
118
- expect(String(dd?.done_when)).toContain('design.json');
119
- // 编辑式最高标准(第三轮·webppt 也转编辑式,用户授权覆盖红线):强制默认 + 每页背景层 + cards 罕见例外
120
- expect(a).toContain('编辑式最高标准·强制默认');
121
- expect(a).toContain('每个内容页都必须有背景层');
122
- expect(a).toContain('卡片墙 / 网格 / 表格 = 罕见例外');
123
- expect(a).toContain('`cards` 已降为罕见例外、默认别选');
124
- // 第五轮:AI 背景默认(渐变只作失败兜底)+ 动笔前三问/苹果式精炼
125
- expect(a).toContain('默认高清 AI 图,渐变只作失败兜底');
126
- expect(a).toContain('优先配高清 AI 全幅底图');
127
- expect(a).toContain('动笔前三问');
128
- expect(a).toContain('MacBook Pro');
129
- });
130
-
131
- it('对抗评审步:回顾原始需求挑刺并修订定稿(全自动、无人工 pause)', async () => {
132
- const def = await parseWorkflowFile(webpptPath);
133
- const rv = def.steps.find((s) => s.id === 'stage_design_review');
134
- expect(typeof rv?.agent).toBe('string');
135
- const a = String(rv?.agent);
136
- expect(a).toContain('对抗');
137
- expect(a).toContain('原始需求');
138
- expect(a).toContain('修订');
139
- // 稀疏页标准(用户裁决):不再一律禁「一句话占一页」,而是 ≤20% 且必须配图/底图避免简陋。
140
- expect(a).toContain('20%');
141
- expect(a).toContain('简陋');
142
- // 配色解耦 + 字号可读性评审子项(用户裁决)
143
- expect(a).toContain('分类色'); // 图表数据系列可区分
144
- expect(a).toContain('38px'); // 正文放映级可读(≈1.5×)
145
- // 新增评审子项(2026-06-19):封面对比 / 真实 DOM 文本 / 稀疏页满画布
146
- expect(a).toContain('对比度'); // 封面/章节文字在浅底图上对比达标
147
- expect(a).toContain('DOM 文本'); // 文字皆真实 DOM 文本(无伪元素/烧图文字)
148
- expect(a).toContain('占满画布'); // list/目录满宽不留空半
149
- // 改 design 文档(Edit/Write),不是只读评审
150
- expect(rv?.allowed_tools).toContain('Edit');
151
- // 不是 pause(webppt 定位=自动产出,无人工打断)
152
- expect(rv?.type).not.toBe('pause');
153
- });
154
-
155
- it('分批生成 loop:while + fresh_context + deck_pages_check 收口(防大 deck 烂尾)', async () => {
156
- const def = await parseWorkflowFile(webpptPath);
157
- const loop = def.steps.find((s) => s.id === 'stage_build_loop');
158
- expect(loop?.type).toBe('loop');
159
- expect(loop?.fresh_context).toBe(true); // 每轮重置 history 防膨胀
160
- expect(loop?.over).toBeUndefined(); // while 模式(非 for-each)
161
- expect(typeof loop?.max_iterations === 'number' || typeof loop?.max_iterations === 'string').toBe(true);
162
- const dos = (loop?.do ?? []) as StepDef[];
163
- const batch = dos.find((s) => s.id === 'build_batch');
164
- const brk = dos.find((s) => s.id === 'build_done');
165
- // 生成步:跑 deck_pages_check 自查 + ≤5 页 + 每页视觉元素 + COMPLETE 标记
166
- expect(typeof batch?.agent).toBe('string');
167
- expect(String(batch?.agent)).toContain('deck_pages_check.py');
168
- expect(String(batch?.agent)).toContain('WEBPPT_BUILD_COMPLETE');
169
- expect(String(batch?.agent)).toContain('5 页'); // 每轮最多 5 页
170
- // 字号阶梯(放映级正文 ≈1.5×)+ 配色解耦(图表分类色)注入生成步
171
- expect(String(batch?.agent)).toContain('38px'); // 正文/卡片正文放映级下限(≈1.5×)
172
- expect(String(batch?.agent)).toContain('分类色'); // 图表数据系列分类色
173
- // 文本必须真实 DOM(禁伪元素/烧图)+ 封面对比 + 稀疏页满画布(2026-06-19)
174
- expect(String(batch?.agent)).toContain('真实 DOM 文本'); // 禁 ::before/::after / 禁烧进图
175
- expect(String(batch?.agent)).toContain('::before/::after'); // 明示禁用伪元素文字
176
- expect(String(batch?.agent)).toContain('对比度铁律'); // 封面浅底图深字+浅板
177
- expect(String(batch?.agent)).toContain('占满整宽'); // list/目录满宽不留空半
178
- // 递归切图:可拖结构离散 HTML + 卡片填实/不溢出(2026-06-19)
179
- expect(String(batch?.agent)).toContain('可拖结构'); // 离散 HTML 元素、递归切成各自可拖对象
180
- expect(String(batch?.agent)).toContain('递归切'); // 导出递归切
181
- expect(String(batch?.agent)).toContain('卡片/分组填充不足'); // 填实/不溢出 WARNING 提示
182
- // 对比度铁律 + 文案精炼说人话 + 排不下自救(2026-06-19 第三轮)
183
- expect(String(batch?.agent)).toContain('文字对比度铁律'); // 深底白字、绝不深底深字
184
- expect(String(batch?.agent)).toContain('说人话'); // 文案精炼·类比/例子
185
- expect(String(batch?.agent)).toContain('两列'); // 排不下改 grid 两列
186
- // deck 纵向流式(人可滚动审阅,不再各页叠在一起)
187
- expect(String(batch?.agent)).toContain('流式'); // 纵向流式版式
188
- expect(String(batch?.agent)).toContain('position:relative'); // 每页 position:relative 排开
189
- expect(batch?.capture).toBeTruthy();
190
- // break:页数 COMPLETE 时跳出循环
191
- expect(brk?.type).toBe('break');
192
- expect(String(brk?.when)).toContain('WEBPPT_BUILD_COMPLETE');
193
- });
194
-
195
- it('衔接:img_route_gate 吃 design.json、生图先于闸门、export 只查重叠+每页≤3次+页数兜底', async () => {
196
- const def = await parseWorkflowFile(webpptPath);
197
- const ids = def.steps.map((s) => s.id);
198
-
199
- // 配图分流闸门:image_plan_lint 的 --outline 直接吃 design.json
200
- const gate = def.steps.find((s) => s.id === 'stage_img_route_gate');
201
- expect(String(gate?.agent)).toContain('image_plan_lint.py');
202
- expect(String(gate?.agent)).toContain('--outline out/webppt/${session}/build/design.json');
203
- expect(String(gate?.done_when)).toContain('img_route_ok');
204
- // 顺序:build_loop → img_route_gate → gen_images
205
- expect(ids.indexOf('stage_img_route_gate')).toBeGreaterThan(ids.indexOf('stage_build_loop'));
206
- expect(ids.indexOf('stage_img_route_gate')).toBeLessThan(ids.indexOf('stage_gen_images'));
207
- // 生图先于构图闸门(闸门量含图成品)——分层/时序不变量
208
- expect(ids.indexOf('stage_gen_images')).toBeLessThan(ids.indexOf('stage_export'));
209
-
210
- // 导出步:页数兜底 + measure-only 渲染含图成品 + 只查重叠 + 修法序(移动>精炼>缩字≤20%) + 每页≤3次配额 + 哨兵
211
- const exp = def.steps.find((s) => s.id === 'stage_export');
212
- expect(String(exp?.agent)).toContain('deck_pages_check.py'); // 页数兜底
213
- expect(String(exp?.agent)).toContain('layout_balance.py');
214
- expect(String(exp?.agent)).toContain('--measure-only'); // 渲染真实 deck 量含图成品
215
- expect(String(exp?.agent)).toContain('重叠'); // 不可妥协硬门之一
216
- expect(String(exp?.agent)).toContain('截图夹带文本'); // 底图/切图绝不能带 HTML 文字(硬门,2026-06-19)
217
- // 改 deck.html 只准用 Edit、禁 Bash 文本替换(治弱模型 type/findstr/PowerShell 把 HTML 改崩→halt,2026-06-19 第三轮)
218
- expect(String(exp?.agent)).toContain('只准用 Edit');
219
- expect(String(exp?.agent)).toContain('编码损坏');
220
- expect(String(exp?.agent)).toContain('移动'); // 修重叠优先移动/重排(不是一味缩字)
221
- expect(String(exp?.agent)).toContain('20%'); // 缩字单次封顶 20%
222
- expect(String(exp?.agent)).toContain('3 次'); // 每页最多修 3 次
223
- expect(String(exp?.agent)).toContain('放行'); // 第 3 次后必放行
224
- expect(String(exp?.done_when)).toContain('layout_ok');
225
- expect(String(exp?.done_when)).toContain('inputs.out');
226
- expect(exp?.maxTurns).toBe(200);
227
- });
228
-
229
- it('所有 ${} 表达式都能被引擎解析(不含畸形语法)', async () => {
230
- const def = await parseWorkflowFile(webpptPath);
231
- const vars = new VarStack();
232
- const inputsObj: Record<string, unknown> = {};
233
- for (const inp of def.inputs ?? []) inputsObj[inp.name] = inp.default ?? '';
234
- vars.setGlobal('inputs', inputsObj);
235
-
236
- const strings: string[] = [];
237
- const walk = (v: unknown): void => {
238
- if (typeof v === 'string') strings.push(v);
239
- else if (Array.isArray(v)) for (const x of v) walk(x);
240
- else if (v && typeof v === 'object')
241
- for (const x of Object.values(v as Record<string, unknown>)) walk(x);
242
- };
243
- walk(def);
244
- expect(strings.length).toBeGreaterThan(10);
245
- for (const s of strings) {
246
- if (!s.includes('${')) continue;
247
- expect(() => interpolate(s, vars)).not.toThrow();
248
- }
249
- });
250
- });
@@ -1,208 +0,0 @@
1
- /**
2
- * test/word.load.test.ts
3
- * ------------------------------------------------------------
4
- * 锁定 workflows/word.yaml(素材驱动知乎深度长文 Word 工作流)的
5
- * 「可解析 + 关键骨架」:
6
- * - name=word,最终产物是 out/word/${session}/article.docx
7
- * - inputs 支持 topic(greedy) / source / out / image_intensity / quality / debug_keep_build
8
- * - Markdown-first:material → outline → article.md → image_map/img_plan → docx skill → OPC
9
- * - 客户图必须使用;需要解释型视觉时积极文生图,提示词必须结合上下文
10
- * - 不引入 PPT 专属 deck.html / design.json / 构图门 / PPTX 导出链路
11
- */
12
-
13
- import { describe, expect, it } from 'bun:test';
14
- import { join } from 'node:path';
15
-
16
- import { parseWorkflowFile } from '../src/loader.js';
17
-
18
- const wordPath = join(
19
- import.meta.dir.replace(/[/\\]test$/, ''), // plugins/workflow-runner
20
- '..', // plugins
21
- '..', // minimal-agent 根
22
- 'workflows',
23
- 'word.yaml',
24
- );
25
-
26
- describe('workflows/word.yaml(素材驱动·知乎深度长文 Word)', () => {
27
- it('解析通过且 name/artifacts/inputs 骨架正确', async () => {
28
- const def = await parseWorkflowFile(wordPath);
29
-
30
- expect(def.name).toBe('word');
31
- expect(typeof def.description).toBe('string');
32
- expect(def.description).toContain('知乎深度文章');
33
-
34
- const declared = def.artifacts ?? [];
35
- expect(declared).toContain('out/word/${session}/article.docx');
36
- for (const a of declared) expect(a.startsWith('out/word/${session}/build')).toBe(false);
37
-
38
- const inputNames = (def.inputs ?? []).map((i) => i.name);
39
- expect(inputNames).toEqual(
40
- expect.arrayContaining([
41
- 'topic',
42
- 'source',
43
- 'out',
44
- 'image_intensity',
45
- 'quality',
46
- 'debug_keep_build',
47
- ]),
48
- );
49
- expect(inputNames[0]).toBe('topic');
50
- expect((def.inputs ?? []).find((i) => i.name === 'topic')?.greedy).toBe(true);
51
- expect((def.inputs ?? []).find((i) => i.name === 'out')?.default).toBe(
52
- 'out/word/${session}/article.docx',
53
- );
54
- });
55
-
56
- it('步骤骨架包含素材、识图、长文、图文混排、docx 导出与校验', async () => {
57
- const def = await parseWorkflowFile(wordPath);
58
- const ids = def.steps.map((s) => s.id);
59
-
60
- for (const id of [
61
- 'stage0_analyze',
62
- 'stage_extract',
63
- 'stage_vision_loop',
64
- 'stage_assemble_material',
65
- 'stage_outline',
66
- 'stage_write_article',
67
- 'stage_img_plan',
68
- 'stage_gen_images',
69
- 'stage_generated_image_gate',
70
- 'stage_finalize_markdown',
71
- 'stage_topic_image_gate',
72
- 'stage_customer_image_gate',
73
- 'stage_export_docx',
74
- 'stage_verify_docx',
75
- 'final_report',
76
- ]) {
77
- expect(ids).toContain(id);
78
- }
79
-
80
- expect(def.steps.find((s) => s.id === 'stage_export_docx')?.skill).toBe(
81
- 'docx',
82
- );
83
- expect(def.steps.find((s) => s.id === 'stage_verify_docx')?.tool).toBe(
84
- 'Bash',
85
- );
86
- expect(def.steps.find((s) => s.id === 'final_report')?.type).toBe('echo');
87
- });
88
-
89
- it('锁定 Word 核心约束:知乎长文、客户图全用、上下文生图、docx OPC', async () => {
90
- const def = await parseWorkflowFile(wordPath);
91
- const all = JSON.stringify(def, null, 2);
92
-
93
- for (const needle of [
94
- '知乎深度文章',
95
- '总结',
96
- '扩写',
97
- '观点',
98
- '论证',
99
- '图文混排',
100
- '所有客户图',
101
- '必须使用',
102
- 'source_file',
103
- 'final_file',
104
- 'article_section',
105
- 'material.md',
106
- 'article.md',
107
- 'skill: docx',
108
- 'markdown-implicit_figures',
109
- 'implicit_figures',
110
- 'OPC',
111
- 'opc_check.py',
112
- 'WORD_DOCX_PNG_CONTENT_TYPE_ADDED',
113
- '无客户图',
114
- '纯 topic',
115
- '至少 3',
116
- '至少 5',
117
- '不得为空',
118
- 'text-to-image',
119
- ]) {
120
- expect(all).toContain(needle);
121
- }
122
-
123
- expect(all).toContain('现代科技风');
124
- expect(all).toContain('知乎配图');
125
- expect(all).toContain('抽象背景');
126
- expect(all).toContain('禁止空泛');
127
- expect(all).toContain('避免 Markdown 图片 alt 文本被渲染成额外可见图注');
128
- });
129
-
130
- it('纯 topic 模式:无客户图也必须按 image_intensity 生成文生图并闸门校验', async () => {
131
- const def = await parseWorkflowFile(wordPath);
132
- const gate = def.steps.find((s) => s.id === 'stage_topic_image_gate');
133
- const all = JSON.stringify(def, null, 2);
134
- const gateText = JSON.stringify(gate, null, 2);
135
- const gateCommand = String(gate?.args?.command ?? '');
136
-
137
- expect(gate?.tool).toBe('Bash');
138
- expect(gateText).toContain('pure topic mode');
139
- expect(gateText).toContain('WORD_TOPIC_IMAGE_GATE_FAILED');
140
- expect(gateCommand).toContain('"minimal": 1');
141
- expect(gateCommand).toContain('"balanced": 3');
142
- expect(gateCommand).toContain('"rich": 5');
143
- expect(gateText).toContain('img_plan.json');
144
- expect(gateText).toContain('image_map.json');
145
- expect(gateText).toContain('article.md');
146
- expect(gateText).toContain('text-to-image');
147
-
148
- for (const needle of [
149
- 'img_plan.json` 不得为空',
150
- '`minimal`:至少 1 张',
151
- '`balanced`:至少 3 张',
152
- '`rich`:至少 5 张',
153
- '`file`、`mode`、`aspect`、`prompt`',
154
- '`mode` 必须是 `text-to-image`',
155
- '章节观点、上下文、场景和图注意图',
156
- ]) {
157
- expect(all).toContain(needle);
158
- }
159
- });
160
-
161
- it('stage_extract 清理旧素材残留,纯 topic 不会误读上次 source/assets', async () => {
162
- const def = await parseWorkflowFile(wordPath);
163
- const extract = def.steps.find((s) => s.id === 'stage_extract');
164
- const command = String(extract?.args?.command ?? '');
165
-
166
- expect(command).toContain('out/word/${session}/build/source.md');
167
- expect(command).toContain('rm -rf out/word/${session}/build/assets');
168
- expect(command).toContain('mkdir -p out/word/${session}/build/assets');
169
- expect(command).toContain('out/word/${session}/build/word_topic_image_gate.json');
170
- expect(command).toContain('out/word/${session}/build/word_topic_image_gate.md');
171
- });
172
-
173
- it('生成配图失败时会在导出前硬失败,不会把渐变占位图交付进 Word', async () => {
174
- const def = await parseWorkflowFile(wordPath);
175
- const gate = def.steps.find((s) => s.id === 'stage_generated_image_gate');
176
- const command = String(gate?.args?.command ?? '');
177
-
178
- expect(gate?.tool).toBe('Bash');
179
- expect(gate?.onError).toBe('halt');
180
- expect(String(gate?.when)).toContain('image_generation_report.json');
181
- expect(command).toContain('qualityOk');
182
- expect(command).toContain('8192');
183
- expect(command).toContain('WORD_GENERATED_IMAGE_GATE_FAILED');
184
- });
185
-
186
- it('不包含 PPT 专属固定画布 / HTML deck / PPTX 导出链路', async () => {
187
- const def = await parseWorkflowFile(wordPath);
188
- const all = JSON.stringify(def, null, 2);
189
- const ids = def.steps.map((s) => s.id);
190
-
191
- for (const forbiddenId of [
192
- 'stage_design_doc',
193
- 'stage_build_loop',
194
- 'visual_quality_gate',
195
- 'stage_export_pptx',
196
- ]) {
197
- expect(ids).not.toContain(forbiddenId);
198
- }
199
- for (const forbidden of [
200
- 'deck.html',
201
- 'design.json',
202
- 'export_pptx',
203
- 'visual_quality_gate',
204
- ]) {
205
- expect(all).not.toContain(forbidden);
206
- }
207
- });
208
- });