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
@@ -17,6 +17,20 @@
17
17
  * 边界,否则又回到多份真值。
18
18
  */
19
19
  export const CONFIG_LIMITS = {
20
+ /** 同一进程同时运行的顶层动态工作流数。 */
21
+ workflowMaxActiveRuns: { min: 1, max: 64, step: 1, kind: 'integer' },
22
+ /** 同一进程动态工作流共享的模型并发。 */
23
+ workflowModelConcurrency: { min: 1, max: 64, step: 1, kind: 'integer' },
24
+ /** 同一进程动态工作流共享的工具并发。 */
25
+ workflowToolConcurrency: { min: 1, max: 128, step: 1, kind: 'integer' },
26
+ /** 同一进程动态工作流共享的外部进程并发。 */
27
+ workflowProcessConcurrency: { min: 1, max: 64, step: 1, kind: 'integer' },
28
+ /** 单个 pipeline 的默认 item 并发。 */
29
+ workflowPipelineConcurrency: { min: 1, max: 32, step: 1, kind: 'integer' },
30
+ /** 工作流可为单个 pipeline 显式申请的最大并发。 */
31
+ workflowPipelineMaxConcurrency: { min: 1, max: 32, step: 1, kind: 'integer' },
32
+ /** 一棵父子工作流调用树的调用总量熔断。 */
33
+ workflowMaxCalls: { min: 1, max: 100_000, step: 100, kind: 'integer' },
20
34
  /** 顾问单次咨询喂进去的输入 token 上限。上界给到 200 万是为了容纳百万级上下文模型;
21
35
  * 真正生效值还会再被「所选顾问模型的 contextWindow」二次收窄(见 advisor.ts)。 */
22
36
  advisorInputTokenBudget: { min: 1_000, max: 2_000_000, step: 1_000, kind: 'integer' },
@@ -32,6 +46,14 @@ export const CONFIG_LIMITS = {
32
46
  subagentExploreMaxTurns: { min: 5, max: 500, step: 5, kind: 'integer' },
33
47
  /** general(读写执行)子任务的轮数上限。 */
34
48
  subagentGeneralMaxTurns: { min: 10, max: 1_000, step: 10, kind: 'integer' },
49
+ /** Goal 的 token 预算上限(input+output 之和)。⚠️ 它是**可选**的:
50
+ * 不设 = 不限(契约里存 `null`,不是 0 —— 0 会被判成「一开始就超了」)。
51
+ * 这条边界只在用户真的填了数字时约束它。 */
52
+ goalTokenBudget: { min: 1_000, max: 100_000_000, step: 1_000, kind: 'integer' },
53
+ /** `verify()` 里 `shell:` 检查的默认超时(毫秒)。默认值在
54
+ * `infra/verification.ts::DEFAULT_SHELL_CHECK_TIMEOUT_MS`;上界给到 10 分钟,
55
+ * 容纳「必须跑一整个测试套件才算数」的硬门,但默认仍保持 30s 以免阻塞流水线。 */
56
+ verifyShellTimeoutMs: { min: 1_000, max: 600_000, step: 1_000, kind: 'integer' },
35
57
  /** 电脑操作每帧画面的像素预算。 */
36
58
  computerUseMaxImagePixels: { min: 100_000, max: 10_000_000, step: 100_000, kind: 'integer' },
37
59
  /** 自动压缩触发阈值,占 contextWindow 的比例(0,1]。UI 按百分比展示,保留 2 位小数。 */
@@ -27,6 +27,20 @@ export interface NumericLimit {
27
27
  }
28
28
 
29
29
  export const CONFIG_LIMITS = {
30
+ /** 同一进程同时运行的顶层动态工作流数。 */
31
+ workflowMaxActiveRuns: { min: 1, max: 64, step: 1, kind: 'integer' },
32
+ /** 同一进程动态工作流共享的模型并发。 */
33
+ workflowModelConcurrency: { min: 1, max: 64, step: 1, kind: 'integer' },
34
+ /** 同一进程动态工作流共享的工具并发。 */
35
+ workflowToolConcurrency: { min: 1, max: 128, step: 1, kind: 'integer' },
36
+ /** 同一进程动态工作流共享的外部进程并发。 */
37
+ workflowProcessConcurrency: { min: 1, max: 64, step: 1, kind: 'integer' },
38
+ /** 单个 pipeline 的默认 item 并发。 */
39
+ workflowPipelineConcurrency: { min: 1, max: 32, step: 1, kind: 'integer' },
40
+ /** 工作流可为单个 pipeline 显式申请的最大并发。 */
41
+ workflowPipelineMaxConcurrency: { min: 1, max: 32, step: 1, kind: 'integer' },
42
+ /** 一棵父子工作流调用树的调用总量熔断。 */
43
+ workflowMaxCalls: { min: 1, max: 100_000, step: 100, kind: 'integer' },
30
44
  /** 顾问单次咨询喂进去的输入 token 上限。上界给到 200 万是为了容纳百万级上下文模型;
31
45
  * 真正生效值还会再被「所选顾问模型的 contextWindow」二次收窄(见 advisor.ts)。 */
32
46
  advisorInputTokenBudget: { min: 1_000, max: 2_000_000, step: 1_000, kind: 'integer' },
@@ -44,6 +58,16 @@ export const CONFIG_LIMITS = {
44
58
  /** general(读写执行)子任务的轮数上限。 */
45
59
  subagentGeneralMaxTurns: { min: 10, max: 1_000, step: 10, kind: 'integer' },
46
60
 
61
+ /** Goal 的 token 预算上限(input+output 之和)。⚠️ 它是**可选**的:
62
+ * 不设 = 不限(契约里存 `null`,不是 0 —— 0 会被判成「一开始就超了」)。
63
+ * 这条边界只在用户真的填了数字时约束它。 */
64
+ goalTokenBudget: { min: 1_000, max: 100_000_000, step: 1_000, kind: 'integer' },
65
+
66
+ /** `verify()` 里 `shell:` 检查的默认超时(毫秒)。默认值在
67
+ * `infra/verification.ts::DEFAULT_SHELL_CHECK_TIMEOUT_MS`;上界给到 10 分钟,
68
+ * 容纳「必须跑一整个测试套件才算数」的硬门,但默认仍保持 30s 以免阻塞流水线。 */
69
+ verifyShellTimeoutMs: { min: 1_000, max: 600_000, step: 1_000, kind: 'integer' },
70
+
47
71
  /** 电脑操作每帧画面的像素预算。 */
48
72
  computerUseMaxImagePixels: { min: 100_000, max: 10_000_000, step: 100_000, kind: 'integer' },
49
73
 
package/src/config.js CHANGED
@@ -78,6 +78,7 @@ export async function loadProvider() {
78
78
  const compactRatio = parseCompactRatio(process.env.MINIMAL_AGENT_COMPACT_RATIO);
79
79
  const maxTokens = parsePositiveInt(process.env.MINIMAL_AGENT_MAX_TOKENS) ?? DEFAULT_MAX_TOKENS;
80
80
  return {
81
+ source: 'local',
81
82
  name: process.env.MINIMAL_AGENT_PROVIDER ?? 'env',
82
83
  baseURL,
83
84
  apiKey,
package/src/config.ts CHANGED
@@ -17,7 +17,7 @@
17
17
  */
18
18
 
19
19
  import { configService } from './config/configService.js';
20
- import type { Provider } from './types.js';
20
+ import type { LocalProvider, Provider } from './types.js';
21
21
 
22
22
  const DEFAULT_CONTEXT_WINDOW = 128_000;
23
23
 
@@ -52,7 +52,7 @@ function parseCompactRatio(raw: string | undefined): number | undefined {
52
52
  * 加载 Provider 配置(从环境变量)。
53
53
  * 缺少必需变量时抛出明确错误。
54
54
  */
55
- export async function loadProvider(): Promise<Provider> {
55
+ export async function loadProvider(): Promise<LocalProvider> {
56
56
  const baseURL = process.env.MINIMAL_AGENT_BASE_URL;
57
57
  const apiKey = process.env.MINIMAL_AGENT_API_KEY;
58
58
  const model = process.env.MINIMAL_AGENT_MODEL;
@@ -88,6 +88,7 @@ export async function loadProvider(): Promise<Provider> {
88
88
  parsePositiveInt(process.env.MINIMAL_AGENT_MAX_TOKENS) ?? DEFAULT_MAX_TOKENS;
89
89
 
90
90
  return {
91
+ source: 'local',
91
92
  name: process.env.MINIMAL_AGENT_PROVIDER ?? 'env',
92
93
  baseURL,
93
94
  apiKey,
@@ -20,7 +20,7 @@ export function buildContextBudgetPlan(input) {
20
20
  overBudget: totalInputTokens > inputLimit,
21
21
  };
22
22
  }
23
- const AUXILIARY_REMOVAL_ORDER = ['Advisor', 'Agent'];
23
+ const AUXILIARY_REMOVAL_ORDER = ['AdvisorDecision', 'Advisor', 'Agent'];
24
24
  /**
25
25
  * Last-resort schema reduction. Normal requests keep the full catalog; this is
26
26
  * used only after history compaction still cannot fit the provider window.
@@ -47,7 +47,7 @@ export interface EmergencyToolFit {
47
47
  plan: ContextBudgetPlan;
48
48
  }
49
49
 
50
- const AUXILIARY_REMOVAL_ORDER = ['Advisor', 'Agent'];
50
+ const AUXILIARY_REMOVAL_ORDER = ['AdvisorDecision', 'Advisor', 'Agent'];
51
51
 
52
52
  /**
53
53
  * Last-resort schema reduction. Normal requests keep the full catalog; this is
@@ -292,6 +292,9 @@ export function findTailWithCompleteToolChains(messages, minKeep = MIN_KEEP_RECE
292
292
  * @param opts 可选的辅助数据,用于校正系统性低估:
293
293
  * - actualPromptTokens:本轮 LLM done 事件返回的真实 prompt token 数(如有)
294
294
  * - toolsTokens:工具 schema 占的估算 token 数(由 estimateToolsTokens 算出)
295
+ * - serverDeletedTokens:cacheEdits 模式下,服务端已删除但本地 history 仍完整
296
+ * 存在的内容的 token 估算(CacheEditsState.activeDeletedTokens)--先从历史
297
+ * 估算里扣掉再进 max,否则虚高的一方永远获胜,压缩会过早触发
295
298
  * @returns 可能更短的新 messages 数组(不修改原数组)
296
299
  *
297
300
  * 判据(取"真实 usage"与"估算+工具token"两者之大者):
@@ -303,8 +306,10 @@ export function findTailWithCompleteToolChains(messages, minKeep = MIN_KEEP_RECE
303
306
  */
304
307
  export async function autoCompactIfNeeded(messages, provider, opts) {
305
308
  const before = countMessagesTokens(messages); // 纯历史 token,保持语义不变(UI/snip/对比均依赖此值)
306
- // 判据:真实 usage(若有)与「估算 + 工具 schema」取大者,校正系统性低估
307
- const estimated = before + (opts?.toolsTokens ?? 0) + (opts?.transientTokens ?? 0);
309
+ // 判据:真实 usage(若有)与「估算 + 工具 schema」取大者,校正系统性低估。
310
+ // serverDeletedTokens 只从历史部分(before)里扣--它对应 history 里的已删内容,
311
+ // 与工具 schema / transient 无关;扣完再进 max,真实 usage 才有机会主导判据。
312
+ const estimated = before - (opts?.serverDeletedTokens ?? 0) + (opts?.toolsTokens ?? 0) + (opts?.transientTokens ?? 0);
308
313
  const judge = Math.max(opts?.actualPromptTokens ?? 0, estimated);
309
314
  const threshold = getCompactThreshold(provider);
310
315
  if (judge < threshold) {
@@ -353,6 +353,9 @@ export function findTailWithCompleteToolChains(
353
353
  * @param opts 可选的辅助数据,用于校正系统性低估:
354
354
  * - actualPromptTokens:本轮 LLM done 事件返回的真实 prompt token 数(如有)
355
355
  * - toolsTokens:工具 schema 占的估算 token 数(由 estimateToolsTokens 算出)
356
+ * - serverDeletedTokens:cacheEdits 模式下,服务端已删除但本地 history 仍完整
357
+ * 存在的内容的 token 估算(CacheEditsState.activeDeletedTokens)--先从历史
358
+ * 估算里扣掉再进 max,否则虚高的一方永远获胜,压缩会过早触发
356
359
  * @returns 可能更短的新 messages 数组(不修改原数组)
357
360
  *
358
361
  * 判据(取"真实 usage"与"估算+工具token"两者之大者):
@@ -369,6 +372,8 @@ export async function autoCompactIfNeeded(
369
372
  actualPromptTokens?: number;
370
373
  toolsTokens?: number;
371
374
  transientTokens?: number;
375
+ /** cacheEdits 模式的估算校正量:服务端已删、本地未删的 token(见函数头注) */
376
+ serverDeletedTokens?: number;
372
377
  signal?: AbortSignal;
373
378
  promptCache?: PromptCacheContext;
374
379
  /** 注入 chat 实现(仅测试用,验证 signal 透传;生产不传走默认实现)。 */
@@ -376,8 +381,10 @@ export async function autoCompactIfNeeded(
376
381
  },
377
382
  ): Promise<AutoCompactResult> {
378
383
  const before = countMessagesTokens(messages); // 纯历史 token,保持语义不变(UI/snip/对比均依赖此值)
379
- // 判据:真实 usage(若有)与「估算 + 工具 schema」取大者,校正系统性低估
380
- const estimated = before + (opts?.toolsTokens ?? 0) + (opts?.transientTokens ?? 0);
384
+ // 判据:真实 usage(若有)与「估算 + 工具 schema」取大者,校正系统性低估。
385
+ // serverDeletedTokens 只从历史部分(before)里扣--它对应 history 里的已删内容,
386
+ // 与工具 schema / transient 无关;扣完再进 max,真实 usage 才有机会主导判据。
387
+ const estimated = before - (opts?.serverDeletedTokens ?? 0) + (opts?.toolsTokens ?? 0) + (opts?.transientTokens ?? 0);
381
388
  const judge = Math.max(opts?.actualPromptTokens ?? 0, estimated);
382
389
  const threshold = getCompactThreshold(provider);
383
390
  if (judge < threshold) {
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * ============================================================
3
- * src/context/microCompactLite.ts —— 工具结果微压缩(v2)
3
+ * src/context/microCompactLite.ts —— 工具结果微压缩(v4)
4
4
  * ------------------------------------------------------------
5
5
  * 对齐 kakadeai 的 microCompact 设计,纯规则实现,零 LLM 调用。
6
6
  *
@@ -8,14 +8,30 @@
8
8
  * 工具执行结果在写入 history 前经过一道"单向检查门",
9
9
  * 用规则压缩冗余内容,减少 token 消耗但不丢失关键信息。
10
10
  *
11
- * 对齐 kakadeai 的两条有效路径:
11
+ * 对齐 kakadeai 的三条有效路径(本实现对高价值工具更保守):
12
12
  * Path A: Cached MC → 本方案用 SHA-1 进程缓存 + 计数淘汰实现
13
13
  * Path B: Time-based MC → 本方案用轮次衰减实现
14
+ * Path C: 批量回收 → reclaimOldToolResults:低风险工具结果数超阈值时,
15
+ * 只保留最近几条的完整内容,其余按模式处理:
16
+ * - inline(默认,全 provider 可用):本地 history 原地替换为占位符。
17
+ * wire token 真实减少,代价是前缀缓存从被改消息起失效。
18
+ * - cacheEdits(v4,Anthropic 格式 + provider.cacheEdits 开启):本地
19
+ * history **不改**,删除目标记入 CacheEditsState,由 anthropicFormat
20
+ * 组装 cache_edits block 随请求发送——对齐 kakadeai Cached MC 的
21
+ * triggerThreshold/keepRecent 语义与服务端原地删除效果:模型看到
22
+ * 的上下文变短、前缀缓存完整保留。
14
23
  *
15
24
  * kakadeai 已删除 Legacy LLM path → 本方案不实现 LLM 压缩
25
+ *
26
+ * 为什么需要 Path C:SHA-1 去重要求内容完全相同才计数,
27
+ * 而真实工具结果带行号/时间戳/文件内容,几乎不会完全重复——去重路径
28
+ * 形同虚设,工具结果实际全部永久留在 history 里。这是 minimal-agent
29
+ * 上下文膨胀比 kakadeai 快得多的根因(工具结果 token 占比 60-80%)。
16
30
  * ============================================================
17
31
  */
18
- import { createHash } from 'node:crypto';
32
+ import { createHash, randomUUID } from 'node:crypto';
33
+ import { countTextTokens } from './tokenCounter.js';
34
+ import { clearToolResultArchive } from './toolResultArchive.js';
19
35
  // ==================== 配置常量 ====================
20
36
  /** 同一内容最多原样保留多少次,之后用压缩引用替代 */
21
37
  const MAX_REPEAT_COUNT = 3;
@@ -29,8 +45,28 @@ const TAIL_KEEP_CHARS = 1000;
29
45
  const MAX_KEEP_ROUNDS = 10;
30
46
  /** 短内容阈值:不超过此长度的内容直接放行(不做任何处理) */
31
47
  const SHORT_CONTENT_THRESHOLD = 200;
48
+ /** Path C 批量回收:可回收工具结果的存活数量超过该值时触发回收 */
49
+ const RECLAIM_TRIGGER_THRESHOLD = 8;
50
+ /** Path C 批量回收:触发后保留最近多少条完整内容(热尾部) */
51
+ const RECLAIM_KEEP_RECENT = 4;
52
+ /**
53
+ * Path C 批量回收的占位符前缀。用 startsWith 检测已回收的消息,
54
+ * 保证幂等(不会重复计数、重复替换)。刻意与去重标记 `[↑ `、
55
+ * 截断标记 `[... 省略了` 不同字形,避免互相误判。
56
+ */
57
+ const RECLAIM_MARKER_PREFIX = '[旧工具结果已回收';
58
+ function createEmptyCacheEdits() {
59
+ return { deletedToolIds: new Set(), pinned: [], pendingNew: [], activeDeletedTokens: 0 };
60
+ }
32
61
  export function createMicroCompactState() {
33
- return { turn: 0, cache: new Map() };
62
+ return {
63
+ turn: 0,
64
+ cache: new Map(),
65
+ reclaimedCount: 0,
66
+ reclaimedChars: 0,
67
+ archiveKey: randomUUID(),
68
+ cacheEdits: createEmptyCacheEdits(),
69
+ };
34
70
  }
35
71
  const defaultState = createMicroCompactState();
36
72
  export function incrementTurn(state = defaultState) {
@@ -57,24 +93,51 @@ export function getCacheStats(state = defaultState) {
57
93
  expiredCount++;
58
94
  }
59
95
  }
60
- return { totalEntries: state.cache.size, repeatedCount, compressedCount, expiredCount, truncatedCount, totalCharsSaved };
96
+ return {
97
+ totalEntries: state.cache.size,
98
+ repeatedCount,
99
+ compressedCount,
100
+ expiredCount,
101
+ truncatedCount,
102
+ totalCharsSaved,
103
+ reclaimedCount: state.reclaimedCount,
104
+ reclaimedChars: state.reclaimedChars,
105
+ };
61
106
  }
62
107
  /** 清空缓存(供 /new 命令或测试使用) */
63
108
  export function clearCache(state = defaultState) {
64
109
  state.cache.clear();
65
110
  state.turn = 0;
111
+ state.reclaimedCount = 0;
112
+ state.reclaimedChars = 0;
113
+ void clearToolResultArchive(state.archiveKey);
114
+ state.archiveKey = randomUUID();
115
+ resetCacheEdits(state);
116
+ }
117
+ /**
118
+ * 重置 cacheEdits 状态。调用时机(漏掉任何一个都会造成下标错位或重复删除):
119
+ * - autoCompact / 手动 compact 之后:history 被砍头重写,pinned 的翻译后下标
120
+ * 全部失义,服务端缓存前缀也已失效,编辑指令没有继续存在的意义。
121
+ * - /new 新会话(clearCache 内已调用)。
122
+ */
123
+ export function resetCacheEdits(state = defaultState) {
124
+ state.cacheEdits.deletedToolIds.clear();
125
+ state.cacheEdits.pinned.length = 0;
126
+ state.cacheEdits.pendingNew.length = 0;
127
+ // 有效删除量一并清零:compact 后历史被重写,旧删除账目对应的内容可能已不在
128
+ // 新历史里,不清零会让 autoCompact 校正过度(判据虚低 -> 该压不压撑爆上下文)。
129
+ state.cacheEdits.activeDeletedTokens = 0;
66
130
  }
67
131
  // ==================== 工具白名单 ====================
68
132
  /**
69
- * 只有这些工具的返回值参与微压缩(长度截断 + SHA-1 去重)。
133
+ * 只有低风险观察工具的返回值参与长度截断(SHA-1 去重对所有工具生效)。
70
134
  *
71
- * 排除 Read/Edit/Write 的原因:输出本身就短,有独立的大小限制。
72
- * 排除 WebSearch 的原因:搜索结果是"一次性知识注入",首次必须完整展示给模型;
73
- * 后续重复时由 SHA-1 去重处理,但不做长度截断(避免丢失关键信息)。
135
+ * Read/Edit/Write/Bash/WebSearch 默认不截断:它们可能包含源码中段、diff、
136
+ * 一次性诊断或不可复现证据。超大结果由 toolResultArchive 先保存原文并提供可恢复引用。
137
+ * 低风险工具仍保留头尾截断,以控制普通搜索结果的上下文成本。
74
138
  */
75
139
  const COMPRESSIBLE_TOOLS = new Set([
76
140
  'Grep',
77
- 'Bash',
78
141
  'WebFetch',
79
142
  'Glob',
80
143
  ]);
@@ -94,7 +157,7 @@ const COMPRESSIBLE_TOOLS = new Set([
94
157
  * @param content 工具返回的原始内容
95
158
  * @returns 处理后的内容(可能被压缩、截断、或原样返回)
96
159
  */
97
- export function microCompact(toolName, content, state = defaultState) {
160
+ export function microCompact(toolName, content, state = defaultState, policy = getToolResultPolicy(toolName)) {
98
161
  if (!content)
99
162
  return content;
100
163
  // Rule 0: 错误信息原样保留
@@ -118,8 +181,8 @@ export function microCompact(toolName, content, state = defaultState) {
118
181
  // 首次看到此内容
119
182
  state.cache.set(hash, { count: 1, firstToolName: toolName, firstSeenTurn: state.turn });
120
183
  // Rule 2: 不需要——首次出现不存在时间衰减问题
121
- // Rule 3: 长度截断(仅白名单工具)
122
- if (content.length > MAX_RESULT_SIZE && COMPRESSIBLE_TOOLS.has(toolName)) {
184
+ // Rule 3: 长度截断(仅低风险工具;高价值结果禁止不可逆中段丢弃)
185
+ if (!policy.highValue && content.length > MAX_RESULT_SIZE && COMPRESSIBLE_TOOLS.has(toolName)) {
123
186
  return truncateContent(content);
124
187
  }
125
188
  return content;
@@ -139,10 +202,146 @@ export function expireOldEntries(state = defaultState) {
139
202
  }
140
203
  return expired;
141
204
  }
205
+ // ==================== Path C: 批量回收旧工具结果 ====================
206
+ /**
207
+ * 可回收的工具集合:仅保留低风险观察工具。即便这些工具通常可重放,
208
+ * 高价值结果也可通过 tool_result_policy 显式保护,不会因为工具名而强行清掉。
209
+ *
210
+ * 刻意排除高价值/不可稳定重放的工具:
211
+ * - Bash / WebSearch:一次性诊断和外部搜索结果可能无法复现
212
+ * - Read / Edit / Write:源码中段、diff 或生成内容可能是后续推理证据
213
+ * - Ask / AskUserQuestion:用户答案不可重放,清了就永远丢了
214
+ * - Task / agent 系:子任务结论昂贵且常被后续轮次引用
215
+ * - PresentResult:最终交付物清单,是本轮对话的核心产出
216
+ */
217
+ const RECLAIMABLE_TOOLS = new Set([
218
+ 'Grep',
219
+ 'Glob',
220
+ 'WebFetch',
221
+ ]);
222
+ const EMPTY_RECLAIM_STATS = { reclaimedCount: 0, reclaimedChars: 0 };
223
+ /**
224
+ * Path C:批量回收旧工具结果(每轮 LLM 调用前执行)。
225
+ *
226
+ * 语义(对齐 kakadeai Cached MC 的 triggerThreshold / keepRecent):
227
+ * history 中"存活"的可回收工具结果数量 > RECLAIM_TRIGGER_THRESHOLD 时,
228
+ * 只保留最近 RECLAIM_KEEP_RECENT 条的完整内容(热尾部),其余按 mode 处理:
229
+ * - 'inline'(默认):原地替换为占位符(含工具名与被替换的字符数,
230
+ * 模型需要时可重新调用该工具)。
231
+ * - 'cacheEdits':**不改 history**——删除目标(tool_call_id)记入
232
+ * state.cacheEdits.pendingNew,由 anthropicFormat 组装 cache_edits block
233
+ * 随请求发送,服务端在 KV 缓存内原地删除。
234
+ *
235
+ * 设计约束与取舍:
236
+ * 1. inline 只改 tool 消息的 content,tool_call_id / display_metadata 原样保留——
237
+ * API 协议完整性不受影响,且 display_metadata 在发送 Provider 前本就
238
+ * 被剥离(仅本地展示用),所以 UI 渲染不受影响。
239
+ * 2. 幂等:inline 用占位符前缀(RECLAIM_MARKER_PREFIX)检测已回收消息;
240
+ * cacheEdits 用 deletedToolIds 集合检测。已回收的不计入候选、不二次处理。
241
+ * 触发频率 = 每攒 (阈值-保留数) 条新结果触发一次。
242
+ * 3. 跳过 Error 结果(短且常是排障线索)和 ≤200 字符的短结果
243
+ * (占位符本身就有 ~60 字符,清短结果纯亏)。
244
+ * 4. 缓存代价(模式差异的核心):
245
+ * inline 直接改 history,前缀缓存从被改消息起失效——换 wire token 真实
246
+ * 削减,一次缓存重建几轮就回本,适用于无 cache_edits 能力的端点(含全部
247
+ * OpenAI 格式 provider)。
248
+ * cacheEdits 本地不动、服务端原地删——前缀 hash 不变、缓存命中完整保留;
249
+ * 代价是 wire 上完整内容仍要发送(省的是服务端 KV 驻留与模型注意力窗口,
250
+ * 不是请求体积)。reclaimedChars 在此模式下统计的是"服务端删除的内容量"。
251
+ * 5. tool_call_id → 工具名的映射来自 assistant 消息的 tool_calls 数组,
252
+ * 扫一遍 history 即得,不需要额外状态。
253
+ * 6. cacheEdits 模式下本函数只做决策不做协议——它不认识 Anthropic 消息形状,
254
+ * 翻译后下标由 anthropicFormat 的组装函数负责回填(见其 pinned 逻辑)。
255
+ *
256
+ * @param history 完整会话历史(inline 模式原地修改命中的 tool 消息;cacheEdits 模式只读)
257
+ * @param state 微压缩状态(累计统计写入 reclaimedCount / reclaimedChars;cacheEdits 模式另写 pendingNew)
258
+ * @param mode 'inline'(默认)| 'cacheEdits'(Anthropic 格式 + provider.cacheEdits)
259
+ * @returns 本次回收的条数与字符数(未触发时全为 0)
260
+ */
261
+ export function reclaimOldToolResults(history, state = defaultState, mode = 'inline') {
262
+ // 1. 建立 tool_call_id → 工具名 映射
263
+ const toolNameById = new Map();
264
+ for (const msg of history) {
265
+ if (msg.role !== 'assistant' || !msg.tool_calls)
266
+ continue;
267
+ for (const tc of msg.tool_calls) {
268
+ if (tc.id && tc.function?.name)
269
+ toolNameById.set(tc.id, tc.function.name);
270
+ }
271
+ }
272
+ // 2. 收集可回收候选:白名单工具 + 存活(未回收过)+ 非错误 + 非短内容
273
+ // 存活判据按模式分叉:inline 看占位符前缀,cacheEdits 看 deletedToolIds。
274
+ const candidates = [];
275
+ for (const msg of history) {
276
+ if (msg.role !== 'tool' || typeof msg.content !== 'string')
277
+ continue;
278
+ const content = msg.content;
279
+ if (content.startsWith(RECLAIM_MARKER_PREFIX))
280
+ continue;
281
+ if (content.startsWith('Error:') || content.startsWith('错误'))
282
+ continue;
283
+ if (content.length <= SHORT_CONTENT_THRESHOLD)
284
+ continue;
285
+ const toolCallId = msg.tool_call_id;
286
+ const toolName = toolCallId ? toolNameById.get(toolCallId) : undefined;
287
+ const policy = msg.tool_result_policy ?? (toolName ? getToolResultPolicy(toolName) : undefined);
288
+ if (!toolCallId
289
+ || !toolName
290
+ || !RECLAIMABLE_TOOLS.has(toolName)
291
+ || !policy?.reclaimable
292
+ || policy.highValue)
293
+ continue;
294
+ if (mode === 'cacheEdits' && state.cacheEdits.deletedToolIds.has(toolCallId))
295
+ continue;
296
+ candidates.push({ msg: msg, toolCallId, chars: content.length });
297
+ }
298
+ // 3. 未超阈值不动(> 而非 >=:恰好等于阈值视为健康水位)
299
+ if (candidates.length <= RECLAIM_TRIGGER_THRESHOLD) {
300
+ return EMPTY_RECLAIM_STATS;
301
+ }
302
+ // 4. 保留热尾部(按消息顺序的最后 KEEP_RECENT 条),其余按模式处理
303
+ const toClear = candidates.slice(0, candidates.length - RECLAIM_KEEP_RECENT);
304
+ let reclaimedChars = 0;
305
+ if (mode === 'cacheEdits') {
306
+ for (const { msg, toolCallId, chars } of toClear) {
307
+ state.cacheEdits.deletedToolIds.add(toolCallId);
308
+ state.cacheEdits.pendingNew.push(toolCallId);
309
+ // 累计有效删除量(token 估算,与 tokenCounter 同一套系数):
310
+ // autoCompact 判据用它校正「本地 history 未瘦身」造成的虚高估算。
311
+ state.cacheEdits.activeDeletedTokens += countTextTokens(msg.content);
312
+ reclaimedChars += chars;
313
+ }
314
+ }
315
+ else {
316
+ for (const { msg, toolCallId, chars } of toClear) {
317
+ const toolName = toolNameById.get(toolCallId) ?? 'tool';
318
+ reclaimedChars += chars;
319
+ const archiveHint = msg.tool_result_policy?.archiveRef
320
+ ? ` | 完整原文可用 Read 读取:${msg.tool_result_policy.archiveRef}`
321
+ : '';
322
+ msg.content =
323
+ `${RECLAIM_MARKER_PREFIX} | ${toolName} | 原本 ${chars.toLocaleString()} 字符${archiveHint} | ` +
324
+ `如需再次查看请重新调用该工具]`;
325
+ }
326
+ }
327
+ // 5. 累计统计(getCacheStats 可查,观测回收效果)
328
+ state.reclaimedCount += toClear.length;
329
+ state.reclaimedChars += reclaimedChars;
330
+ return { reclaimedCount: toClear.length, reclaimedChars };
331
+ }
142
332
  // ==================== 内部函数 ====================
143
333
  function sha1(str) {
144
334
  return createHash('sha1').update(str).digest('hex');
145
335
  }
336
+ export function getToolResultPolicy(toolName) {
337
+ // Bash/WebSearch/Read/Edit/Write 等结果可能包含一次性诊断、关键源码或不可复现证据,
338
+ // 默认高价值且不可回收;低风险观察工具才进入 Path C。
339
+ const reclaimable = RECLAIMABLE_TOOLS.has(toolName);
340
+ return {
341
+ reclaimable,
342
+ highValue: !reclaimable,
343
+ };
344
+ }
146
345
  function truncateContent(content) {
147
346
  const omitted = content.length - HEAD_KEEP_CHARS - TAIL_KEEP_CHARS;
148
347
  return (content.slice(0, HEAD_KEEP_CHARS) +