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
@@ -0,0 +1,46 @@
1
+ export type ComputerAutomationIntent =
2
+ | { needed: true; source: 'explicit-current' | 'continuation'; reason: string }
3
+ | { needed: false; source: 'none'; reason: string };
4
+
5
+ export interface ComputerAutomationContinuationState {
6
+ lastUsedAt: number;
7
+ }
8
+
9
+ const CONTINUATION_WINDOW_MS = 30 * 60_000;
10
+ const CONTINUATION_ONLY = /^(?:请)?(?:继续|接着(?:做|操作)?|重试|再试一次|往下做|恢复操作)[。!!\s]*$/i;
11
+ const DIRECT_DESKTOP = /(?:操作(?:电脑|桌面|屏幕|窗口|系统|本机)|电脑自动化|桌面自动化|查看(?:当前)?(?:桌面|屏幕|前台窗口)|截(?:取)?(?:当前)?屏|系统设置|控制面板|任务管理器|资源管理器|访达|Finder)/i;
12
+ const GUI_ACTION = /(?:点击|双击|右键|拖拽|滚动|输入|粘贴|按(?:键|快捷键)|切换|激活|关闭|移动|调整窗口|发送|发布|上传)/i;
13
+ const APP_TARGET = /(?:在|用|打开|切换到|进入)[^,。\n]{0,28}(?:应用|软件|客户端|微信|WeChat|钉钉|飞书|Slack|QQ|邮件|Outlook|Word|Excel|PowerPoint|设置|窗口)(?:里|中|上|内|给|向|并|,|。|\s|$)/i;
14
+ const DISCUSSION_ONLY = /(?:解释|介绍|讨论|分析|评审|代码|源码|实现|设计|为什么|是什么|如何实现|测试.*ComputerUse|ComputerUse.*测试)/i;
15
+ const DIRECT_TOOL_TASK = /(?:读取|分析|查看|理解).{0,12}(?:图片|照片|截图文件|PDF|文件|附件)|(?:搜索|修改|编写|重构|构建|运行测试|查找).{0,12}(?:代码|文件|网页)|(?:搜索网页|打开网址|访问网站|网页中)/i;
16
+
17
+ /**
18
+ * Conservative, deterministic exposure classifier. It only consumes the
19
+ * current human input and a short-lived record of a real prior ComputerUse
20
+ * call; model output, page content, and tool arguments can never enable it.
21
+ */
22
+ export function classifyComputerAutomationIntent(
23
+ input: string,
24
+ continuation?: ComputerAutomationContinuationState,
25
+ now = Date.now(),
26
+ ): ComputerAutomationIntent {
27
+ const text = input.trim();
28
+ if (
29
+ continuation
30
+ && now - continuation.lastUsedAt <= CONTINUATION_WINDOW_MS
31
+ && CONTINUATION_ONLY.test(text)
32
+ ) {
33
+ return { needed: true, source: 'continuation', reason: '继续最近一次桌面自动化任务' };
34
+ }
35
+ if (!text) return { needed: false, source: 'none', reason: '没有桌面操作请求' };
36
+ if (DIRECT_TOOL_TASK.test(text) && !DIRECT_DESKTOP.test(text)) {
37
+ return { needed: false, source: 'none', reason: '专用文件、图片或 Web 工具可直接完成' };
38
+ }
39
+ if (DISCUSSION_ONLY.test(text) && !DIRECT_DESKTOP.test(text) && !GUI_ACTION.test(text)) {
40
+ return { needed: false, source: 'none', reason: '仅讨论桌面能力,没有要求实际操作' };
41
+ }
42
+ if (DIRECT_DESKTOP.test(text) || (GUI_ACTION.test(text) && APP_TARGET.test(text))) {
43
+ return { needed: true, source: 'explicit-current', reason: '用户明确要求操作原生桌面界面' };
44
+ }
45
+ return { needed: false, source: 'none', reason: '未发现明确的原生桌面操作意图' };
46
+ }
@@ -28,6 +28,9 @@ import { CONSECUTIVE_FAILURE_LIMIT, readRecords, record, renderReport, summarize
28
28
  function logPath() {
29
29
  return join(computerUseStateDir(), 'telemetry.jsonl');
30
30
  }
31
+ function exposureLogPath() {
32
+ return join(computerUseStateDir(), 'exposure.jsonl');
33
+ }
31
34
  /**
32
35
  * 记一条调用元数据。
33
36
  *
@@ -42,6 +45,15 @@ export async function recordComputerUseCall(raw) {
42
45
  /* 观测失败不影响功能 */
43
46
  }
44
47
  }
48
+ /** Records only the boolean exposure decision and a bounded enum source. */
49
+ export async function recordComputerUseExposure(exposed, intentSource) {
50
+ try {
51
+ await record(exposureLogPath(), { exposed, intentSource });
52
+ }
53
+ catch {
54
+ /* observability must never affect a turn */
55
+ }
56
+ }
45
57
  export { CONSECUTIVE_FAILURE_LIMIT };
