minimal-agent 0.12.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (472) hide show
  1. package/README.md +6 -5
  2. package/package.json +62 -5
  3. package/plugins/computer_use/.claude-plugin/plugin.json +1 -1
  4. package/plugins/cron-runner/src/commands.js +4 -4
  5. package/plugins/cron-runner/src/commands.ts +4 -4
  6. package/plugins/workflow-runner/.claude-plugin/plugin.json +2 -2
  7. package/plugins/workflow-runner/commands/workflow.md +57 -90
  8. package/plugins/workflow-runner/commands/workflows.md +4 -4
  9. package/plugins/workflow-runner/plugin.js +24 -13
  10. package/plugins/workflow-runner/plugin.ts +28 -13
  11. package/plugins/workflow-runner/src/discovery.js +160 -0
  12. package/plugins/workflow-runner/src/discovery.ts +194 -0
  13. package/plugins/workflow-runner/src/goalAnchor.js +53 -0
  14. package/plugins/workflow-runner/src/goalAnchor.ts +59 -0
  15. package/plugins/workflow-runner/src/index.js +204 -185
  16. package/plugins/workflow-runner/src/index.ts +249 -224
  17. package/plugins/workflow-runner/src/inputCoercion.js +40 -0
  18. package/plugins/workflow-runner/src/inputCoercion.ts +43 -0
  19. package/plugins/workflow-runner/src/journal.js +224 -0
  20. package/plugins/workflow-runner/src/journal.ts +274 -0
  21. package/plugins/workflow-runner/src/jsonSchema.js +132 -0
  22. package/plugins/workflow-runner/src/jsonSchema.ts +162 -0
  23. package/plugins/workflow-runner/src/moduleResolution.js +64 -0
  24. package/plugins/workflow-runner/src/moduleResolution.ts +71 -0
  25. package/plugins/workflow-runner/src/resourceInputs.js +220 -0
  26. package/plugins/workflow-runner/src/resourceInputs.ts +300 -0
  27. package/plugins/workflow-runner/src/runner.js +404 -467
  28. package/plugins/workflow-runner/src/runner.ts +491 -535
  29. package/plugins/workflow-runner/src/runtime/config.js +46 -0
  30. package/plugins/workflow-runner/src/runtime/config.ts +69 -0
  31. package/plugins/workflow-runner/src/runtime/context.js +1304 -0
  32. package/plugins/workflow-runner/src/runtime/context.ts +1786 -0
  33. package/plugins/workflow-runner/src/runtime/exec.js +34 -0
  34. package/plugins/workflow-runner/src/runtime/exec.ts +53 -0
  35. package/plugins/workflow-runner/src/runtime/flow.js +8 -0
  36. package/plugins/workflow-runner/src/runtime/flow.ts +12 -0
  37. package/plugins/workflow-runner/src/runtime/fs.js +27 -0
  38. package/plugins/workflow-runner/src/runtime/fs.ts +41 -0
  39. package/plugins/workflow-runner/src/runtime/model.js +6 -0
  40. package/plugins/workflow-runner/src/runtime/model.ts +8 -0
  41. package/plugins/workflow-runner/src/runtime/output.js +7 -0
  42. package/plugins/workflow-runner/src/runtime/output.ts +21 -0
  43. package/plugins/workflow-runner/src/runtime/scheduler.js +141 -0
  44. package/plugins/workflow-runner/src/runtime/scheduler.ts +166 -0
  45. package/plugins/workflow-runner/src/runtime/state.js +16 -0
  46. package/plugins/workflow-runner/src/runtime/state.ts +19 -0
  47. package/plugins/workflow-runner/src/runtime/tools.js +3 -0
  48. package/plugins/workflow-runner/src/runtime/tools.ts +6 -0
  49. package/plugins/workflow-runner/src/sandbox.js +141 -0
  50. package/plugins/workflow-runner/src/sandbox.ts +182 -0
  51. package/plugins/workflow-runner/src/scriptGuard.d.mts +38 -0
  52. package/plugins/workflow-runner/src/scriptGuard.mjs +449 -0
  53. package/plugins/workflow-runner/src/taskIdentity.js +172 -152
  54. package/plugins/workflow-runner/src/taskIdentity.ts +233 -200
  55. package/plugins/workflow-runner/src/toolRuntime.js +29 -8
  56. package/plugins/workflow-runner/src/toolRuntime.ts +36 -11
  57. package/plugins/workflow-runner/src/types.js +7 -105
  58. package/plugins/workflow-runner/src/types.ts +155 -520
  59. package/plugins/workflow-runner/src/util.js +47 -0
  60. package/plugins/workflow-runner/src/util.ts +51 -0
  61. package/plugins/workflow-runner/src/workflowContext.js +20 -0
  62. package/plugins/workflow-runner/src/workflowContext.ts +58 -0
  63. package/plugins/workflow-runner/src/workflowDependencies.js +36 -0
  64. package/plugins/workflow-runner/src/workflowDependencies.ts +59 -0
  65. package/plugins/workflow-runner/src/workflowFingerprint.js +118 -0
  66. package/plugins/workflow-runner/src/workflowFingerprint.ts +122 -0
  67. package/plugins/workflow-runner/src/workflowState.js +542 -469
  68. package/plugins/workflow-runner/src/workflowState.ts +639 -589
  69. package/plugins/workflow-runner/test/api.test.ts +223 -0
  70. package/plugins/workflow-runner/test/apiCapabilities.test.ts +614 -0
  71. package/plugins/workflow-runner/test/apiConcurrencyGate.test.ts +104 -0
  72. package/plugins/workflow-runner/test/apiEcho.test.ts +210 -0
  73. package/plugins/workflow-runner/test/apiReadText.test.ts +178 -0
  74. package/plugins/workflow-runner/test/apiResourceLedger.test.ts +184 -0
  75. package/plugins/workflow-runner/test/childWorkflow.test.ts +304 -0
  76. package/plugins/workflow-runner/test/discovery.test.ts +234 -0
  77. package/plugins/workflow-runner/test/goalAnchor.test.ts +106 -0
  78. package/plugins/workflow-runner/test/goalController.test.ts +317 -0
  79. package/plugins/workflow-runner/test/journalLanes.test.ts +198 -0
  80. package/plugins/workflow-runner/test/listResources.test.ts +106 -0
  81. package/plugins/workflow-runner/test/resourceInputs.test.ts +294 -0
  82. package/plugins/workflow-runner/test/sandbox.test.ts +126 -0
  83. package/plugins/workflow-runner/test/scheduler.test.ts +70 -0
  84. package/plugins/workflow-runner/test/scriptGuard.test.ts +276 -0
  85. package/plugins/workflow-runner/test/skillDocSync.test.ts +78 -0
  86. package/plugins/workflow-runner/test/taskIdentity.test.ts +288 -179
  87. package/plugins/workflow-runner/test/workflowFingerprint.test.ts +106 -0
  88. package/plugins/workflow-runner/test/workflowState.test.ts +429 -0
  89. package/skills/pptx/examples/assets/cover-bg.svg +23 -0
  90. package/skills/pptx/examples/assets/icon-spark.svg +5 -0
  91. package/skills/skill-creator/scripts/run_eval.py +3 -2
  92. package/skills/ui-design/SKILL.md +5 -2
  93. package/skills/ui-design/references/layout-composition.md +1 -1
  94. package/skills/workflow-creator/SKILL.md +344 -0
  95. package/skills/workflow-creator/assets/template/workflow.mjs +48 -0
  96. package/skills/workflow-creator/references/api.md +216 -0
  97. package/skills/workflow-creator/references/migration.md +103 -0
  98. package/skills/workflow-creator/references/patterns.md +779 -0
  99. package/skills/workflow-creator/scripts/list-resources.mjs +205 -0
  100. package/skills/workflow-creator/scripts/scaffold.mjs +148 -0
  101. package/skills/workflow-creator/scripts/validate.mjs +275 -0
  102. package/skills/workflow-creator/scripts/workflow-creator.test.mjs +82 -0
  103. package/src/advisor/advisorCoordinator.js +503 -0
  104. package/src/advisor/advisorCoordinator.ts +657 -0
  105. package/src/cli/configMenu.tsx +0 -1
  106. package/src/cli/print.js +44 -6
  107. package/src/cli/print.ts +73 -4
  108. package/src/cli/streamJson.js +5 -6
  109. package/src/cli/streamJson.ts +8 -4
  110. package/src/cli/wizards/advisorWizard.js +4 -2
  111. package/src/cli/wizards/advisorWizard.tsx +8 -2
  112. package/src/cli/wizards/contextAdvisorWizard.js +5 -4
  113. package/src/cli/wizards/contextAdvisorWizard.tsx +7 -6
  114. package/src/collaboration/taskFlow.js +115 -0
  115. package/src/collaboration/taskFlow.ts +169 -0
  116. package/src/config/configDefaults.js +41 -1
  117. package/src/config/configDefaults.ts +43 -1
  118. package/src/config/configDiagnostics.ts +2 -2
  119. package/src/config/configFile.js +40 -9
  120. package/src/config/configFile.ts +60 -11
  121. package/src/config/configService.js +443 -74
  122. package/src/config/configService.ts +723 -142
  123. package/src/config/numericLimits.js +22 -0
  124. package/src/config/numericLimits.ts +24 -0
  125. package/src/config.js +1 -0
  126. package/src/config.ts +3 -2
  127. package/src/context/budgetPlan.js +1 -1
  128. package/src/context/budgetPlan.ts +1 -1
  129. package/src/context/compact.js +7 -2
  130. package/src/context/compact.ts +9 -2
  131. package/src/context/microCompactLite.js +212 -13
  132. package/src/context/microCompactLite.ts +261 -12
  133. package/src/context/sessionRegistry.js +8 -1
  134. package/src/context/sessionRegistry.ts +18 -5
  135. package/src/context/toolResultArchive.js +72 -0
  136. package/src/context/toolResultArchive.ts +95 -0
  137. package/src/goal/errors.js +8 -0
  138. package/src/goal/errors.ts +18 -0
  139. package/src/goal/goalRuntime.js +344 -0
  140. package/src/goal/goalRuntime.ts +466 -0
  141. package/src/goal/goalStore.js +200 -0
  142. package/src/goal/goalStore.ts +219 -0
  143. package/src/goal/index.js +4 -0
  144. package/src/goal/index.ts +4 -0
  145. package/src/goal/statusMapping.js +71 -0
  146. package/src/goal/statusMapping.ts +95 -0
  147. package/src/goal/types.js +7 -0
  148. package/src/goal/types.ts +179 -0
  149. package/src/goal/workflowController.js +306 -0
  150. package/src/goal/workflowController.ts +360 -0
  151. package/src/harness/evidenceLedger.js +2 -0
  152. package/src/harness/evidenceLedger.ts +1 -0
  153. package/src/harness/stallGuard.js +9 -3
  154. package/src/harness/stallGuard.ts +7 -3
  155. package/src/images/imageResolver.js +161 -0
  156. package/src/images/imageResolver.ts +189 -0
  157. package/src/infra/verification.js +56 -20
  158. package/src/infra/verification.ts +87 -20
  159. package/src/llm/client.js +79 -21
  160. package/src/llm/client.ts +182 -35
  161. package/src/llm/gatewayClient.js +201 -0
  162. package/src/llm/gatewayClient.ts +299 -0
  163. package/src/llm/messageProvenance.js +46 -0
  164. package/src/llm/messageProvenance.ts +58 -0
  165. package/src/llm/modelProvider.js +1 -0
  166. package/src/llm/modelProvider.ts +22 -0
  167. package/src/llm/providers/anthropicFormat.js +108 -1
  168. package/src/llm/providers/anthropicFormat.ts +115 -4
  169. package/src/llm/providers/openaiFormat.js +9 -0
  170. package/src/llm/providers/openaiFormat.ts +12 -3
  171. package/src/loop.js +319 -54
  172. package/src/loop.ts +373 -57
  173. package/src/main.js +4 -1
  174. package/src/main.tsx +4 -1
  175. package/src/managedExecution/index.js +2 -0
  176. package/src/managedExecution/index.ts +2 -0
  177. package/src/managedExecution/registry.js +15 -0
  178. package/src/managedExecution/registry.ts +20 -0
  179. package/src/managedExecution/types.js +1 -0
  180. package/src/managedExecution/types.ts +86 -0
  181. package/src/modelRef.js +9 -0
  182. package/src/modelRef.ts +31 -0
  183. package/src/multimodal.js +14 -28
  184. package/src/multimodal.ts +17 -33
  185. package/src/net/lanDiscovery.js +65 -0
  186. package/src/net/lanDiscovery.ts +82 -0
  187. package/src/plugin-sdk.js +28 -3
  188. package/src/plugin-sdk.ts +39 -6
  189. package/src/plugins/pluginApi.ts +16 -1
  190. package/src/plugins/pluginLoader.js +4 -0
  191. package/src/plugins/pluginLoader.ts +6 -0
  192. package/src/plugins/pluginRunner.js +152 -9
  193. package/src/plugins/pluginRunner.ts +186 -8
  194. package/src/plugins/slashFallback.js +113 -0
  195. package/src/plugins/slashFallback.ts +137 -0
  196. package/src/prompts/policyRegistry.js +15 -8
  197. package/src/prompts/policyRegistry.ts +18 -8
  198. package/src/prompts/promptAssembly.js +103 -12
  199. package/src/prompts/promptAssembly.ts +114 -12
  200. package/src/prompts/skillList.js +21 -3
  201. package/src/prompts/skillList.ts +27 -2
  202. package/src/prompts/stableSystemPrompt.js +18 -0
  203. package/src/prompts/stableSystemPrompt.ts +33 -0
  204. package/src/runtime/agentRuntimeContext.js +8 -2
  205. package/src/runtime/agentRuntimeContext.ts +17 -4
  206. package/src/session/runAgentTurn.js +78 -12
  207. package/src/session/runAgentTurn.ts +105 -23
  208. package/src/session/runTurn.js +10 -9
  209. package/src/session/runTurn.ts +17 -8
  210. package/src/session/sessionState.ts +2 -0
  211. package/src/team/auth.js +186 -0
  212. package/src/team/auth.ts +298 -0
  213. package/src/team/cli.js +105 -0
  214. package/src/team/cli.ts +122 -0
  215. package/src/team/onlineToolContract.js +64 -0
  216. package/src/team/onlineToolContract.ts +109 -0
  217. package/src/team/toolPolicy.js +36 -0
  218. package/src/team/toolPolicy.ts +75 -0
  219. package/src/tools/advisor/advisor.js +148 -37
  220. package/src/tools/advisor/advisor.ts +161 -38
  221. package/src/tools/advisor/advisorDecision.js +71 -0
  222. package/src/tools/advisor/advisorDecision.ts +85 -0
  223. package/src/tools/agent/agent.js +18 -5
  224. package/src/tools/agent/agent.ts +21 -7
  225. package/src/tools/agent/agentControl.js +246 -0
  226. package/src/tools/agent/agentControl.ts +284 -0
  227. package/src/tools/agent/agentTaskService.js +40 -1
  228. package/src/tools/agent/agentTaskService.ts +44 -1
  229. package/src/tools/agent/agentTypes.js +14 -2
  230. package/src/tools/agent/agentTypes.ts +15 -2
  231. package/src/tools/applypatch/applyPatch.js +362 -0
  232. package/src/tools/applypatch/applyPatch.ts +428 -0
  233. package/src/tools/bash/bash.js +70 -18
  234. package/src/tools/bash/bash.ts +75 -20
  235. package/src/tools/capabilities.js +10 -5
  236. package/src/tools/capabilities.ts +10 -5
  237. package/src/tools/computeruse/computerIntent.js +32 -0
  238. package/src/tools/computeruse/computerIntent.ts +46 -0
  239. package/src/tools/computeruse/telemetryLog.js +12 -0
  240. package/src/tools/computeruse/telemetryLog.ts +16 -0
  241. package/src/tools/computeruse/vision/telemetry.js +1 -0
  242. package/src/tools/computeruse/vision/telemetry.ts +1 -0
  243. package/src/tools/effectiveToolSet.js +4 -0
  244. package/src/tools/effectiveToolSet.ts +4 -0
  245. package/src/tools/index.js +21 -2
  246. package/src/tools/index.ts +33 -2
  247. package/src/tools/powershell/powershell.js +18 -1
  248. package/src/tools/powershell/powershell.ts +18 -2
  249. package/src/tools/presentresult/presentresult.js +6 -15
  250. package/src/tools/presentresult/presentresult.ts +6 -15
  251. package/src/tools/read/read.js +69 -11
  252. package/src/tools/read/read.ts +70 -11
  253. package/src/tools/shared/fileUtils.js +1 -2
  254. package/src/tools/shared/fileUtils.ts +1 -2
  255. package/src/tools/shared/permanentDeleteGuard.js +34 -3
  256. package/src/tools/shared/permanentDeleteGuard.ts +43 -6
  257. package/src/tools/shared/toolOutputStore.js +23 -1
  258. package/src/tools/shared/toolOutputStore.ts +22 -1
  259. package/src/tools/skill/skill.js +9 -3
  260. package/src/tools/skill/skill.ts +8 -4
  261. package/src/tools/toolPromptGuides.js +117 -0
  262. package/src/tools/toolPromptGuides.ts +137 -0
  263. package/src/tools/webbrowser/agentBrowserPath.js +19 -9
  264. package/src/tools/webbrowser/agentBrowserPath.ts +70 -28
  265. package/src/tools/webbrowser/browser.js +27 -11
  266. package/src/tools/webbrowser/browser.ts +68 -24
  267. package/src/tools/webbrowser/browserAutomation.js +329 -0
  268. package/src/tools/webbrowser/browserAutomation.ts +467 -0
  269. package/src/tools/webbrowser/browserAxState.js +97 -0
  270. package/src/tools/webbrowser/browserAxState.ts +142 -0
  271. package/src/tools/webbrowser/browserBatch.js +1578 -0
  272. package/src/tools/webbrowser/browserBatch.ts +2382 -0
  273. package/src/tools/webbrowser/browserCdp.js +208 -0
  274. package/src/tools/webbrowser/browserCdp.ts +255 -0
  275. package/src/tools/webbrowser/browserConditions.js +24 -0
  276. package/src/tools/webbrowser/browserConditions.ts +45 -0
  277. package/src/tools/webbrowser/browserContent.js +281 -0
  278. package/src/tools/webbrowser/browserContent.ts +438 -0
  279. package/src/tools/webbrowser/browserControl.js +131 -30
  280. package/src/tools/webbrowser/browserControl.ts +210 -50
  281. package/src/tools/webbrowser/browserDaemon.js +22 -14
  282. package/src/tools/webbrowser/browserDaemon.ts +54 -21
  283. package/src/tools/webbrowser/browserFrames.js +47 -0
  284. package/src/tools/webbrowser/browserFrames.ts +54 -0
  285. package/src/tools/webbrowser/browserInteractionResolver.js +17 -0
  286. package/src/tools/webbrowser/browserInteractionResolver.ts +40 -0
  287. package/src/tools/webbrowser/browserLocator.js +140 -0
  288. package/src/tools/webbrowser/browserLocator.ts +194 -0
  289. package/src/tools/webbrowser/browserOutcome.js +10 -17
  290. package/src/tools/webbrowser/browserOutcome.ts +48 -31
  291. package/src/tools/webbrowser/browserRecovery.js +58 -0
  292. package/src/tools/webbrowser/browserRecovery.ts +83 -0
  293. package/src/tools/webbrowser/browserRunRegistry.js +35 -3
  294. package/src/tools/webbrowser/browserRunRegistry.ts +91 -15
  295. package/src/tools/webbrowser/browserService.js +28 -2
  296. package/src/tools/webbrowser/browserService.ts +49 -9
  297. package/src/tools/webbrowser/browserStream.js +132 -33
  298. package/src/tools/webbrowser/browserStream.ts +224 -50
  299. package/src/tools/webbrowser/browserTabs.js +48 -15
  300. package/src/tools/webbrowser/browserTabs.ts +178 -96
  301. package/src/tools/webbrowser/webbrowser.js +683 -144
  302. package/src/tools/webbrowser/webbrowser.ts +979 -236
  303. package/src/tools/webfetch/preapproved.js +0 -2
  304. package/src/tools/webfetch/preapproved.ts +0 -2
  305. package/src/tools/websearch/websearch.js +129 -8
  306. package/src/tools/websearch/websearch.ts +138 -6
  307. package/src/types.ts +450 -42
  308. package/src/ui/App.js +377 -58
  309. package/src/ui/App.tsx +576 -111
  310. package/src/ui/LiveArea.js +14 -8
  311. package/src/ui/LiveArea.tsx +14 -10
  312. package/src/ui/MessageList.js +63 -20
  313. package/src/ui/MessageList.tsx +101 -16
  314. package/src/ui/ModelPicker.js +7 -4
  315. package/src/ui/ModelPicker.tsx +55 -8
  316. package/src/ui/hooks/useChat.js +152 -163
  317. package/src/ui/hooks/useChat.ts +396 -334
  318. package/src/ui/loginCommand.js +56 -0
  319. package/src/ui/loginCommand.ts +63 -0
  320. package/src/ui/toolProgress.js +41 -0
  321. package/src/ui/toolProgress.ts +44 -0
  322. package/src/web/browserBridge.js +20 -2
  323. package/src/web/browserBridge.ts +20 -2
  324. package/src/web/protocol.ts +1897 -194
  325. package/workflows/adaptive-research/workflow.mjs +86 -0
  326. package/workflows/e2e-capabilities/workflow.mjs +102 -0
  327. package/workflows/e2e-llm/workflow.mjs +52 -0
  328. package/workflows/e2e-smoke/workflow.mjs +59 -0
  329. package/workflows/e2e-vision-schema/README.md +48 -0
  330. package/workflows/e2e-vision-schema/workflow.mjs +149 -0
  331. package/workflows/e2e-write-greet/workflow.mjs +37 -0
  332. package/workflows/file-census/README.md +14 -0
  333. package/workflows/file-census/scripts/.gitkeep +2 -0
  334. package/workflows/file-census/workflow.mjs +110 -0
  335. package/workflows/goal/README.md +166 -0
  336. package/workflows/goal/prompts/audit.md +57 -0
  337. package/workflows/goal/prompts/contract.md +56 -0
  338. package/workflows/goal/prompts/iterate.md +37 -0
  339. package/workflows/goal/workflow.mjs +501 -0
  340. package/workflows/illustrate/README.md +90 -0
  341. package/workflows/illustrate/assets/engines.json +20 -0
  342. package/workflows/illustrate/assets/extract-baidu.js +21 -0
  343. package/workflows/illustrate/assets/extract-bing.js +33 -0
  344. package/workflows/illustrate/assets/extract-google.js +31 -0
  345. package/workflows/illustrate/workflow.mjs +301 -0
  346. package/workflows/plan/workflow.mjs +389 -0
  347. package/workflows/question-crops/README.md +35 -0
  348. package/workflows/question-crops/prompts/inventory.md +23 -0
  349. package/workflows/question-crops/scripts/image-ops.mjs +305 -0
  350. package/workflows/question-crops/scripts/image-ops.test.mjs +95 -0
  351. package/workflows/question-crops/workflow.mjs +172 -0
  352. package/workflows/ralph-loop/workflow.mjs +162 -0
  353. package/workflows/research/DESIGN.md +449 -0
  354. package/workflows/research/README.md +74 -0
  355. package/workflows/research/prompts/s0-goal.md +43 -0
  356. package/workflows/research/prompts/s1-early-exit.md +22 -0
  357. package/workflows/research/prompts/s1-map.md +58 -0
  358. package/workflows/research/prompts/s2-options.md +53 -0
  359. package/workflows/research/prompts/s3-deep-dive.md +56 -0
  360. package/workflows/research/prompts/s4-verify.md +74 -0
  361. package/workflows/research/prompts/s5-synthesis.md +81 -0
  362. package/workflows/research/prompts/s5b-fill-gaps.md +32 -0
  363. package/workflows/research/prompts/s6-package.md +32 -0
  364. package/workflows/research/scripts/build-report.mjs +98 -0
  365. package/workflows/research/workflow.mjs +288 -0
  366. package/workflows/wechat-reading-shots/prompts/collect-params.md +16 -0
  367. package/workflows/wechat-reading-shots/prompts/evaluate.md +20 -0
  368. package/workflows/wechat-reading-shots/prompts/open-book.md +28 -0
  369. package/workflows/wechat-reading-shots/prompts/read-page.md +13 -0
  370. package/workflows/wechat-reading-shots/prompts/turn-batch.md +24 -0
  371. package/workflows/wechat-reading-shots/test/control-flow.test.ts +329 -0
  372. package/workflows/wechat-reading-shots/workflow.mjs +266 -0
  373. package/workflows/wrong-question-docx/README.md +55 -0
  374. package/workflows/wrong-question-docx/prompts/figure-qa.md +8 -0
  375. package/workflows/wrong-question-docx/prompts/transcribe.md +25 -0
  376. package/workflows/wrong-question-docx/scripts/workbook.mjs +857 -0
  377. package/workflows/wrong-question-docx/test/control-flow.test.ts +165 -0
  378. package/workflows/wrong-question-docx/test/workbook.test.mjs +303 -0
  379. package/workflows/wrong-question-docx/workflow.mjs +485 -0
  380. package/plugins/workflow-runner/src/agentCommon.js +0 -354
  381. package/plugins/workflow-runner/src/agentCommon.ts +0 -435
  382. package/plugins/workflow-runner/src/controlFlow/branch.js +0 -40
  383. package/plugins/workflow-runner/src/controlFlow/branch.ts +0 -46
  384. package/plugins/workflow-runner/src/controlFlow/loop.js +0 -211
  385. package/plugins/workflow-runner/src/controlFlow/loop.ts +0 -248
  386. package/plugins/workflow-runner/src/controlFlow/pause.js +0 -129
  387. package/plugins/workflow-runner/src/controlFlow/pause.ts +0 -141
  388. package/plugins/workflow-runner/src/controlFlow/signal.js +0 -21
  389. package/plugins/workflow-runner/src/controlFlow/signal.ts +0 -29
  390. package/plugins/workflow-runner/src/controlFlow/types.js +0 -18
  391. package/plugins/workflow-runner/src/controlFlow/types.ts +0 -63
  392. package/plugins/workflow-runner/src/dslManifest.js +0 -72
  393. package/plugins/workflow-runner/src/dslManifest.ts +0 -127
  394. package/plugins/workflow-runner/src/expressions.js +0 -618
  395. package/plugins/workflow-runner/src/expressions.ts +0 -622
  396. package/plugins/workflow-runner/src/loader.js +0 -573
  397. package/plugins/workflow-runner/src/loader.ts +0 -721
  398. package/plugins/workflow-runner/src/multimodal.js +0 -38
  399. package/plugins/workflow-runner/src/multimodal.ts +0 -64
  400. package/plugins/workflow-runner/src/recovery.js +0 -119
  401. package/plugins/workflow-runner/src/recovery.ts +0 -149
  402. package/plugins/workflow-runner/src/stepExecutors/agent.js +0 -173
  403. package/plugins/workflow-runner/src/stepExecutors/agent.ts +0 -234
  404. package/plugins/workflow-runner/src/stepExecutors/assert.js +0 -41
  405. package/plugins/workflow-runner/src/stepExecutors/assert.ts +0 -50
  406. package/plugins/workflow-runner/src/stepExecutors/echo.js +0 -31
  407. package/plugins/workflow-runner/src/stepExecutors/echo.ts +0 -38
  408. package/plugins/workflow-runner/src/stepExecutors/llm.js +0 -99
  409. package/plugins/workflow-runner/src/stepExecutors/llm.ts +0 -133
  410. package/plugins/workflow-runner/src/stepExecutors/set.js +0 -49
  411. package/plugins/workflow-runner/src/stepExecutors/set.ts +0 -56
  412. package/plugins/workflow-runner/src/stepExecutors/skill.js +0 -111
  413. package/plugins/workflow-runner/src/stepExecutors/skill.ts +0 -140
  414. package/plugins/workflow-runner/src/stepExecutors/tool.js +0 -208
  415. package/plugins/workflow-runner/src/stepExecutors/tool.ts +0 -256
  416. package/plugins/workflow-runner/src/stepExecutors/verify.js +0 -58
  417. package/plugins/workflow-runner/src/stepExecutors/verify.ts +0 -68
  418. package/plugins/workflow-runner/src/stepPipeline.js +0 -277
  419. package/plugins/workflow-runner/src/stepPipeline.ts +0 -366
  420. package/plugins/workflow-runner/test/agent.test.ts +0 -587
  421. package/plugins/workflow-runner/test/agentLlmError.test.ts +0 -373
  422. package/plugins/workflow-runner/test/bashBlacklist.sweep.test.ts +0 -65
  423. package/plugins/workflow-runner/test/captureMisbind.test.ts +0 -99
  424. package/plugins/workflow-runner/test/cli.e2e.test.ts +0 -147
  425. package/plugins/workflow-runner/test/context-files.test.ts +0 -320
  426. package/plugins/workflow-runner/test/e2e.test.ts +0 -370
  427. package/plugins/workflow-runner/test/engineRobustness.test.ts +0 -226
  428. package/plugins/workflow-runner/test/expressions.test.ts +0 -397
  429. package/plugins/workflow-runner/test/foundation.test.ts +0 -126
  430. package/plugins/workflow-runner/test/graceful.test.ts +0 -139
  431. package/plugins/workflow-runner/test/greedyInputs.load.test.ts +0 -47
  432. package/plugins/workflow-runner/test/hostCapability.test.ts +0 -108
  433. package/plugins/workflow-runner/test/illustrate.load.test.ts +0 -183
  434. package/plugins/workflow-runner/test/jsonPayload.test.ts +0 -83
  435. package/plugins/workflow-runner/test/loader.test.ts +0 -617
  436. package/plugins/workflow-runner/test/maxTurnsRetryDelay.test.ts +0 -33
  437. package/plugins/workflow-runner/test/multimodal.test.ts +0 -342
  438. package/plugins/workflow-runner/test/output-schema.test.ts +0 -213
  439. package/plugins/workflow-runner/test/parseWorkflowArgs.test.ts +0 -87
  440. package/plugins/workflow-runner/test/pluginRunner.isolation.test.ts +0 -269
  441. package/plugins/workflow-runner/test/ppt.load.test.ts +0 -1220
  442. package/plugins/workflow-runner/test/ralphLoop.e2e.test.ts +0 -220
  443. package/plugins/workflow-runner/test/recovery.test.ts +0 -265
  444. package/plugins/workflow-runner/test/runner.test.ts +0 -911
  445. package/plugins/workflow-runner/test/runnerPreflight.test.ts +0 -379
  446. package/plugins/workflow-runner/test/skillTurnDone.test.ts +0 -71
  447. package/plugins/workflow-runner/test/stateLifecycle.test.ts +0 -150
  448. package/plugins/workflow-runner/test/stepPipeline.test.ts +0 -114
  449. package/plugins/workflow-runner/test/taskArbitration.test.ts +0 -338
  450. package/plugins/workflow-runner/test/taskLifecycle.test.ts +0 -270
  451. package/plugins/workflow-runner/test/toolArtifactOverwrite.test.ts +0 -221
  452. package/plugins/workflow-runner/test/toolCapabilityBoundary.test.ts +0 -29
  453. package/plugins/workflow-runner/test/toolRuntimeIntegration.test.ts +0 -168
  454. package/plugins/workflow-runner/test/webppt.load.test.ts +0 -250
  455. package/plugins/workflow-runner/test/word.load.test.ts +0 -208
  456. package/plugins/workflow-runner/test/workflows.smoke.test.ts +0 -76
  457. package/plugins/workflow-runner/test/yamlGuardConditions.test.ts +0 -207
  458. package/src/advisorState.js +0 -22
  459. package/src/cli/configWizard.js +0 -293
  460. package/src/tools/toolProgressBridge.js +0 -48
  461. package/workflows/adaptive-research.yaml +0 -50
  462. package/workflows/book-review-short.yaml +0 -125
  463. package/workflows/e2e-write-greet.yaml +0 -31
  464. package/workflows/illustrate.yaml +0 -227
  465. package/workflows/plan.yaml +0 -470
  466. package/workflows/ppt.yaml +0 -1670
  467. package/workflows/ralph-loop.yaml +0 -199
  468. package/workflows/schema.json +0 -176
  469. package/workflows/webppt.yaml +0 -496
  470. package/workflows/wechat-reading-shots.yaml +0 -315
  471. package/workflows/word.yaml +0 -720
  472. package/workflows/youtube-shorts.yaml +0 -202