46
58
  /**
47
59
  * 人类可读的遥测汇总,给 CLI/诊断用。
@@ -38,6 +38,10 @@ function logPath(): string {
38
38
  return join(computerUseStateDir(), 'telemetry.jsonl');
39
39
  }
40
40
 
41
+ function exposureLogPath(): string {
42
+ return join(computerUseStateDir(), 'exposure.jsonl');
43
+ }
44
+
41
45
  /**
42
46
  * 记一条调用元数据。
43
47
  *
@@ -52,6 +56,18 @@ export async function recordComputerUseCall(raw: Record<string, unknown>): Promi
52
56
  }
53
57
  }
54
58
 
59
+ /** Records only the boolean exposure decision and a bounded enum source. */
60
+ export async function recordComputerUseExposure(
61
+ exposed: boolean,
62
+ intentSource: 'explicit-current' | 'continuation' | 'none',
63
+ ): Promise<void> {
64
+ try {
65
+ await record(exposureLogPath(), { exposed, intentSource });
66
+ } catch {
67
+ /* observability must never affect a turn */
68
+ }
69
+ }
70
+
55
71
  export { CONSECUTIVE_FAILURE_LIMIT };
56
72
 
57
73
  /**
@@ -30,6 +30,7 @@ const ALLOWED_FIELDS = new Set([
30
30
  'changeRatio', 'settled', 'stableMs', 'settleConfidence', 'focusChange',
31
31
  'settleMode', 'interrupted', 'refused', 'ok',
32
32
  'frames', 'axNodes', 'axTruncated',
33
+ 'exposed', 'intentSource',
33
34
  // 不可逆动作审批的结局(短枚举,如 irreversible_approved / irreversible_denied)。
34
35
  //
35
36
  // 刻意**不**复用 `refused`:那个字段参与连续失败计数,而「用户不批准这次
@@ -33,6 +33,7 @@ const ALLOWED_FIELDS = new Set([
33
33
  'changeRatio', 'settled', 'stableMs', 'settleConfidence', 'focusChange',
34
34
  'settleMode', 'interrupted', 'refused', 'ok',
35
35
  'frames', 'axNodes', 'axTruncated',
36
+ 'exposed', 'intentSource',
36
37
  // 不可逆动作审批的结局(短枚举,如 irreversible_approved / irreversible_denied)。
37
38
  //
38
39
  // 刻意**不**复用 `refused`:那个字段参与连续失败计数,而「用户不批准这次
@@ -29,9 +29,13 @@ export function createEffectiveToolSet(input) {
29
29
  input.runtime.cwd,
30
30
  input.runtime.surface,
31
31
  input.runtime.profile,
32
+ input.runtime.conversationMode ?? 'private',
32
33
  input.runtime.memoryAccess,
33
34
  input.runtime.browser?.supervised === true ? 'supervised-browser' : 'no-browser',
34
35
  input.runtime.computer ? 'computer' : 'no-computer',
36
+ input.runtime.computerIntent?.needed === true
37
+ ? `computer-intent:${input.runtime.computerIntent.source}`
38
+ : 'no-computer-intent',
35
39
  input.availableTools.map(identity).join(','),
36
40
  availability.join(','),
37
41
  input.allowedNames?.join(',') ?? '*',
@@ -46,9 +46,13 @@ export function createEffectiveToolSet(input: {
46
46
  input.runtime.cwd,
47
47
  input.runtime.surface,
48
48
  input.runtime.profile,
49
+ input.runtime.conversationMode ?? 'private',
49
50
  input.runtime.memoryAccess,
50
51
  input.runtime.browser?.supervised === true ? 'supervised-browser' : 'no-browser',
51
52
  input.runtime.computer ? 'computer' : 'no-computer',
53
+ input.runtime.computerIntent?.needed === true
54
+ ? `computer-intent:${input.runtime.computerIntent.source}`
55
+ : 'no-computer-intent',
52
56
  input.availableTools.map(identity).join(','),
53
57
  availability.join(','),
54
58
  input.allowedNames?.join(',') ?? '*',
@@ -13,10 +13,13 @@
13
13
  * ============================================================
14
14
  */
15
15
  import { advisorTool } from './advisor/advisor.js';
16
+ import { advisorDecisionTool } from './advisor/advisorDecision.js';
17
+ import { applyPatchTool } from './applypatch/applyPatch.js';
16
18
  // ⚠️ agent.ts 与本模块构成环(tools/index → agent → loop → tools/index):
17
19
  // agent.ts 顶层不求值本模块/loop 的任何导出、loop.ts 的工具 token 估算已懒化,
18
20
  // 环在运行时是安全的(详见 agent.ts 文件头「循环依赖纪律」)。
19
21
  import { agentTool } from './agent/agent.js';
22
+ import { agentFollowupTool, agentInterruptTool, agentListTool, agentMessageTool, agentWaitTool, } from './agent/agentControl.js';
20
23
  import { askUserQuestionTool } from './ask/ask.js';
21
24
  import { bashTool } from './bash/bash.js';
22
25
  import { assertCapabilityRegistry } from './capabilities.js';
@@ -40,14 +43,17 @@ import { taskCreateTool, taskGetTool, taskListTool, taskUpdateTool, } from './ta
40
43
  import { taskOutputTool } from './tasks/taskOutput.js';
41
44
  import { taskStopTool } from './tasks/taskStop.js';
42
45
  import { terminalCaptureTool } from './terminal/terminalCapture.js';
46
+ import { attachBuiltinPromptGuides } from './toolPromptGuides.js';
43
47
  import { trashTool } from './trash/trash.js';
44
48
  import { webbrowserTool } from './webbrowser/webbrowser.js';
49
+ import { browserBatchTool } from './webbrowser/browserBatch.js';
50
+ import { browserCdpTool } from './webbrowser/browserCdp.js';
45
51
  import { webfetchTool } from './webfetch/webfetch.js';
46
52
  import { webSearchTool } from './websearch/websearch.js';
47
53
  import { enterWorktreeTool, exitWorktreeTool, } from './worktree/sessionWorktree.js';
48
54
  import { writeTool } from './write/write.js';
49
55
  /** 所有内置工具(顺序 = 给 LLM 呈现的顺序,不影响代码执行,但会影响模型的优先级直觉) */