@@ -1,207 +0,0 @@
1
- /**
2
- * ============================================================
3
- * 真实 yaml 的护栏条件必须真的能判真、也真的能判假
4
- * ------------------------------------------------------------
5
- * 护栏(assert / when)有一个非常隐蔽的失效模式:**永远判假,且不报任何错**。
6
- * 用户看到的是 onFail 里那段业务文案,与真实原因毫无关系,排查方向被彻底带偏。
7
- *
8
- * 实测踩到的两个源头,都只在真机跑到那一步才暴露,单测不覆盖就查不出来:
9
- *
10
- * ① **反斜杠被吃掉两层**。表达式引擎的字符串字面量吃一层,YAML 双引号标量再吃一层
11
- * —— 写 '(\w+)' 传到引擎手上变成 '(w+)',正则悄悄失配。
12
- * 对策:正则一律写字符类 [a-z] / [0-9],不用 \w / \d。
13
- *
14
- * ② **用 includes 在自由文本里找关键词会被解释性文字骗过**。
15
- * 实测:模型回「right/pagedown/space 全部无效」,`includes(pager,'right')` 判真放行,
16
- * 于是本该在探针步诚实停下的运行,一路空转到后面才崩。
17
- * 对策:让模型输出 `PAGER=xxx` 协议令牌,用 extract 精确取值。
18
- *
19
- * 所以这个测试直接读**真实 yaml 文件**,用**真实形状的捕获文本**求值每个护栏,
20
- * 正反两面都断言。不自造样本 —— 自造样本正是上面两个 bug 能溜过单测的原因。
21
- * ============================================================
22
- */
23
-
24
- import { describe, expect, test } from 'bun:test';
25
- import { readFileSync } from 'node:fs';
26
- import { join } from 'node:path';
27
- import { parse } from 'yaml';
28
- import { evalExpr } from '../src/expressions.js';
29
- import { VarStack } from '../src/types.js';
30
-
31
- const YAML_PATH = join(
32
- import.meta.dir,
33
- '..',
34
- '..',
35
- '..',
36
- 'workflows',
37
- 'wechat-reading-shots.yaml',
38
- );
39
-
40
- type Step = { id: string; condition?: string; when?: string };
41
- const def = parse(readFileSync(YAML_PATH, 'utf8')) as { steps: Step[] };
42
-
43
- function stepById(id: string): Step {
44
- const found = def.steps.find((s) => s.id === id);
45
- expect(found).toBeDefined();
46
- return found!;
47
- }
48
-
49
- function varsWith(overrides: Record<string, unknown>): VarStack {
50
- const vs = new VarStack();
51
- vs.set('cfg', { book: '某本书', page: 12, shots: 10 });
52
- vs.set('open_state', 'OPEN=ok');
53
- vs.set('cur_page', 'PAGE=11 12');
54
- for (const [k, v] of Object.entries(overrides)) vs.set(k, v);
55
- return vs;
56
- }
57
-
58
- describe('wechat-reading-shots 护栏条件', () => {
59
- test('★ 定位护栏不能被解释性文字骗过(令牌必须精确取值)', () => {
60
- // 真实形状:模型写一大段说明再给结论。若护栏写成 includes(open_state,'ok'),
61
- // 「ok 的路子都走不通」这句话里的 'ok' 会让它判真放行。
62
- const deceptive = '归位、书架、搜索都试过了,ok 的路子都走不通。\n\nOPEN=fail';
63
- expect(
64
- evalExpr(stepById('guard_open').condition!, varsWith({ open_state: deceptive })),
65
- ).toBe(false);
66
- });
67
-
68
- test('★ 定位护栏能从一大段说明文字里取出 OPEN 令牌', () => {
69
- // 反斜杠转义写错时这条会静默判假 —— onFail 会说「没能停到正文页」,
70
- // 与真实原因(正则失配)毫无关系,排查方向被彻底带偏。
71
- const verbose =
72
- '点了书架里的封面,放大镜读到「81 / 116」,已经在正文了。\n\nOPEN=ok';
73
- expect(
74
- evalExpr(stepById('guard_open').condition!, varsWith({ open_state: verbose })),
75
- ).toBe(true);
76
- });
77
-
78
- test('落点护栏:双页对开时目标落在左页或右页都算到位', () => {
79
- const cond = stepById('guard_landing').condition!;
80
- expect(evalExpr(cond, varsWith({ cur_page: 'PAGE=12 13' }))).toBe(true); // 左页命中
81
- expect(evalExpr(cond, varsWith({ cur_page: 'PAGE=11 12' }))).toBe(true); // 右页命中
82
- expect(evalExpr(cond, varsWith({ cur_page: 'PAGE=80 81' }))).toBe(false); // 差得远
83
- expect(evalExpr(cond, varsWith({ cur_page: 'PAGE=0 0' }))).toBe(false); // 读不出来
84
- });
85
-
86
- test('落点护栏不能被「112 里含 12」这类子串匹配蒙混过关', () => {
87
- // includes 写法会在这里判真('PAGE 112 113' 含 '12'),extract 精确取值不会。
88
- expect(
89
- evalExpr(stepById('guard_landing').condition!, varsWith({ cur_page: 'PAGE=112 113' })),
90
- ).toBe(false);
91
- });
92
-
93
- test('所有护栏正则都不含反斜杠转义(\\w/\\d 会被 YAML 吃掉一层)', () => {
94
- // 必须**递归进 loop 的 do[]** —— 循环体里的 when 同样是护栏,
95
- // 只扫顶层会漏掉截图循环的边界判定(那正是最容易写错的地方)。
96
- const collect = (steps: (Step & { do?: Step[] })[]): string[] =>
97
- steps.flatMap((st) => [
98
- ...[st.condition, st.when].filter((e): e is string => typeof e === 'string'),
99
- ...(Array.isArray(st.do) ? collect(st.do as (Step & { do?: Step[] })[]) : []),
100
- ]);
101
- const exprs = collect(def.steps as (Step & { do?: Step[] })[]);
102
- expect(exprs.length).toBeGreaterThan(4);
103
- for (const e of exprs) {
104
- expect(e).not.toContain('\\w');
105
- expect(e).not.toContain('\\d');
106
- expect(e).not.toContain('\\s');
107
- }
108
- });
109
- });
110
-
111
- /**
112
- * ============================================================
113
- * 循环体里 capture 出来的变量必须活到循环之外
114
- * ------------------------------------------------------------
115
- * 真实事故:seek 循环一路把书从第 84 页翻到第 12 页,循环里每轮都 capture
116
- * `cur_page`,最后一轮读到「PAGE=12 13」—— 任务其实已经成功。但 loop 每轮
117
- * `vars.push()` … `vars.pop()`,capture 写进的是**迭代帧**,循环一结束就被弹掉。
118
- * 循环外的 guard_landing 读到空串,报「没能翻到第 12 页(最后读到的页码:)」,
119
- * 把一个刚刚成功的任务判成失败,报错文案还完全指不向真因。
120
- *
121
- * 正确的语义分界:**迭代变量(as / as_idx)按帧作用域,作者显式命名的变量不按。**
122
- * ============================================================
123
- */
124
- describe('VarStack 作用域:迭代变量 vs 作者变量', () => {
125
- test('★ 循环体里 set 的作者变量,pop 之后依然在', () => {
126
- const vs = new VarStack();
127
- vs.pushIteration();
128
- vs.setIteration('i', 3); // 迭代变量
129
- vs.set('cur_page', 'PAGE=12 13'); // capture / set 步写的作者变量
130
- expect(vs.get('i')).toBe(3);
131
- vs.pop();
132
- expect(vs.get('i')).toBeUndefined(); // 迭代变量随帧消失 —— 这是对的
133
- expect(vs.get('cur_page')).toBe('PAGE=12 13'); // 作者变量必须留下
134
- });
135
-
136
- test('嵌套循环:内层写的作者变量穿透到所有循环之外', () => {
137
- const vs = new VarStack();
138
- vs.pushIteration();
139
- vs.pushIteration();
140
- vs.set('hit_edge', true);
141
- vs.pop();
142
- vs.pop();
143
- expect(vs.get('hit_edge')).toBe(true);
144
- });
145
-
146
- test('迭代变量不会互相污染:内层 pop 后外层的值还在', () => {
147
- const vs = new VarStack();
148
- vs.pushIteration();
149
- vs.setIteration('i', 1);
150
- vs.pushIteration();
151
- vs.setIteration('i', 99);
152
- expect(vs.get('i')).toBe(99);
153
- vs.pop();
154
- expect(vs.get('i')).toBe(1);
155
- });
156
-
157
- test('snapshot 里也能看到循环体写的作者变量(落盘/事件用同一份)', () => {
158
- const vs = new VarStack();
159
- vs.pushIteration();
160
- vs.set('cur_page', 'PAGE=12 13');
161
- vs.pop();
162
- expect(vs.snapshot().cur_page).toBe('PAGE=12 13');
163
- });
164
- });
165
-
166
- /**
167
- * ============================================================
168
- * 参数解析必须容忍模型的自由文本
169
- * ------------------------------------------------------------
170
- * 「最后只回复一行 JSON」是**没法强制**的约定。实测模型会在 JSON 前加一句
171
- * 「三项参数都已给出:…」,也可能套 ```json 围栏。
172
- *
173
- * 裸 `parseJson(整段文本)` 一炸,`cfg` 变成 null,下游 guard_params 报
174
- * 「参数没收齐(书名为空…)」—— 而参数其实齐了,是解析被前言撑爆的。
175
- * 又一次「报错文案指不向真因」,这类静默偏航是本项目反复踩的坑。
176
- * ============================================================
177
- */
178
- describe('参数 JSON 解析的容错', () => {
179
- const setStep = def.steps.find((s) => s.id === 'set_params') as unknown as {
180
- set: { cfg: string };
181
- };
182
- /** 取出 ${...} 里的表达式 */
183
- const expr = setStep.set.cfg.replace(/^\$\{/, '').replace(/\}$/, '');
184
-
185
- const cases: [string, string][] = [
186
- ['纯 JSON', '{"book":"a","page":12,"shots":10}'],
187
- ['带前言', '三项参数都已给出。\n\n{"book":"a","page":12,"shots":10}'],
188
- ['带 ```json 围栏', '```json\n{"book":"a","page":12,"shots":10}\n```'],
189
- ['前后都有话', '好的:\n{"book":"a","page":12,"shots":10}\n以上。'],
190
- ];
191
-
192
- for (const [name, raw] of cases) {
193
- test(`★ ${name} 都能解出参数`, () => {
194
- const vs = new VarStack();
195
- vs.set('params_json', raw);
196
- const cfg = evalExpr(expr, vs) as { book: string; page: number; shots: number };
197
- expect(cfg).toEqual({ book: 'a', page: 12, shots: 10 });
198
- });
199
- }
200
-
201
- test('解出来的 cfg 能通过 guard_params', () => {
202
- const vs = new VarStack();
203
- vs.set('params_json', '说明在前。\n{"book":"a","page":12,"shots":10}');
204
- vs.set('cfg', evalExpr(expr, vs));
205
- expect(evalExpr(stepById('guard_params').condition!, vs)).toBe(true);
206
- });
207
- });
@@ -1,22 +0,0 @@
1
- /**
2
- * ============================================================
3
- * src/advisorState.ts —— 顾问模型(Advisor 工具)开关状态
4
- * ------------------------------------------------------------
5
- * 模块级单例,镜像 askBridge.ts::setAskHandler 的简单风格——这不是按请求
6
- * 隔离的状态(不需要 AsyncLocalStorage),TUI 单进程单会话场景下一个
7
- * 进程内全局开关就够用。
8
- *
9
- * 默认 true:用户配置了 5 个 ADVISOR_AGENT_* 环境变量本身就是"我要用"的
10
- * 信号,/advisor off 是需要时的临时关闭手段。
11
- *
12
- * 纯内存,不落盘——进程重启即重置为默认值(与 sessionState.ts 的
13
- * "运行时态、不持久化"定位一致)。
14
- * ============================================================
15
- */
16
- let enabled = true;
17
- export function isAdvisorEnabled() {
18
- return enabled;
19
- }
20
- export function setAdvisorEnabled(value) {
21
- enabled = value;
22
- }
@@ -1,293 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- /**
3
- * ============================================================
4
- * src/cli/configWizard.tsx —— 首次启动配置向导(Ink TUI)
5
- * ------------------------------------------------------------
6
- * 当 loadProviderLayered() 返回 null(env 和 ~/.minimal-agent/config.json 都没有
7
- * 完整 provider 配置)时,由 Root.tsx 渲染本组件。
8
- *
9
- * 流程:
10
- * Step 1: 选 provider 预设(minimax / openai / deepseek / kimi / custom)
11
- * Step 2: 输入 baseURL(预设有默认值,用户可改)
12
- * Step 3: 输入 apiKey(不回显,用 * 替代)
13
- * Step 4: 输入 model(预设有候选)
14
- * Step 5: 连接测试(POST /chat/completions max_tokens=5)
15
- * - 通过 → saveConfig + onSuccess(provider) → Root 切到 App
16
- * - 失败 → 显示错误 + 回到 Step 1(保留已输入的值方便修改)
17
- *
18
- * 设计取舍:
19
- * - 不引第三方 prompt 库(@inquirer/prompts 等),用 Ink + useInput 手写,
20
- * 保持"零新增依赖"承诺。
21
- * - 不做 spinner 动画,loading 时显示一行文字够用。
22
- * - 不做"返回上一步",要修改请按 ESC 退出向导重跑(简化键位逻辑)。
23
- * —— 用户中途退出 = 不写文件 = 下次启动继续向导,符合需求 "直到成功为止"。
24
- * ============================================================
25
- */
26
- import { useCallback, useMemo, useState } from 'react';
27
- import { Box, Text, useApp, useInput } from 'ink';
28
- import { saveConfig } from '../config/configFile.js';
29
- import { configService } from '../config/configService.js';
30
- // 兜底值:custom 或表外 model 都退到这里。
31
- // 与 src/config.ts 的同名常量含义对齐("既没 env、saved 也没填 contextWindow" 的最终兜底)。
32
- const FALLBACK_CONTEXT_WINDOW = 128_000;
33
- const PRESETS = [
34
- {
35
- name: 'minimax',
36
- label: 'MiniMax (海螺)',
37
- baseURL: 'https://api.minimax.chat/v1',
38
- models: ['MiniMax-M3', 'MiniMax-M2.7', 'MiniMax-M1', 'abab6.5s-chat'],
39
- contextWindow: 204_800,
40
- },
41
- {
42
- // 火山方舟 ARK Coding Plan —— 一个 endpoint 后挂多个 model id,
43
- // model 字段大小写严格匹配('glm-5.1' 而非 'GLM-5.1')。
44
- // 部分 model(如 glm-5.1)走 draft-2020-12 严校验,靠 zodToJson 的
45
- // modernizeExclusiveBounds 兼容。
46
- name: 'volces',
47
- label: '火山方舟 Coding Plan (ARK)',
48
- baseURL: 'https://ark.cn-beijing.volces.com/api/coding/v3',
49
- models: [
50
- 'doubao-seed-2.0-pro',
51
- 'doubao-seed-2.0-code',
52
- 'doubao-seed-code',
53
- 'glm-5.1',
54
- 'minimax-latest',
55
- 'deepseek-v3.2',
56
- 'kimi-k2.7-code',
57
- 'kimi-k2.6',
58
- ],
59
- contextWindow: 204_800,
60
- modelContextWindows: {
61
- 'kimi-k2.7-code': 512_000,
62
- },
63
- },
64
- {
65
- name: 'deepseek',
66
- label: 'DeepSeek',
67
- baseURL: 'https://api.deepseek.com/v1',
68
- models: ['deepseek-chat', 'deepseek-reasoner'],
69
- contextWindow: 128_000,
70
- },
71
- {
72
- name: 'openai',
73
- label: 'OpenAI',
74
- baseURL: 'https://api.openai.com/v1',
75
- models: ['gpt-4o', 'gpt-4o-mini'],
76
- contextWindow: 128_000,
77
- },
78
- {
79
- name: 'moonshot',
80
- label: 'Moonshot (Kimi)',
81
- baseURL: 'https://api.moonshot.cn/v1',
82
- models: ['moonshot-v1-8k', 'moonshot-v1-32k', 'moonshot-v1-128k'],
83
- contextWindow: 128_000,
84
- modelContextWindows: {
85
- 'moonshot-v1-8k': 8_000,
86
- 'moonshot-v1-32k': 32_000,
87
- 'moonshot-v1-128k': 128_000,
88
- },
89
- },
90
- {
91
- name: 'custom',
92
- label: '自定义(手动填 baseURL)',
93
- baseURL: '',
94
- models: [],
95
- contextWindow: FALLBACK_CONTEXT_WINDOW,
96
- },
97
- ];
98
- function resolveContextWindow(preset, model) {
99
- return (preset.modelContextWindows?.[model] ??
100
- preset.contextWindow ??
101
- FALLBACK_CONTEXT_WINDOW);
102
- }
103
- export function ConfigWizard({ onSuccess }) {
104
- const { exit } = useApp();
105
- const [step, setStep] = useState('preset');
106
- const [presetIndex, setPresetIndex] = useState(0);
107
- const [baseURL, setBaseURL] = useState('');
108
- const [apiKey, setApiKey] = useState('');
109
- const [model, setModel] = useState('');
110
- const [modelIndex, setModelIndex] = useState(0);
111
- const [draft, setDraft] = useState('');
112
- const [errorMsg, setErrorMsg] = useState(null);
113
- const preset = PRESETS[presetIndex];
114
- const enterStep = useCallback((next) => {
115
- setErrorMsg(null);
116
- if (next === 'baseURL')
117
- setDraft(baseURL || preset.baseURL);
118
- if (next === 'apiKey')
119
- setDraft('');
120
- if (next === 'model') {
121
- if (preset.models.length > 0) {
122
- setDraft(model || preset.models[0]);
123
- setModelIndex(0);
124
- }
125
- else {
126
- setDraft(model);
127
- }
128
- }
129
- setStep(next);
130
- }, [baseURL, model, preset]);
131
- // handleTest 接受 finalModel 作为参数:
132
- // Step 4 里调用方 `setModel(...) + handleTest()` 时,setModel 是异步的,handleTest
133
- // 的 closure 还引用着旧的 model state;直接传 finalModel 才能避免"首次必跑两轮"
134
- // —— 第一次发请求时 model 还是空串,API 报错,回到 Step 1 再走一遍才能成功。
135
- //
136
- // 测试通过后 **不立即** saveConfig + onSuccess,而是转去 Step 5(tavily)
137
- // 让用户决定是否一并填 Tavily key,最后在 finalize() 一次性落盘。
138
- const handleTest = useCallback(async (finalModel) => {
139
- setStep('testing');
140
- setErrorMsg(null);
141
- try {
142
- const url = `${baseURL.replace(/\/$/, '')}/chat/completions`;
143
- const resp = await fetch(url, {
144
- method: 'POST',
145
- headers: {
146
- 'Content-Type': 'application/json',
147
- Authorization: `Bearer ${apiKey}`,
148
- },
149
- body: JSON.stringify({
150
- model: finalModel,
151
- messages: [{ role: 'user', content: 'ping' }],
152
- max_tokens: 5,
153
- stream: false,
154
- }),
155
- });
156
- if (!resp.ok) {
157
- const body = await resp.text().catch(() => '');
158
- throw new Error(`HTTP ${resp.status}: ${body.slice(0, 200) || resp.statusText}`);
159
- }
160
- const data = (await resp.json());
161
- if (!Array.isArray(data.choices)) {
162
- throw new Error('响应中没有 choices 字段,可能不是 OpenAI 兼容协议');
163
- }
164
- setDraft('');
165
- setStep('tavily');
166
- }
167
- catch (e) {
168
- setErrorMsg(e.message || '连接失败');
169
- setStep('error');
170
- }
171
- }, [apiKey, baseURL]);
172
- // 落盘 + 切到 App。tavily key 为空表示用户跳过 WebSearch 配置。
173
- const finalize = useCallback(async (finalModel, tavilyApiKey) => {
174
- const contextWindow = resolveContextWindow(preset, finalModel);
175
- await saveConfig({
176
- baseURL,
177
- apiKey,
178
- model: finalModel,
179
- provider: preset.name,
180
- contextWindow,
181
- tavilyApiKey,
182
- });
183
- await configService.reload();
184
- onSuccess({
185
- name: preset.name,
186
- baseURL,
187
- apiKey,
188
- model: finalModel,
189
- contextWindow,
190
- });
191
- }, [apiKey, baseURL, onSuccess, preset]);
192
- useInput((input, key) => {
193
- if (key.escape || (key.ctrl && input === 'c')) {
194
- exit();
195
- return;
196
- }
197
- if (step === 'preset') {
198
- if (key.upArrow) {
199
- setPresetIndex((i) => (i - 1 + PRESETS.length) % PRESETS.length);
200
- }
201
- else if (key.downArrow) {
202
- setPresetIndex((i) => (i + 1) % PRESETS.length);
203
- }
204
- else if (key.return) {
205
- enterStep('baseURL');
206
- }
207
- return;
208
- }
209
- if (step === 'baseURL') {
210
- if (key.return) {
211
- if (draft.trim().length === 0)
212
- return;
213
- setBaseURL(draft.trim());
214
- enterStep('apiKey');
215
- }
216
- else if (key.backspace || key.delete) {
217
- setDraft((s) => s.slice(0, -1));
218
- }
219
- else if (input && !key.meta && !key.ctrl) {
220
- setDraft((s) => s + input);
221
- }
222
- return;
223
- }
224
- if (step === 'apiKey') {
225
- if (key.return) {
226
- if (draft.length === 0)
227
- return;
228
- setApiKey(draft);
229
- enterStep('model');
230
- }
231
- else if (key.backspace || key.delete) {
232
- setDraft((s) => s.slice(0, -1));
233
- }
234
- else if (input && !key.meta && !key.ctrl) {
235
- setDraft((s) => s + input);
236
- }
237
- return;
238
- }
239
- if (step === 'model') {
240
- if (preset.models.length > 0) {
241
- if (key.upArrow) {
242
- const ni = (modelIndex - 1 + preset.models.length) % preset.models.length;
243
- setModelIndex(ni);
244
- setDraft(preset.models[ni]);
245
- }
246
- else if (key.downArrow) {
247
- const ni = (modelIndex + 1) % preset.models.length;
248
- setModelIndex(ni);
249
- setDraft(preset.models[ni]);
250
- }
251
- else if (key.tab) {
252
- setDraft((s) => s + '');
253
- }
254
- }
255
- if (key.return) {
256
- const finalModel = draft.trim();
257
- if (finalModel.length === 0)
258
- return;
259
- setModel(finalModel);
260
- void handleTest(finalModel);
261
- }
262
- else if (key.backspace || key.delete) {
263
- setDraft((s) => s.slice(0, -1));
264
- }
265
- else if (input && !key.meta && !key.ctrl && !key.upArrow && !key.downArrow) {
266
- setDraft((s) => s + input);
267
- }
268
- return;
269
- }
270
- if (step === 'tavily') {
271
- if (key.return) {
272
- // 空 draft 表示用户跳过 WebSearch 配置(合法路径,不报错)
273
- const tavilyApiKey = draft.trim().length > 0 ? draft.trim() : undefined;
274
- void finalize(model, tavilyApiKey);
275
- }
276
- else if (key.backspace || key.delete) {
277
- setDraft((s) => s.slice(0, -1));
278
- }
279
- else if (input && !key.meta && !key.ctrl) {
280
- setDraft((s) => s + input);
281
- }
282
- return;
283
- }
284
- if (step === 'error') {
285
- if (key.return) {
286
- enterStep('preset');
287
- }
288
- return;
289
- }
290
- });
291
- const maskedApiKey = useMemo(() => '*'.repeat(Math.min(draft.length, 32)), [draft]);
292
- return (_jsxs(Box, { flexDirection: "column", paddingX: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: "cyan", bold: true, children: "minimal-agent \u00B7 \u9996\u6B21\u914D\u7F6E\u5411\u5BFC" }) }), _jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: "gray", children: "\u6309 ESC \u6216 Ctrl+C \u9000\u51FA\uFF08\u4E0D\u5199\u914D\u7F6E\uFF0C\u4E0B\u6B21\u542F\u52A8\u7EE7\u7EED\u5411\u5BFC\uFF09" }) }), step === 'preset' && (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { children: "Step 1/5 \u00B7 \u9009\u62E9 provider \u9884\u8BBE\uFF08\u2191\u2193 \u79FB\u52A8\uFF0CEnter \u786E\u8BA4\uFF09" }), _jsx(Box, { flexDirection: "column", marginTop: 1, children: PRESETS.map((p, i) => (_jsxs(Text, { color: i === presetIndex ? 'cyan' : undefined, children: [i === presetIndex ? '> ' : ' ', p.label, p.baseURL ? ` (${p.baseURL})` : ''] }, p.name))) })] })), step === 'baseURL' && (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { children: "Step 2/5 \u00B7 \u8F93\u5165 API base URL\uFF08\u9ED8\u8BA4\u4E3A\u9884\u8BBE\u503C\uFF0C\u53EF\u6539\uFF09" }), _jsx(Box, { marginTop: 1, borderStyle: "round", borderColor: "cyan", paddingX: 1, children: _jsx(Text, { children: draft || ' ' }) }), _jsx(Text, { color: "gray", children: "Enter \u786E\u8BA4 \u00B7 Backspace \u5220\u9664" })] })), step === 'apiKey' && (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { children: "Step 3/5 \u00B7 \u8F93\u5165 API key\uFF08\u8F93\u5165\u5185\u5BB9\u4E0D\u4F1A\u663E\u793A\uFF09" }), _jsx(Box, { marginTop: 1, borderStyle: "round", borderColor: "cyan", paddingX: 1, children: _jsx(Text, { children: maskedApiKey || ' ' }) }), _jsxs(Text, { color: "gray", children: ["Enter \u786E\u8BA4 \u00B7 Backspace \u5220\u9664\uFF08\u5DF2\u8F93\u5165 ", draft.length, " \u5B57\u7B26\uFF09"] })] })), step === 'model' && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { children: ["Step 4/5 \u00B7 \u8F93\u5165\u6216\u9009\u62E9 model", preset.models.length > 0 ? '(↑↓ 切换预设,或直接编辑)' : ''] }), preset.models.length > 0 && (_jsx(Box, { flexDirection: "column", marginTop: 1, children: preset.models.map((m, i) => (_jsxs(Text, { color: i === modelIndex ? 'cyan' : 'gray', children: [i === modelIndex ? '> ' : ' ', m] }, m))) })), _jsx(Box, { marginTop: 1, borderStyle: "round", borderColor: "cyan", paddingX: 1, children: _jsx(Text, { children: draft || ' ' }) }), _jsx(Text, { color: "gray", children: "Enter \u63D0\u4EA4\u5E76\u6D4B\u8BD5\u8FDE\u63A5" })] })), step === 'testing' && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: "yellow", children: ["\u23F3 \u6B63\u5728\u6D4B\u8BD5\u8FDE\u63A5 ", baseURL, " ..."] }), _jsxs(Text, { color: "gray", children: ["model = ", model] })] })), step === 'tavily' && (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: "green", children: "\u2713 LLM \u8FDE\u63A5\u6D4B\u8BD5\u901A\u8FC7" }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { children: "Step 5/5 \u00B7 \u53EF\u9009 - Tavily API key\uFF08\u7528\u4E8E WebSearch \u5DE5\u5177\uFF09" }) }), _jsx(Box, { marginTop: 1, borderStyle: "round", borderColor: "cyan", paddingX: 1, children: _jsx(Text, { children: maskedApiKey || ' ' }) }), _jsx(Text, { color: "gray", children: "\u76F4\u63A5 Enter \u8DF3\u8FC7\uFF08\u4E4B\u540E\u53EF\u5728\u5BF9\u8BDD\u91CC\u8F93\u5165 /config \u6DFB\u52A0\uFF0C\u6216\u8BBE env TAVILY_API_KEY\uFF09" }), _jsxs(Text, { color: "gray", children: ["\u514D\u8D39 key \u7533\u8BF7\uFF1Ahttps://tavily.com/ \u00B7 \u5DF2\u8F93\u5165 ", draft.length, " \u5B57\u7B26"] })] })), step === 'error' && (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: "red", children: "\u2717 \u8FDE\u63A5\u6D4B\u8BD5\u5931\u8D25" }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "red", children: errorMsg ?? '未知错误' }) }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "gray", children: "\u5DF2\u8F93\u5165\uFF1A" }) }), _jsxs(Text, { color: "gray", children: [" provider = ", preset.name] }), _jsxs(Text, { color: "gray", children: [" baseURL = ", baseURL] }), _jsxs(Text, { color: "gray", children: [" model = ", model] }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "yellow", children: "\u6309 Enter \u56DE\u5230 Step 1 \u91CD\u8BD5 \u00B7 ESC \u9000\u51FA" }) })] }))] }));
293
- }
@@ -1,48 +0,0 @@
1
- /**
2
- * ============================================================
3
- * src/tools/toolProgressBridge.ts —— 长时工具的「步内进度」宿主桥
4
- * ------------------------------------------------------------
5
- * 仿 askBridge 的宿主交互桥模式(全局 handler 注册表):
6
- * 长时工具(GenerateImage 批量生图,单步可达 10-30 分钟)在执行**中途**把
7
- * 逐项进度行发布出来,有 UI 的宿主(TUI useChat)订阅后实时上屏——
8
- * 否则整步在 LiveArea 上只有一行静态描述,十几分钟毫无变化,
9
- * 用户必然误判死机(2026-07-02 真实事故:31 张生图 ~13 分钟被当成卡死,
10
- * 差点手杀健康运行)。
11
- *
12
- * 两种宿主:
13
- * - TUI:useChat mount 时 setToolProgressHandler() 注册,更新 runningTools
14
- * 对应条目的 progress 字段 → LiveArea tool_executing 行实时显示。
15
- * - 非交互(`-p` / gateway / 子进程):没有 handler → publish 是 no-op,
16
- * 零副作用(进度对结构化结局契约不可见,不污染 stdout/stderr)。
17
- *
18
- * 工具侧只依赖本模块,不 import ui/(与 askBridge 同样的中立位置理由:
19
- * 它是工具与宿主之间的中介,避免 tools → ui 反向耦合)。
20
- * ============================================================
21
- */
22
- let handler = null;
23
- /**
24
- * 注册 / 注销宿主处理器。
25
- * TUI 的 useChat 在 mount 时注册、unmount 时传 null 注销。
26
- * 单进程单 UI,模块级单例即可(与 askBridge 一致)。
27
- */
28
- export function setToolProgressHandler(h) {
29
- handler = h;
30
- }
31
- /** 是否有宿主在场(测试 / 诊断用)。 */
32
- export function hasToolProgressHandler() {
33
- return handler !== null;
34
- }
35
- /**
36
- * 发布一条进度行。无 handler 时 no-op;handler 抛异常也吞掉——
37
- * 进度是锦上添花,绝不能让 UI 侧的 bug 反噬工具执行。
38
- */
39
- export function publishToolProgress(toolName, line) {
40
- if (!handler)
41
- return;
42
- try {
43
- handler(toolName, line);
44
- }
45
- catch {
46
- /* 进度上屏失败不阻断工具 */
47
- }
48
- }
@@ -1,50 +0,0 @@
1
- name: adaptive-research
2
- description: |
3
- 演示「受工作流指导的 TAOR」:确定性骨架 + 两处随机应变。
4
- - research 步是 agent: 节点 —— 把一个开放任务(调研主题、整理笔记落盘)交给有界子 agent
5
- 自主用工具完成(思考→搜→写→自我验证)。
6
- - count_lines 步是确定性 tool,但声明 onError: recover —— 万一路径/前置不对,
7
- 不整条崩,临时起恢复 agent 把这一步救回。
8
- 最后 assert 守门。这就是「指导 + 随机应变」按节点滑动的旋钮。
9
- version: "0.1"
10
-
11
- inputs:
12
- - name: topic
13
- type: string
14
- required: true
15
- greedy: true
16
- description: "调研主题(可直接一句话自然语言;命令行整句进 topic,不被空格拆碎)"
17
-
18
- steps:
19
- # 1. agent 节点:开放式调研,自主决定怎么做,产出笔记并自我验证
20
- - id: research
21
- title: "1/3·自主调研写笔记"
22
- agent: |
23
- 调研主题「${inputs.topic}」:用你手上的工具搜集 3-5 个关键要点,
24
- 整理成简洁的中文 markdown,写到 ./out/notes.md(目录不存在就先创建)。
25
- 写完后用 Read 自检文件确实写好了再收尾。
26
- allowed_tools: [Read, Write, Edit, Bash, Grep, Glob]
27
- # 确定性完成条件:模型「宣告要写却没写」时引擎自动提醒续跑(announce-not-do 兜底)
28
- done_when: "fileExists('./out/notes.md')"
29
- capture:
30
- # agent 步 raw 只有 text/result(无 content)——曾绑 content 导致 notes 恒 undefined
31
- text: notes
32
-
33
- # 2. 确定性工具,但带 onError: recover —— 出意外就地自愈,而非崩停
34
- - id: count_lines
35
- title: "2/3·统计笔记行数"
36
- tool: Bash
37
- args:
38
- command: "wc -l ./out/notes.md"
39
- onError: recover
40
- recover_hint: "文件不存在或路径不对,就先用 Glob/Read 定位 notes.md 再统计行数"
41
- capture:
42
- content: line_report
43
-
44
- # 3. 守门 verify(升级自 assert,享受 verify 的 file_exists 检查器)
45
- - id: verify
46
- title: "3/3·守门校验"
47
- type: verify
48
- checks:
49
- - 'file_exists:./out/notes.md'
50
- onFail: "调研笔记 ./out/notes.md 未生成,检查 research 步"