50
- export const ALL_TOOLS = [
56
+ export const ALL_TOOLS = attachBuiltinPromptGuides([
51
57
  readTool,
52
58
  editTool,
53
59
  multiEditTool,
@@ -79,9 +85,15 @@ export const ALL_TOOLS = [
79
85
  taskStopTool,
80
86
  askUserQuestionTool,
81
87
  advisorTool,
88
+ advisorDecisionTool,
82
89
  computerUseTool,
83
90
  // 追加在末尾:主循环 tools schema 的原有前缀字节不动(提示词缓存友好)
84
91
  agentTool,
92
+ agentMessageTool,
93
+ agentListTool,
94
+ agentWaitTool,
95
+ agentInterruptTool,
96
+ agentFollowupTool,
85
97
  // Product tools append at the end to preserve the existing schema prefix cache.
86
98
  trashTool,
87
99
  taskCreateTool,
@@ -93,7 +105,11 @@ export const ALL_TOOLS = [
93
105
  exitWorktreeTool,
94
106
  terminalCaptureTool,
95
107
  snipTool,
96
- ];
108
+ applyPatchTool,
109
+ // Browser extensions append after the stable legacy schema prefix.
110
+ browserBatchTool,
111
+ browserCdpTool,
112
+ ]);
97
113
  assertCapabilityRegistry(ALL_TOOLS.map((tool) => tool.name));
98
114
  /** 按名字查表 */
99
115
  export function getToolByName(name) {
@@ -197,7 +213,10 @@ export { clearPersonaTool, confirmMemoryTool, forgetMemoryTool, listMemoriesTool
197
213
  export { multiEditTool } from './edit/multi-edit.js';
198
214
  export { genImageTool } from './genimage/genimage.js';
199
215
  export { advisorTool } from './advisor/advisor.js';
216
+ export { advisorDecisionTool } from './advisor/advisorDecision.js';
217
+ export { applyPatchTool } from './applypatch/applyPatch.js';
200
218
  export { agentTool } from './agent/agent.js';
219
+ export { agentFollowupTool, agentInterruptTool, agentListTool, agentMessageTool, agentWaitTool, } from './agent/agentControl.js';
201
220
  export { createGenerateSpeechTool, generateSpeechTool, } from './genspeech/genspeech.js';
202
221
  export { createWebSearchTool } from './websearch/websearch.js';
203
222
  export { lspTool } from './lsp/lsp.js';
@@ -15,10 +15,19 @@
15
15
 
16
16
  import type { Tool, ToolCallContext, ToolResult } from '../types.js';
17
17
  import { advisorTool } from './advisor/advisor.js';
18
+ import { advisorDecisionTool } from './advisor/advisorDecision.js';
19
+ import { applyPatchTool } from './applypatch/applyPatch.js';
18
20
  // ⚠️ agent.ts 与本模块构成环(tools/index → agent → loop → tools/index):
19
21
  // agent.ts 顶层不求值本模块/loop 的任何导出、loop.ts 的工具 token 估算已懒化,
20
22
  // 环在运行时是安全的(详见 agent.ts 文件头「循环依赖纪律」)。
21
23
  import { agentTool } from './agent/agent.js';
24
+ import {
25
+ agentFollowupTool,
26
+ agentInterruptTool,
27
+ agentListTool,
28
+ agentMessageTool,
29
+ agentWaitTool,
30
+ } from './agent/agentControl.js';
22
31
  import { askUserQuestionTool } from './ask/ask.js';
23
32
  import { bashTool } from './bash/bash.js';
24
33
  import { assertCapabilityRegistry } from './capabilities.js';
@@ -58,8 +67,11 @@ import {
58
67
  import { taskOutputTool } from './tasks/taskOutput.js';
59
68
  import { taskStopTool } from './tasks/taskStop.js';
60
69
  import { terminalCaptureTool } from './terminal/terminalCapture.js';
70
+ import { attachBuiltinPromptGuides } from './toolPromptGuides.js';
61
71
  import { trashTool } from './trash/trash.js';
62
72
  import { webbrowserTool } from './webbrowser/webbrowser.js';
73
+ import { browserBatchTool } from './webbrowser/browserBatch.js';
74
+ import { browserCdpTool } from './webbrowser/browserCdp.js';
63
75
  import { webfetchTool } from './webfetch/webfetch.js';
64
76
  import { webSearchTool } from './websearch/websearch.js';
65
77
  import {
@@ -69,7 +81,7 @@ import {
69
81
  import { writeTool } from './write/write.js';
70
82
 
71
83
  /** 所有内置工具(顺序 = 给 LLM 呈现的顺序,不影响代码执行,但会影响模型的优先级直觉) */
72
- export const ALL_TOOLS: Tool[] = [
84
+ export const ALL_TOOLS: Tool[] = attachBuiltinPromptGuides([
73
85
  readTool,
74
86
  editTool,
75
87
  multiEditTool,
@@ -101,9 +113,15 @@ export const ALL_TOOLS: Tool[] = [
101
113
  taskStopTool,
102
114
  askUserQuestionTool,
103
115
  advisorTool,
116
+ advisorDecisionTool,
104
117
  computerUseTool,
105
118
  // 追加在末尾:主循环 tools schema 的原有前缀字节不动(提示词缓存友好)
106
119
  agentTool,
120
+ agentMessageTool,
121
+ agentListTool,
122
+ agentWaitTool,
123
+ agentInterruptTool,
124
+ agentFollowupTool,
107
125
  // Product tools append at the end to preserve the existing schema prefix cache.
108
126
  trashTool,
109
127
  taskCreateTool,
@@ -115,7 +133,11 @@ export const ALL_TOOLS: Tool[] = [
115
133
  exitWorktreeTool,
116
134
  terminalCaptureTool,
117
135
  snipTool,
118
- ];
136
+ applyPatchTool,
137
+ // Browser extensions append after the stable legacy schema prefix.
138
+ browserBatchTool,
139
+ browserCdpTool,
140
+ ]);
119
141
 
120
142
  assertCapabilityRegistry(ALL_TOOLS.map((tool) => tool.name));
121
143
 
@@ -263,7 +285,16 @@ export {
263
285
  export { multiEditTool } from './edit/multi-edit.js';
264
286
  export { genImageTool } from './genimage/genimage.js';
265
287
  export { advisorTool } from './advisor/advisor.js';
288
+ export { advisorDecisionTool } from './advisor/advisorDecision.js';
289
+ export { applyPatchTool } from './applypatch/applyPatch.js';
266
290
  export { agentTool } from './agent/agent.js';
291
+ export {
292
+ agentFollowupTool,
293
+ agentInterruptTool,
294
+ agentListTool,
295
+ agentMessageTool,
296
+ agentWaitTool,
297
+ } from './agent/agentControl.js';
267
298
  export {
268
299
  createGenerateSpeechTool,
269
300
  generateSpeechTool,
@@ -91,21 +91,12 @@ async function call(input) {
91
91
  return { ok: false, error: '网页结果只支持 http 或 https 链接' };
92
92
  }
93
93
  const hasFailedFile = files.some((file) => file.verification === 'failed');
94
- const allFilesVerified = files.length > 0 && files.every((file) => file.verification === 'passed');
95
- // `final` means the result is safe to present as the completed delivery. A file
96
- // with `not_run` verification is still useful, but it must remain an honest draft.
97
- const status = hasFailedFile
98
- ? 'draft'
99
- : allFilesVerified
100
- ? 'final'
101
- : files.length === 0 && links.length > 0
102
- ? 'final'
103
- : 'draft';
104
- const warnings = files.some((file) => file.verification === 'not_run')
105
- ? ['文件已提交,但尚未通过结构化验证。']
106
- : hasFailedFile
107
- ? ['至少一个文件未通过结构化验证。']
108
- : [];
94
+ // `not_run` means no *additional* format/content validator was available. It
95
+ // is not a failed delivery: this tool has already verified that the file exists,
96
+ // is inside the workspace, and captured its size and SHA-256. Only an explicit
97
+ // failed validator should turn an otherwise usable result into a warning.
98
+ const status = hasFailedFile ? 'draft' : 'final';
99
+ const warnings = hasFailedFile ? ['至少一个文件未通过结构化验证。'] : [];
109
100
  const manifest = {
110
101
  status,
111
102
  summary: input.summary?.trim() || (files.length ? `已提交 ${files.length} 个文件` : `已提交 ${links.length} 个网页结果`),
@@ -101,21 +101,12 @@ async function call(input: PresentResultInput): Promise<ToolResult> {
101
101
  return { ok: false, error: '网页结果只支持 http 或 https 链接' };
102
102
  }
103
103
  const hasFailedFile = files.some((file) => file.verification === 'failed');
104
- const allFilesVerified = files.length > 0 && files.every((file) => file.verification === 'passed');
105
- // `final` means the result is safe to present as the completed delivery. A file
106
- // with `not_run` verification is still useful, but it must remain an honest draft.
107
- const status = hasFailedFile
108
- ? 'draft'
109
- : allFilesVerified
110
- ? 'final'
111
- : files.length === 0 && links.length > 0
112
- ? 'final'
113
- : 'draft';
114
- const warnings = files.some((file) => file.verification === 'not_run')
115
- ? ['文件已提交,但尚未通过结构化验证。']
116
- : hasFailedFile
117
- ? ['至少一个文件未通过结构化验证。']
118
- : [];
104
+ // `not_run` means no *additional* format/content validator was available. It
105
+ // is not a failed delivery: this tool has already verified that the file exists,
106
+ // is inside the workspace, and captured its size and SHA-256. Only an explicit
107
+ // failed validator should turn an otherwise usable result into a warning.
108
+ const status = hasFailedFile ? 'draft' : 'final';
109
+ const warnings = hasFailedFile ? ['至少一个文件未通过结构化验证。'] : [];
119
110
  const manifest: DeliverableManifest = {
120
111
  status,
121
112
  summary: input.summary?.trim() || (files.length ? `已提交 ${files.length} 个文件` : `已提交 ${links.length} 个网页结果`),
@@ -8,6 +8,7 @@ import { join } from 'node:path';
8
8
  import { promisify } from 'node:util';
9
9
  import { randomUUID } from 'node:crypto';
10
10
  import { z } from 'zod';
11
+ import { dlog } from '../../utils/debugLog.js';
11
12
  import { toToolParameters } from '../../utils/zodToJson.js';
12
13
  import { DEFAULT_MAX_RESULT_SIZE_CHARS, MAX_FILE_SIZE_BYTES, MAX_LINES_TO_READ, } from '../types.js';
13
14
  import { fileActivityMetadata } from '../shared/fileActivity.js';
@@ -15,6 +16,7 @@ import { hashFileBytes, recordRead, } from '../shared/fileState.js';
15
16
  import { hasBinaryExtension, isBlockedDevicePath, readTextFile, resolveToolPath, } from '../shared/fileUtils.js';
16
17
  import { filePathField } from '../shared/schemas.js';
17
18
  import { pruneRuntimeOutputs, sessionRuntimeDir, } from '../../session/runtimeStore.js';
19
+ import { detectImageMime, resolveLocalImage, } from '../../images/imageResolver.js';
18
20
  const inputSchema = z.object({
19
21
  file_path: filePathField('读取'),
20
22
  offset: z
@@ -46,6 +48,12 @@ const IMAGE_EXTENSIONS = new Set([
46
48
  '.gif',
47
49
  '.webp',
48
50
  '.bmp',
51
+ '.tif',
52
+ '.tiff',
53
+ '.avif',
54
+ '.heic',
55
+ '.heif',
56
+ '.svg',
49
57
  ]);
50
58
  const MAX_IMAGE_BYTES = 25 * 1024 * 1024;
51
59
  const MAX_NOTEBOOK_BYTES = 32 * 1024 * 1024;
@@ -225,16 +233,29 @@ async function call(input, state, cwd, runtimeIdentity) {
225
233
  };
226
234
  }
227
235
  }
228
- if (IMAGE_EXTENSIONS.has(ext)) {
236
+ const imageBytes = info.size <= MAX_IMAGE_BYTES
237
+ ? await readFile(filePath).catch(() => null)
238
+ : null;
239
+ const detectedImage = imageBytes ? detectImageMime(imageBytes) : null;
240
+ if (IMAGE_EXTENSIONS.has(ext) || detectedImage) {
229
241
  if (info.size > MAX_IMAGE_BYTES)
230
242
  return { ok: false, error: `图片超过 ${MAX_IMAGE_BYTES} 字节上限` };
231
- const bytes = await readFile(filePath);
243
+ let resolvedImage;
244
+ try {
245
+ resolvedImage = await resolveLocalImage(filePath, {
246
+ maxInputBytes: MAX_IMAGE_BYTES,
247
+ });
248
+ }
249
+ catch (error) {
250
+ return { ok: false, error: `图片读取失败:${error.message}` };
251
+ }
252
+ const bytes = imageBytes ?? await readFile(filePath);
232
253
  recordRead(filePath, { contentHash: hashFileBytes(bytes) }, state);
233
254
  return {
234
255
  ok: true,
235
- content: `已读取图片:${filePath}(${info.size} 字节)。图像已附加供视觉模型检查;非视觉模型只能确认文件元数据,不能解读像素内容。`,
256
+ content: `已读取图片:${filePath}(${info.size} 字节,实际格式 ${resolvedImage.originalMime})${resolvedImage.transformed ? `;已规范化为 ${resolvedImage.mime}` : ''}。图像已附加供视觉模型直接检查。`,
236
257
  metadata: await fileActivityMetadata(filePath, 'read', 'not_run', 'source', cwd),
237
- visionImages: [{ source: filePath }],
258
+ visionImages: [{ source: resolvedImage.path }],
238
259
  visionNote: '这是 Read 工具读取的本地图片,请直接检查图像内容。',
239
260
  };
240
261
  }
@@ -352,10 +373,30 @@ async function renderPdfPages(document, filePath, pages, identity) {
352
373
  const dynamicImport = new Function('specifier', 'return import(specifier)');
353
374
  let createCanvas;
354
375
  try {
355
- ({ createCanvas } = await dynamicImport('@napi-rs/canvas'));
376
+ const napi = await dynamicImport('@napi-rs/canvas');
377
+ createCanvas = napi.createCanvas;
378
+ // ⚠️ **必须在 pdfjs 之前把这几个全局占住**,否则 PDF 转图 100% 失败。
379
+ //
380
+ // pdfjs 的 legacy 构建在 Node 环境下自己往 globalThis 装一套 Path2D /
381
+ // DOMMatrix / ImageData polyfill。渲染时它 `new Path2D()` 拿到的是**它自己那份**,
382
+ // 转手调 `ctx.fill(path, 'evenodd')` 交给 @napi-rs/canvas —— 而 napi 的原生绑定
383
+ // 只认自己的 `Path`,于是每一页都抛
384
+ // `Value is none of these types \`String\`, \`Path\``
385
+ // 两份 polyfill 撞车,谁都没错,就是不是同一个对象。
386
+ //
387
+ // 实测:五种 render 参数组合(canvas / canvasContext / canvas:null / 带不带
388
+ // standardFontDataUrl)全部同样失败 —— 也就是说 `canvas` 那个类型错**不是**病因,
389
+ // 修类型并不能让它跑起来。把全局换成 napi 的实现之后第 1 页立刻渲染出 137KB PNG。
390
+ for (const name of ['Path2D', 'DOMMatrix', 'ImageData']) {
391
+ const impl = napi[name];
392
+ if (impl)
393
+ globalThis[name] = impl;
394
+ }
356
395
  }
357
- catch {
358
- /* optional adapter */
396
+ catch (e) {
397
+ // optional adapter:没装 @napi-rs/canvas 就回落 pdftoppm。
398
+ // 但「没装」和「装了却加载失败」对用户是两件事,别都吞成前者。
399
+ dlog('read:pdf', `@napi-rs/canvas 不可用:${e instanceof Error ? e.message : e}`);
359
400
  }
360
401
  if (createCanvas) {
361
402
  try {
@@ -363,8 +404,13 @@ async function renderPdfPages(document, filePath, pages, identity) {
363
404
  const page = await document.getPage(pageNumber);
364
405
  const viewport = page.getViewport({ scale: 2 });
365
406
  const canvas = createCanvas(Math.ceil(viewport.width), Math.ceil(viewport.height));
407
+ // ⚠️ pdfjs v6 的 RenderParameters 里 `canvas` 是**必填**、`canvasContext`
408
+ // 反而降级为可选且不推荐;文档明说「若必须用 context,canvas 必须为 null」。
409
+ // 只给 canvasContext 会类型不过(`bun run typecheck` 唯一的红)。
410
+ // 运行时它有默认值 `canvas = canvasContext.canvas` 所以不炸 —— 但类型要对。
366
411
  await page.render({
367
- canvas: canvas.getContext('2d'),
412
+ canvasContext: canvas.getContext('2d'),
413
+ canvas: null,
368
414
  viewport,
369
415
  }).promise;
370
416
  const target = join(outputDir, `${outputPrefix}-page-${pageNumber}.png`);
@@ -374,7 +420,14 @@ async function renderPdfPages(document, filePath, pages, identity) {
374
420
  void pruneRuntimeOutputs();
375
421
  return images;
376
422
  }
377
- catch {
423
+ catch (e) {
424
+ // ⚠️ 别把这里改回裸 catch。上面那个 Path2D 冲突就是被它藏住的:
425
+ // Canvas 每页都抛 → images 清空 → 回落 pdftoppm。装了 poppler 的机器照样
426
+ // 出图(只是分辨率更低、多一次进程),**完全看不出来**;没装 poppler 的机器
427
+ // (多数 Windows、绿色版 U 盘)则返回 `ok:true` + 0 张图 + 一句
428
+ // 「视觉渲染不可用(Canvas 与 pdftoppm 均不可用)」——而 Canvas 明明可用,
429
+ // 只是抛了。错误文案把人指向「装依赖」,真因一个字都查不到。
430
+ dlog('read:pdf', `Canvas 渲染失败:${e instanceof Error ? e.message : e}`);
378
431
  images.length = 0;
379
432
  }
380
433
  }
@@ -10,6 +10,7 @@ import { randomUUID } from 'node:crypto';
10
10
  import { z } from 'zod';
11
11
 
12
12
  import type { Tool, ToolCallContext, ToolResult } from '../../types.js';
13
+ import { dlog } from '../../utils/debugLog.js';
13
14
  import { toToolParameters } from '../../utils/zodToJson.js';
14
15
  import {
15
16
  DEFAULT_MAX_RESULT_SIZE_CHARS,
@@ -34,6 +35,10 @@ import {
34
35
  sessionRuntimeDir,
35
36
  type RuntimeIdentity,
36
37
  } from '../../session/runtimeStore.js';
38
+ import {
39
+ detectImageMime,
40
+ resolveLocalImage,
41
+ } from '../../images/imageResolver.js';
37
42
 
38
43
  const inputSchema = z.object({
39
44
  file_path: filePathField('读取'),
@@ -70,6 +75,12 @@ const IMAGE_EXTENSIONS = new Set([
70
75
  '.gif',
71
76
  '.webp',
72
77
  '.bmp',
78
+ '.tif',
79
+ '.tiff',
80
+ '.avif',
81
+ '.heic',
82
+ '.heif',
83
+ '.svg',
73
84
  ]);
74
85
  const MAX_IMAGE_BYTES = 25 * 1024 * 1024;
75
86
  const MAX_NOTEBOOK_BYTES = 32 * 1024 * 1024;
@@ -295,14 +306,26 @@ async function call(
295
306
  }
296
307
  }
297
308
 
298
- if (IMAGE_EXTENSIONS.has(ext)) {
309
+ const imageBytes = info.size <= MAX_IMAGE_BYTES
310
+ ? await readFile(filePath).catch(() => null)
311
+ : null;
312
+ const detectedImage = imageBytes ? detectImageMime(imageBytes) : null;
313
+ if (IMAGE_EXTENSIONS.has(ext) || detectedImage) {
299
314
  if (info.size > MAX_IMAGE_BYTES)
300
315
  return { ok: false, error: `图片超过 ${MAX_IMAGE_BYTES} 字节上限` };
301
- const bytes = await readFile(filePath);
316
+ let resolvedImage;
317
+ try {
318
+ resolvedImage = await resolveLocalImage(filePath, {
319
+ maxInputBytes: MAX_IMAGE_BYTES,
320
+ });
321
+ } catch (error) {
322
+ return { ok: false, error: `图片读取失败:${(error as Error).message}` };
323
+ }
324
+ const bytes = imageBytes ?? await readFile(filePath);
302
325
  recordRead(filePath, { contentHash: hashFileBytes(bytes) }, state);
303
326
  return {
304
327
  ok: true,
305
- content: `已读取图片:${filePath}(${info.size} 字节)。图像已附加供视觉模型检查;非视觉模型只能确认文件元数据,不能解读像素内容。`,
328
+ content: `已读取图片:${filePath}(${info.size} 字节,实际格式 ${resolvedImage.originalMime})${resolvedImage.transformed ? `;已规范化为 ${resolvedImage.mime}` : ''}。图像已附加供视觉模型直接检查。`,
306
329
  metadata: await fileActivityMetadata(
307
330
  filePath,
308
331
  'read',
@@ -310,7 +333,7 @@ async function call(
310
333
  'source',
311
334
  cwd,
312
335
  ),
313
- visionImages: [{ source: filePath }],
336
+ visionImages: [{ source: resolvedImage.path }],
314
337
  visionNote: '这是 Read 工具读取的本地图片,请直接检查图像内容。',
315
338
  };
316
339
  }
@@ -475,9 +498,28 @@ async function renderPdfPages(
475
498
  }>;
476
499
  let createCanvas: Awaited<ReturnType<typeof dynamicImport>>['createCanvas'];
477
500
  try {
478
- ({ createCanvas } = await dynamicImport('@napi-rs/canvas'));
479
- } catch {
480
- /* optional adapter */
501
+ const napi = await dynamicImport('@napi-rs/canvas');
502
+ createCanvas = napi.createCanvas;
503
+ // ⚠️ **必须在 pdfjs 之前把这几个全局占住**,否则 PDF 转图 100% 失败。
504
+ //
505
+ // pdfjs 的 legacy 构建在 Node 环境下自己往 globalThis 装一套 Path2D /
506
+ // DOMMatrix / ImageData polyfill。渲染时它 `new Path2D()` 拿到的是**它自己那份**,
507
+ // 转手调 `ctx.fill(path, 'evenodd')` 交给 @napi-rs/canvas —— 而 napi 的原生绑定
508
+ // 只认自己的 `Path`,于是每一页都抛
509
+ // `Value is none of these types \`String\`, \`Path\``
510
+ // 两份 polyfill 撞车,谁都没错,就是不是同一个对象。
511
+ //
512
+ // 实测:五种 render 参数组合(canvas / canvasContext / canvas:null / 带不带
513
+ // standardFontDataUrl)全部同样失败 —— 也就是说 `canvas` 那个类型错**不是**病因,
514
+ // 修类型并不能让它跑起来。把全局换成 napi 的实现之后第 1 页立刻渲染出 137KB PNG。
515
+ for (const name of ['Path2D', 'DOMMatrix', 'ImageData'] as const) {
516
+ const impl = (napi as Record<string, unknown>)[name];
517
+ if (impl) (globalThis as Record<string, unknown>)[name] = impl;
518
+ }
519
+ } catch (e) {
520
+ // optional adapter:没装 @napi-rs/canvas 就回落 pdftoppm。
521
+ // 但「没装」和「装了却加载失败」对用户是两件事,别都吞成前者。
522
+ dlog('read:pdf', `@napi-rs/canvas 不可用:${e instanceof Error ? e.message : e}`);
481
523
  }
482
524
  if (createCanvas) {
483
525
  try {
@@ -488,8 +530,13 @@ async function renderPdfPages(
488
530
  Math.ceil(viewport.width),
489
531
  Math.ceil(viewport.height),
490
532
  );
533
+ // ⚠️ pdfjs v6 的 RenderParameters 里 `canvas` 是**必填**、`canvasContext`
534
+ // 反而降级为可选且不推荐;文档明说「若必须用 context,canvas 必须为 null」。
535
+ // 只给 canvasContext 会类型不过(`bun run typecheck` 唯一的红)。
536
+ // 运行时它有默认值 `canvas = canvasContext.canvas` 所以不炸 —— 但类型要对。
491
537
  await page.render({
492
- canvas: canvas.getContext('2d') as unknown as Parameters<typeof page.render>[0]['canvas'],
538
+ canvasContext: canvas.getContext('2d') as never,
539
+ canvas: null,
493
540
  viewport,
494
541
  }).promise;
495
542
  const target = join(
@@ -501,7 +548,14 @@ async function renderPdfPages(
501
548
  }
502
549
  void pruneRuntimeOutputs();
503
550
  return images;
504
- } catch {
551
+ } catch (e) {
552
+ // ⚠️ 别把这里改回裸 catch。上面那个 Path2D 冲突就是被它藏住的:
553
+ // Canvas 每页都抛 → images 清空 → 回落 pdftoppm。装了 poppler 的机器照样
554
+ // 出图(只是分辨率更低、多一次进程),**完全看不出来**;没装 poppler 的机器
555
+ // (多数 Windows、绿色版 U 盘)则返回 `ok:true` + 0 张图 + 一句
556
+ // 「视觉渲染不可用(Canvas 与 pdftoppm 均不可用)」——而 Canvas 明明可用,
557
+ // 只是抛了。错误文案把人指向「装依赖」,真因一个字都查不到。
558
+ dlog('read:pdf', `Canvas 渲染失败:${e instanceof Error ? e.message : e}`);
505
559
  images.length = 0;
506
560
  }
507
561
  }
@@ -115,7 +115,7 @@ export function applyLineEnding(content, ending) {
115
115
  // -------------------- 3.5 二进制扩展名拦截 --------------------
116
116
  // 上游 D:\code\kakadeai\constants\files.ts:5-112 BINARY_EXTENSIONS Set 的裁剪版:
117
117
  // 故意剔除 .log / .csv / .tsv / .dat / .data / .lock —— 这些经常被人当文本读。
118
- // 保留纯二进制:图片 / 文档 / 可执行 / 编译产物 / 压缩包 / 多媒体 / 字体 / 数据库 / wasm。
118
+ // 保留纯二进制:图片 / 文档 / 可执行 / 编译产物 / 压缩包 / 多媒体 / 字体 / wasm。
119
119
  export const BINARY_EXTENSIONS = new Set([
120
120
  '.png', '.jpg', '.jpeg', '.gif', '.webp', '.bmp', '.ico', '.tiff', '.tif',
121
121
  '.pdf', '.doc', '.docx', '.xls', '.xlsx', '.ppt', '.pptx',
@@ -124,7 +124,6 @@ export const BINARY_EXTENSIONS = new Set([
124
124
  '.zip', '.tar', '.gz', '.bz2', '.7z', '.rar', '.iso',
125
125
  '.mp3', '.mp4', '.mov', '.avi', '.mkv', '.wav', '.flac', '.ogg',
126
126
  '.ttf', '.otf', '.woff', '.woff2',
127
- '.sqlite', '.sqlite3', '.db',
128
127
  '.psd', '.ai', '.bin', '.wasm',
129
128
  ]);
130
129
  export function hasBinaryExtension(filePath) {