minimal-agent 0.10.0 → 0.12.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 (573) hide show
  1. package/README.md +11 -3
  2. package/package.json +52 -5
  3. package/plugins/computer_use/.claude-plugin/plugin.json +6 -0
  4. package/plugins/computer_use/README.md +94 -0
  5. package/plugins/computer_use/app/_template.md +142 -0
  6. package/plugins/computer_use/app/chrome.md +165 -0
  7. package/plugins/computer_use/app/finder.md +76 -0
  8. package/plugins/computer_use/app/macos-system-settings.md +81 -0
  9. package/plugins/computer_use/app/microsoft-excel.md +80 -0
  10. package/plugins/computer_use/app/microsoft-powerpoint.md +80 -0
  11. package/plugins/computer_use/app/microsoft-word.md +79 -0
  12. package/plugins/computer_use/app/wechat.md +413 -0
  13. package/plugins/computer_use/app/weread.md +319 -0
  14. package/plugins/computer_use/commands/computeruse.md +25 -0
  15. package/plugins/computer_use/commands/cu.md +9 -0
  16. package/plugins/computer_use/plugin.js +26 -0
  17. package/plugins/computer_use/plugin.ts +30 -0
  18. package/plugins/computer_use/src/capture.js +90 -0
  19. package/plugins/computer_use/src/capture.ts +104 -0
  20. package/plugins/computer_use/src/commands.js +91 -0
  21. package/plugins/computer_use/src/commands.ts +103 -0
  22. package/plugins/computer_use/src/daemon.js +134 -0
  23. package/plugins/computer_use/src/daemon.ts +161 -0
  24. package/plugins/computer_use/src/manuals.js +135 -0
  25. package/plugins/computer_use/src/manuals.ts +159 -0
  26. package/plugins/computer_use/src/verify.js +168 -0
  27. package/plugins/computer_use/src/verify.ts +219 -0
  28. package/plugins/computer_use/test/commands.test.ts +73 -0
  29. package/plugins/cron-runner/plugin.ts +38 -0
  30. package/plugins/cron-runner/src/commands.ts +373 -0
  31. package/plugins/cron-runner/src/cronTime.ts +155 -0
  32. package/plugins/cron-runner/src/lock.ts +79 -0
  33. package/plugins/cron-runner/src/runs.ts +99 -0
  34. package/plugins/cron-runner/src/scheduleEngine.ts +76 -0
  35. package/plugins/cron-runner/src/scheduler.ts +376 -0
  36. package/plugins/cron-runner/src/schema.ts +139 -0
  37. package/plugins/cron-runner/src/service.ts +193 -0
  38. package/plugins/cron-runner/src/store.ts +333 -0
  39. package/plugins/cron-runner/src/types.ts +141 -0
  40. package/plugins/cron-runner/test/cronTime.test.ts +41 -0
  41. package/plugins/cron-runner/test/plugin-integration.test.ts +47 -0
  42. package/plugins/cron-runner/test/scheduleEngine.test.ts +41 -0
  43. package/plugins/cron-runner/test/service.test.ts +76 -0
  44. package/plugins/cron-runner/test/store-and-scheduler.test.ts +501 -0
  45. package/plugins/workflow-runner/plugin.js +56 -2
  46. package/plugins/workflow-runner/plugin.ts +113 -0
  47. package/plugins/workflow-runner/src/agentCommon.js +43 -4
  48. package/plugins/workflow-runner/src/agentCommon.ts +435 -0
  49. package/plugins/workflow-runner/src/controlFlow/branch.js +40 -0
  50. package/plugins/workflow-runner/src/controlFlow/branch.ts +46 -0
  51. package/plugins/workflow-runner/src/controlFlow/loop.js +211 -0
  52. package/plugins/workflow-runner/src/controlFlow/loop.ts +248 -0
  53. package/plugins/workflow-runner/src/controlFlow/pause.js +129 -0
  54. package/plugins/workflow-runner/src/controlFlow/pause.ts +141 -0
  55. package/plugins/workflow-runner/src/controlFlow/signal.js +21 -0
  56. package/plugins/workflow-runner/src/controlFlow/signal.ts +29 -0
  57. package/plugins/workflow-runner/src/controlFlow/types.js +18 -0
  58. package/plugins/workflow-runner/src/controlFlow/types.ts +63 -0
  59. package/plugins/workflow-runner/src/dslManifest.ts +127 -0
  60. package/plugins/workflow-runner/src/expressions.ts +622 -0
  61. package/plugins/workflow-runner/src/index.js +13 -4
  62. package/plugins/workflow-runner/src/index.ts +338 -0
  63. package/plugins/workflow-runner/src/jsonPayload.ts +84 -0
  64. package/plugins/workflow-runner/src/loader.js +23 -0
  65. package/plugins/workflow-runner/src/loader.ts +721 -0
  66. package/plugins/workflow-runner/src/multimodal.js +2 -1
  67. package/plugins/workflow-runner/src/multimodal.ts +64 -0
  68. package/plugins/workflow-runner/src/recovery.ts +149 -0
  69. package/plugins/workflow-runner/src/runner.js +75 -659
  70. package/plugins/workflow-runner/src/runner.ts +604 -0
  71. package/plugins/workflow-runner/src/stepExecutors/agent.ts +234 -0
  72. package/plugins/workflow-runner/src/stepExecutors/assert.ts +50 -0
  73. package/plugins/workflow-runner/src/stepExecutors/echo.js +31 -0
  74. package/plugins/workflow-runner/src/stepExecutors/echo.ts +38 -0
  75. package/plugins/workflow-runner/src/stepExecutors/llm.ts +133 -0
  76. package/plugins/workflow-runner/src/stepExecutors/set.js +49 -0
  77. package/plugins/workflow-runner/src/stepExecutors/set.ts +56 -0
  78. package/plugins/workflow-runner/src/stepExecutors/skill.js +5 -6
  79. package/plugins/workflow-runner/src/stepExecutors/skill.ts +140 -0
  80. package/plugins/workflow-runner/src/stepExecutors/tool.js +80 -8
  81. package/plugins/workflow-runner/src/stepExecutors/tool.ts +256 -0
  82. package/plugins/workflow-runner/src/stepExecutors/verify.ts +68 -0
  83. package/plugins/workflow-runner/src/stepPipeline.js +277 -0
  84. package/plugins/workflow-runner/src/stepPipeline.ts +366 -0
  85. package/plugins/workflow-runner/src/taskIdentity.ts +405 -0
  86. package/plugins/workflow-runner/src/toolRuntime.js +48 -0
  87. package/plugins/workflow-runner/src/toolRuntime.ts +64 -0
  88. package/plugins/workflow-runner/src/types.js +37 -1
  89. package/plugins/workflow-runner/src/types.ts +602 -0
  90. package/plugins/workflow-runner/src/workflowState.ts +733 -0
  91. package/plugins/workflow-runner/test/agent.test.ts +587 -0
  92. package/plugins/workflow-runner/test/agentLlmError.test.ts +373 -0
  93. package/plugins/workflow-runner/test/bashBlacklist.sweep.test.ts +65 -0
  94. package/plugins/workflow-runner/test/captureMisbind.test.ts +99 -0
  95. package/plugins/workflow-runner/test/cli.e2e.test.ts +147 -0
  96. package/plugins/workflow-runner/test/context-files.test.ts +320 -0
  97. package/plugins/workflow-runner/test/e2e.test.ts +370 -0
  98. package/plugins/workflow-runner/test/engineRobustness.test.ts +226 -0
  99. package/plugins/workflow-runner/test/expressions.test.ts +397 -0
  100. package/plugins/workflow-runner/test/foundation.test.ts +126 -0
  101. package/plugins/workflow-runner/test/graceful.test.ts +139 -0
  102. package/plugins/workflow-runner/test/greedyInputs.load.test.ts +47 -0
  103. package/plugins/workflow-runner/test/hostCapability.test.ts +108 -0
  104. package/plugins/workflow-runner/test/illustrate.load.test.ts +183 -0
  105. package/plugins/workflow-runner/test/jsonPayload.test.ts +83 -0
  106. package/plugins/workflow-runner/test/loader.test.ts +617 -0
  107. package/plugins/workflow-runner/test/maxTurnsRetryDelay.test.ts +33 -0
  108. package/plugins/workflow-runner/test/multimodal.test.ts +342 -0
  109. package/plugins/workflow-runner/test/output-schema.test.ts +213 -0
  110. package/plugins/workflow-runner/test/parseWorkflowArgs.test.ts +87 -0
  111. package/plugins/workflow-runner/test/pluginRunner.isolation.test.ts +269 -0
  112. package/plugins/workflow-runner/test/ppt.load.test.ts +1220 -0
  113. package/plugins/workflow-runner/test/ralphLoop.e2e.test.ts +220 -0
  114. package/plugins/workflow-runner/test/recovery.test.ts +265 -0
  115. package/plugins/workflow-runner/test/runner.test.ts +911 -0
  116. package/plugins/workflow-runner/test/runnerPreflight.test.ts +379 -0
  117. package/plugins/workflow-runner/test/skillTurnDone.test.ts +71 -0
  118. package/plugins/workflow-runner/test/stateLifecycle.test.ts +150 -0
  119. package/plugins/workflow-runner/test/stepPipeline.test.ts +114 -0
  120. package/plugins/workflow-runner/test/taskArbitration.test.ts +338 -0
  121. package/plugins/workflow-runner/test/taskIdentity.test.ts +237 -0
  122. package/plugins/workflow-runner/test/taskLifecycle.test.ts +270 -0
  123. package/plugins/workflow-runner/test/toolArtifactOverwrite.test.ts +221 -0
  124. package/plugins/workflow-runner/test/toolCapabilityBoundary.test.ts +29 -0
  125. package/plugins/workflow-runner/test/toolRuntimeIntegration.test.ts +168 -0
  126. package/plugins/workflow-runner/test/webppt.load.test.ts +250 -0
  127. package/plugins/workflow-runner/test/word.load.test.ts +208 -0
  128. package/plugins/workflow-runner/test/workflows.smoke.test.ts +76 -0
  129. package/plugins/workflow-runner/test/yamlGuardConditions.test.ts +207 -0
  130. package/skills/browser-automation/SKILL.md +9 -19
  131. package/skills/web-crawler/SKILL.md +9 -11
  132. package/src/askBridge.ts +249 -0
  133. package/src/bootstrap/cwdArg.js +10 -3
  134. package/src/bootstrap/cwdArg.ts +31 -0
  135. package/src/bootstrap/workingDir.ts +48 -0
  136. package/src/cli/args.js +70 -7
  137. package/src/cli/args.ts +146 -0
  138. package/src/cli/computerUse.js +185 -0
  139. package/src/cli/computerUse.ts +221 -0
  140. package/src/cli/configMenu.js +274 -202
  141. package/src/cli/configMenu.tsx +521 -0
  142. package/src/cli/memoryAccess.js +45 -0
  143. package/src/cli/memoryAccess.ts +53 -0
  144. package/src/cli/print.js +119 -5
  145. package/src/cli/print.ts +597 -0
  146. package/src/cli/quickModelSetup.js +60 -0
  147. package/src/cli/quickModelSetup.tsx +96 -0
  148. package/src/cli/streamJson.js +80 -4
  149. package/src/cli/streamJson.ts +433 -0
  150. package/src/cli/wizards/advisorWizard.js +1 -0
  151. package/src/cli/wizards/advisorWizard.tsx +195 -0
  152. package/src/cli/wizards/agentRuntimeWizard.js +84 -0
  153. package/src/cli/wizards/agentRuntimeWizard.tsx +134 -0
  154. package/src/cli/wizards/browserWizard.js +55 -0
  155. package/src/cli/wizards/browserWizard.tsx +77 -0
  156. package/src/cli/wizards/contextAdvisorWizard.js +84 -0
  157. package/src/cli/wizards/contextAdvisorWizard.tsx +124 -0
  158. package/src/cli/wizards/fieldForm.js +7 -4
  159. package/src/cli/wizards/fieldForm.tsx +250 -0
  160. package/src/cli/wizards/imageWizard.js +4 -5
  161. package/src/cli/wizards/imageWizard.tsx +96 -0
  162. package/src/cli/wizards/openRouterWizard.tsx +48 -0
  163. package/src/cli/wizards/providerPresets.js +1 -8
  164. package/src/cli/wizards/providerPresets.ts +106 -0
  165. package/src/cli/wizards/providerWizard.js +152 -205
  166. package/src/cli/wizards/providerWizard.tsx +266 -0
  167. package/src/cli/wizards/searchWizard.tsx +47 -0
  168. package/src/cli/wizards/ttsWizard.js +4 -3
  169. package/src/cli/wizards/ttsWizard.tsx +61 -0
  170. package/src/config/configDefaults.js +25 -0
  171. package/src/config/configDefaults.ts +33 -0
  172. package/src/config/configDiagnostics.js +117 -0
  173. package/src/config/configDiagnostics.ts +166 -0
  174. package/src/config/configFile.js +52 -32
  175. package/src/config/configFile.ts +633 -0
  176. package/src/config/configManagement.js +126 -0
  177. package/src/config/configManagement.ts +159 -0
  178. package/src/config/configService.js +66 -11
  179. package/src/config/configService.ts +554 -0
  180. package/src/config/numericLimits.js +61 -0
  181. package/src/config/numericLimits.ts +80 -0
  182. package/src/config.ts +109 -0
  183. package/src/context/agentHome.ts +11 -0
  184. package/src/context/archive.ts +144 -0
  185. package/src/context/budgetPlan.js +54 -0
  186. package/src/context/budgetPlan.ts +88 -0
  187. package/src/context/compact.js +179 -106
  188. package/src/context/compact.ts +584 -0
  189. package/src/context/contextBundle.js +119 -0
  190. package/src/context/contextBundle.ts +176 -0
  191. package/src/context/contextLock.ts +84 -0
  192. package/src/context/microCompactLite.ts +218 -0
  193. package/src/context/persistContext.ts +177 -0
  194. package/src/context/reactiveCompact.js +19 -4
  195. package/src/context/reactiveCompact.ts +240 -0
  196. package/src/context/recentDirs.ts +42 -0
  197. package/src/context/sessionPath.ts +206 -0
  198. package/src/context/sessionRegistry.js +8 -2
  199. package/src/context/sessionRegistry.ts +414 -0
  200. package/src/context/snipCompact.ts +163 -0
  201. package/src/context/tokenCounter.ts +106 -0
  202. package/src/context/workspaceIndex.js +2 -2
  203. package/src/context/workspaceIndex.ts +751 -0
  204. package/src/entry.compiled.tsx +20 -0
  205. package/src/harness/claimValidation.js +9 -0
  206. package/src/harness/claimValidation.ts +22 -0
  207. package/src/harness/evidenceLedger.js +92 -0
  208. package/src/harness/evidenceLedger.ts +96 -0
  209. package/src/harness/stallGuard.js +60 -0
  210. package/src/harness/stallGuard.ts +81 -0
  211. package/src/humanIntervention.js +129 -0
  212. package/src/humanIntervention.ts +216 -0
  213. package/src/infra/verification.ts +295 -0
  214. package/src/irreversible/rules.js +216 -0
  215. package/src/irreversible/rules.ts +261 -0
  216. package/src/llm/client.js +40 -3
  217. package/src/llm/client.ts +621 -0
  218. package/src/llm/promptCache.js +27 -0
  219. package/src/llm/promptCache.ts +41 -0
  220. package/src/llm/providers/anthropicFormat.js +41 -5
  221. package/src/llm/providers/anthropicFormat.ts +290 -0
  222. package/src/llm/providers/openaiFormat.js +186 -8
  223. package/src/llm/providers/openaiFormat.ts +428 -0
  224. package/src/loop.js +614 -63
  225. package/src/loop.ts +1454 -0
  226. package/src/main.js +67 -10
  227. package/src/main.tsx +344 -0
  228. package/src/memory/codec.js +204 -0
  229. package/src/memory/codec.ts +249 -0
  230. package/src/memory/constants.js +34 -0
  231. package/src/memory/constants.ts +50 -0
  232. package/src/memory/episodicMemory.js +684 -0
  233. package/src/memory/episodicMemory.ts +815 -0
  234. package/src/memory/fileStore.js +148 -0
  235. package/src/memory/fileStore.ts +184 -0
  236. package/src/memory/memoryService.js +570 -0
  237. package/src/memory/memoryService.ts +859 -0
  238. package/src/memory/migration.js +128 -0
  239. package/src/memory/migration.ts +160 -0
  240. package/src/memory/repository.js +789 -0
  241. package/src/memory/repository.ts +893 -0
  242. package/src/memory/retrieval.js +108 -0
  243. package/src/memory/retrieval.ts +145 -0
  244. package/src/memory/searchIndex.js +107 -0
  245. package/src/memory/searchIndex.ts +153 -0
  246. package/src/memory/topicView.js +82 -0
  247. package/src/memory/topicView.ts +95 -0
  248. package/src/memory/turnJournal.js +95 -0
  249. package/src/memory/turnJournal.ts +120 -0
  250. package/src/memory/types.js +2 -0
  251. package/src/memory/types.ts +186 -0
  252. package/src/messageQueue.ts +123 -0
  253. package/src/multimodal.js +128 -46
  254. package/src/multimodal.ts +349 -0
  255. package/src/plugin-sdk.js +21 -1
  256. package/src/plugin-sdk.ts +134 -0
  257. package/src/plugins/builtinPluginIds.js +47 -0
  258. package/src/plugins/builtinPluginIds.ts +51 -0
  259. package/src/plugins/builtinRegistry.ts +43 -0
  260. package/src/plugins/commandRouter.js +40 -26
  261. package/src/plugins/commandRouter.ts +261 -0
  262. package/src/plugins/hookEngine.ts +341 -0
  263. package/src/plugins/pluginApi.ts +133 -0
  264. package/src/plugins/pluginLifecycle.ts +34 -0
  265. package/src/plugins/pluginLoader.ts +147 -0
  266. package/src/plugins/pluginManifest.js +127 -0
  267. package/src/plugins/pluginManifest.ts +152 -0
  268. package/src/plugins/pluginRunner.js +47 -2
  269. package/src/plugins/pluginRunner.ts +207 -0
  270. package/src/plugins/transcript.ts +208 -0
  271. package/src/prompts/lint.js +169 -0
  272. package/src/prompts/lint.ts +220 -0
  273. package/src/prompts/pluginList.js +32 -16
  274. package/src/prompts/pluginList.ts +86 -0
  275. package/src/prompts/policyRegistry.js +318 -0
  276. package/src/prompts/policyRegistry.ts +358 -0
  277. package/src/prompts/projectInstructions.js +24 -0
  278. package/src/prompts/projectInstructions.ts +81 -0
  279. package/src/prompts/promptAssembly.js +311 -202
  280. package/src/prompts/promptAssembly.ts +510 -0
  281. package/src/prompts/skillList.js +106 -45
  282. package/src/prompts/skillList.ts +198 -0
  283. package/src/prompts/system.js +31 -6
  284. package/src/prompts/system.ts +81 -0
  285. package/src/runtime/agentRuntimeContext.js +53 -0
  286. package/src/runtime/agentRuntimeContext.ts +112 -0
  287. package/src/session/runAgentTurn.js +71 -12
  288. package/src/session/runAgentTurn.ts +181 -0
  289. package/src/session/runTurn.js +29 -0
  290. package/src/session/runTurn.ts +160 -0
  291. package/src/session/runtimeStore.js +149 -0
  292. package/src/session/runtimeStore.ts +197 -0
  293. package/src/session/sessionState.js +79 -3
  294. package/src/session/sessionState.ts +134 -0
  295. package/src/toolGate.ts +50 -0
  296. package/src/tools/advisor/advisor.js +76 -15
  297. package/src/tools/advisor/advisor.ts +512 -0
  298. package/src/tools/agent/agent.js +245 -29
  299. package/src/tools/agent/agent.ts +837 -0
  300. package/src/tools/agent/agentTaskService.js +60 -0
  301. package/src/tools/agent/agentTaskService.ts +113 -0
  302. package/src/tools/agent/agentTypes.js +20 -8
  303. package/src/tools/agent/agentTypes.ts +94 -0
  304. package/src/tools/agent/coordinator.ts +111 -0
  305. package/src/tools/agent/worktree.ts +296 -0
  306. package/src/tools/ask/ask.js +17 -0
  307. package/src/tools/ask/ask.ts +122 -0
  308. package/src/tools/bash/attachImage.js +223 -0
  309. package/src/tools/bash/attachImage.ts +281 -0
  310. package/src/tools/bash/bash.js +132 -14
  311. package/src/tools/bash/bash.ts +642 -0
  312. package/src/tools/bash/semantics.ts +103 -0
  313. package/src/tools/bash/warnings.js +17 -11
  314. package/src/tools/bash/warnings.ts +117 -0
  315. package/src/tools/capabilities.js +42 -0
  316. package/src/tools/capabilities.ts +69 -0
  317. package/src/tools/computeruse/accessibilityPermission.js +261 -0
  318. package/src/tools/computeruse/accessibilityPermission.ts +294 -0
  319. package/src/tools/computeruse/axSearch.js +96 -0
  320. package/src/tools/computeruse/axSearch.ts +120 -0
  321. package/src/tools/computeruse/axSnap.js +272 -0
  322. package/src/tools/computeruse/axSnap.ts +349 -0
  323. package/src/tools/computeruse/capabilityLabels.js +95 -0
  324. package/src/tools/computeruse/capabilityLabels.ts +115 -0
  325. package/src/tools/computeruse/computerUseService.js +2235 -0
  326. package/src/tools/computeruse/computerUseService.ts +2686 -0
  327. package/src/tools/computeruse/computeruse.js +2742 -0
  328. package/src/tools/computeruse/computeruse.ts +3265 -0
  329. package/src/tools/computeruse/diagnosticTrace.js +154 -0
  330. package/src/tools/computeruse/diagnosticTrace.ts +195 -0
  331. package/src/tools/computeruse/diagnostics.js +369 -0
  332. package/src/tools/computeruse/diagnostics.ts +453 -0
  333. package/src/tools/computeruse/grants.js +53 -0
  334. package/src/tools/computeruse/grants.ts +70 -0
  335. package/src/tools/computeruse/humanBoundary.js +159 -0
  336. package/src/tools/computeruse/humanBoundary.ts +199 -0
  337. package/src/tools/computeruse/intervention.js +77 -0
  338. package/src/tools/computeruse/intervention.ts +110 -0
  339. package/src/tools/computeruse/manualSchema.js +709 -0
  340. package/src/tools/computeruse/manualSchema.ts +916 -0
  341. package/src/tools/computeruse/observationImages.js +705 -0
  342. package/src/tools/computeruse/observationImages.ts +889 -0
  343. package/src/tools/computeruse/protocol.js +60 -0
  344. package/src/tools/computeruse/protocol.ts +515 -0
  345. package/src/tools/computeruse/telemetryLog.js +57 -0
  346. package/src/tools/computeruse/telemetryLog.ts +67 -0
  347. package/src/tools/computeruse/vision/appGuide.js +325 -0
  348. package/src/tools/computeruse/vision/appGuide.ts +482 -0
  349. package/src/tools/computeruse/vision/focus.js +291 -0
  350. package/src/tools/computeruse/vision/focus.ts +382 -0
  351. package/src/tools/computeruse/vision/frames.js +248 -0
  352. package/src/tools/computeruse/vision/frames.ts +329 -0
  353. package/src/tools/computeruse/vision/geometry.js +131 -0
  354. package/src/tools/computeruse/vision/geometry.ts +163 -0
  355. package/src/tools/computeruse/vision/imaging.js +201 -0
  356. package/src/tools/computeruse/vision/imaging.ts +281 -0
  357. package/src/tools/computeruse/vision/png.js +274 -0
  358. package/src/tools/computeruse/vision/png.ts +317 -0
  359. package/src/tools/computeruse/vision/raster.js +320 -0
  360. package/src/tools/computeruse/vision/raster.ts +408 -0
  361. package/src/tools/computeruse/vision/settle.js +131 -0
  362. package/src/tools/computeruse/vision/settle.ts +220 -0
  363. package/src/tools/computeruse/vision/telemetry.js +196 -0
  364. package/src/tools/computeruse/vision/telemetry.ts +241 -0
  365. package/src/tools/computeruse/visionOcr.js +115 -0
  366. package/src/tools/computeruse/visionOcr.ts +128 -0
  367. package/src/tools/computeruse/waitFor.js +237 -0
  368. package/src/tools/computeruse/waitFor.ts +291 -0
  369. package/src/tools/download/download.js +10 -6
  370. package/src/tools/download/download.ts +187 -0
  371. package/src/tools/edit/edit.js +30 -18
  372. package/src/tools/edit/edit.ts +349 -0
  373. package/src/tools/edit/multi-edit.js +25 -14
  374. package/src/tools/edit/multi-edit.ts +223 -0
  375. package/src/tools/effectiveToolSet.js +73 -0
  376. package/src/tools/effectiveToolSet.ts +91 -0
  377. package/src/tools/genimage/genimage.ts +257 -0
  378. package/src/tools/genspeech/genspeech.ts +83 -0
  379. package/src/tools/glob/glob.js +176 -29
  380. package/src/tools/glob/glob.ts +283 -0
  381. package/src/tools/grep/grep.js +61 -19
  382. package/src/tools/grep/grep.ts +239 -0
  383. package/src/tools/grep/rgPath.ts +206 -0
  384. package/src/tools/index.js +99 -5
  385. package/src/tools/index.ts +293 -0
  386. package/src/tools/lsp/config.js +113 -0
  387. package/src/tools/lsp/config.ts +113 -0
  388. package/src/tools/lsp/lsp.js +256 -0
  389. package/src/tools/lsp/lsp.ts +274 -0
  390. package/src/tools/lsp/service.js +303 -0
  391. package/src/tools/lsp/service.ts +296 -0
  392. package/src/tools/memory/memory.js +520 -0
  393. package/src/tools/memory/memory.ts +625 -0
  394. package/src/tools/memory/policy.js +53 -0
  395. package/src/tools/memory/policy.ts +72 -0
  396. package/src/tools/notebook/notebookEdit.js +114 -0
  397. package/src/tools/notebook/notebookEdit.ts +126 -0
  398. package/src/tools/powershell/powershell.js +210 -0
  399. package/src/tools/powershell/powershell.ts +239 -0
  400. package/src/tools/presentresult/presentresult.js +145 -0
  401. package/src/tools/presentresult/presentresult.ts +156 -0
  402. package/src/tools/read/read.js +371 -163
  403. package/src/tools/read/read.ts +558 -0
  404. package/src/tools/shared/diffSummary.js +44 -0
  405. package/src/tools/shared/diffSummary.ts +63 -0
  406. package/src/tools/shared/fileActivity.js +51 -0
  407. package/src/tools/shared/fileActivity.ts +66 -0
  408. package/src/tools/shared/fileMutationBus.js +13 -0
  409. package/src/tools/shared/fileMutationBus.ts +14 -0
  410. package/src/tools/shared/fileState.js +73 -65
  411. package/src/tools/shared/fileState.ts +145 -0
  412. package/src/tools/shared/fileUtils.js +81 -4
  413. package/src/tools/shared/fileUtils.ts +504 -0
  414. package/src/tools/shared/killTree.ts +50 -0
  415. package/src/tools/shared/permanentDeleteGuard.js +26 -0
  416. package/src/tools/shared/permanentDeleteGuard.ts +34 -0
  417. package/src/tools/shared/schemas.ts +20 -0
  418. package/src/tools/shared/toolOutputStore.js +97 -0
  419. package/src/tools/shared/toolOutputStore.ts +110 -0
  420. package/src/tools/skill/skill.js +86 -0
  421. package/src/tools/skill/skill.ts +94 -0
  422. package/src/tools/snip/snip.js +67 -0
  423. package/src/tools/snip/snip.ts +80 -0
  424. package/src/tools/tasks/backgroundTaskService.js +275 -0
  425. package/src/tools/tasks/backgroundTaskService.ts +369 -0
  426. package/src/tools/tasks/processEvidence.js +24 -0
  427. package/src/tools/tasks/processEvidence.ts +34 -0
  428. package/src/tools/tasks/taskManagement.js +163 -0
  429. package/src/tools/tasks/taskManagement.ts +180 -0
  430. package/src/tools/tasks/taskOutput.js +113 -0
  431. package/src/tools/tasks/taskOutput.ts +145 -0
  432. package/src/tools/tasks/taskStop.js +74 -0
  433. package/src/tools/tasks/taskStop.ts +99 -0
  434. package/src/tools/tasks/taskStore.js +46 -0
  435. package/src/tools/tasks/taskStore.ts +77 -0
  436. package/src/tools/terminal/terminalCapture.js +167 -0
  437. package/src/tools/terminal/terminalCapture.ts +179 -0
  438. package/src/tools/trash/trash.js +233 -0
  439. package/src/tools/trash/trash.ts +283 -0
  440. package/src/tools/types.js +1 -1
  441. package/src/tools/types.ts +24 -0
  442. package/src/tools/webbrowser/agentBrowserPath.ts +286 -0
  443. package/src/tools/webbrowser/browser.js +214 -11
  444. package/src/tools/webbrowser/browser.ts +293 -0
  445. package/src/tools/webbrowser/browserControl.js +153 -48
  446. package/src/tools/webbrowser/browserControl.ts +262 -0
  447. package/src/tools/webbrowser/browserDaemon.js +147 -39
  448. package/src/tools/webbrowser/browserDaemon.ts +270 -0
  449. package/src/tools/webbrowser/browserOutcome.js +273 -0
  450. package/src/tools/webbrowser/browserOutcome.ts +306 -0
  451. package/src/tools/webbrowser/browserRunRegistry.js +150 -0
  452. package/src/tools/webbrowser/browserRunRegistry.ts +179 -0
  453. package/src/tools/webbrowser/browserService.js +20 -6
  454. package/src/tools/webbrowser/browserService.ts +56 -0
  455. package/src/tools/webbrowser/browserStream.js +30 -1
  456. package/src/tools/webbrowser/browserStream.ts +216 -0
  457. package/src/tools/webbrowser/browserTabs.js +143 -0
  458. package/src/tools/webbrowser/browserTabs.ts +210 -0
  459. package/src/tools/webbrowser/webbrowser.js +831 -150
  460. package/src/tools/webbrowser/webbrowser.ts +1537 -0
  461. package/src/tools/webfetch/preapproved.ts +274 -0
  462. package/src/tools/webfetch/webfetch.js +24 -23
  463. package/src/tools/webfetch/webfetch.ts +383 -0
  464. package/src/tools/websearch/websearch.js +12 -11
  465. package/src/tools/websearch/websearch.ts +292 -0
  466. package/src/tools/worktree/sessionWorktree.js +128 -0
  467. package/src/tools/worktree/sessionWorktree.ts +158 -0
  468. package/src/tools/write/write.js +27 -44
  469. package/src/tools/write/write.ts +136 -0
  470. package/src/types.ts +960 -0
  471. package/src/ui/App.js +216 -12
  472. package/src/ui/App.tsx +879 -0
  473. package/src/ui/AskQuestion.tsx +300 -0
  474. package/src/ui/InputBox.js +77 -1
  475. package/src/ui/InputBox.tsx +567 -0
  476. package/src/ui/LiveArea.tsx +344 -0
  477. package/src/ui/MessageList.js +27 -6
  478. package/src/ui/MessageList.tsx +559 -0
  479. package/src/ui/ModelPicker.tsx +107 -0
  480. package/src/ui/QueuedMessagesBanner.tsx +51 -0
  481. package/src/ui/Root.js +6 -8
  482. package/src/ui/Root.tsx +100 -0
  483. package/src/ui/SessionPicker.tsx +169 -0
  484. package/src/ui/StatusLine.js +22 -1
  485. package/src/ui/StatusLine.tsx +145 -0
  486. package/src/ui/WorkspacePicker.tsx +84 -0
  487. package/src/ui/advisorCommand.js +54 -0
  488. package/src/ui/advisorCommand.ts +63 -0
  489. package/src/ui/computerCommand.js +19 -0
  490. package/src/ui/computerCommand.ts +35 -0
  491. package/src/ui/figures.ts +45 -0
  492. package/src/ui/hooks/askSlot.ts +112 -0
  493. package/src/ui/hooks/useChat.js +271 -7
  494. package/src/ui/hooks/useChat.ts +1578 -0
  495. package/src/ui/hooks/useInputHistory.ts +235 -0
  496. package/src/ui/hooks/usePasteHandler.ts +220 -0
  497. package/src/ui/hooks/useTerminalSize.ts +41 -0
  498. package/src/ui/hooks/useTextBuffer.ts +108 -0
  499. package/src/ui/hooks/useTokenUsage.ts +44 -0
  500. package/src/ui/liveViewport.ts +189 -0
  501. package/src/ui/markdown.ts +230 -0
  502. package/src/ui/textBuffer.ts +239 -0
  503. package/src/ui/theme.ts +35 -0
  504. package/src/utils/clipboardImage.js +358 -0
  505. package/src/utils/clipboardImage.ts +420 -0
  506. package/src/utils/debugLog.ts +50 -0
  507. package/src/utils/greenRoot.ts +35 -0
  508. package/src/utils/packageRoot.ts +40 -0
  509. package/src/utils/pathContains.js +28 -0
  510. package/src/utils/pathContains.ts +31 -0
  511. package/src/utils/resourcePaths.ts +71 -0
  512. package/src/utils/stripThink.ts +49 -0
  513. package/src/utils/zodToJson.ts +73 -0
  514. package/src/web/browserBridge.js +365 -66
  515. package/src/web/browserBridge.ts +672 -0
  516. package/src/web/protocol.ts +1804 -0
  517. package/vendor/computer-use/arm64-darwin/cu-helperd +0 -0
  518. package/workflows/ppt.yaml +13 -2
  519. package/workflows/wechat-reading-shots.yaml +315 -0
  520. package/workflows/word.yaml +11 -1
  521. package/skills/docx/scripts/office/helpers/__pycache__/__init__.cpython-314.pyc +0 -0
  522. package/skills/docx/scripts/office/helpers/__pycache__/merge_runs.cpython-314.pyc +0 -0
  523. package/skills/docx/scripts/office/helpers/__pycache__/simplify_redlines.cpython-314.pyc +0 -0
  524. package/skills/docx/scripts/office/validators/__pycache__/__init__.cpython-314.pyc +0 -0
  525. package/skills/docx/scripts/office/validators/__pycache__/base.cpython-314.pyc +0 -0
  526. package/skills/docx/scripts/office/validators/__pycache__/docx.cpython-314.pyc +0 -0
  527. package/skills/docx/scripts/office/validators/__pycache__/pptx.cpython-314.pyc +0 -0
  528. package/skills/docx/scripts/office/validators/__pycache__/redlining.cpython-314.pyc +0 -0
  529. package/skills/image-stats/scripts/__pycache__/image_stats.cpython-314.pyc +0 -0
  530. package/skills/image-stats/scripts/__pycache__/image_stats_test.cpython-314.pyc +0 -0
  531. package/skills/ui-design/scripts/__pycache__/assemble_material.cpython-314.pyc +0 -0
  532. package/skills/ui-design/scripts/__pycache__/assemble_material_test.cpython-314.pyc +0 -0
  533. package/skills/ui-design/scripts/__pycache__/chart_sanity_check.cpython-314.pyc +0 -0
  534. package/skills/ui-design/scripts/__pycache__/check_language_policy.cpython-314.pyc +0 -0
  535. package/skills/ui-design/scripts/__pycache__/check_ui_artifact.cpython-314.pyc +0 -0
  536. package/skills/ui-design/scripts/__pycache__/check_ui_artifact_pptx_test.cpython-314.pyc +0 -0
  537. package/skills/ui-design/scripts/__pycache__/deck_pages_check.cpython-314.pyc +0 -0
  538. package/skills/ui-design/scripts/__pycache__/deck_pages_check_test.cpython-314.pyc +0 -0
  539. package/skills/ui-design/scripts/__pycache__/deck_visual_style_check.cpython-314.pyc +0 -0
  540. package/skills/ui-design/scripts/__pycache__/deck_visual_style_check_test.cpython-314.pyc +0 -0
  541. package/skills/ui-design/scripts/__pycache__/design_budget_check.cpython-314.pyc +0 -0
  542. package/skills/ui-design/scripts/__pycache__/design_budget_check_test.cpython-314.pyc +0 -0
  543. package/skills/ui-design/scripts/__pycache__/design_repair_hints.cpython-314.pyc +0 -0
  544. package/skills/ui-design/scripts/__pycache__/design_repair_hints_test.cpython-314.pyc +0 -0
  545. package/skills/ui-design/scripts/__pycache__/design_style_check.cpython-314.pyc +0 -0
  546. package/skills/ui-design/scripts/__pycache__/design_style_check_test.cpython-314.pyc +0 -0
  547. package/skills/ui-design/scripts/__pycache__/draft_coverage_check.cpython-314.pyc +0 -0
  548. package/skills/ui-design/scripts/__pycache__/extract_source_assets.cpython-314.pyc +0 -0
  549. package/skills/ui-design/scripts/__pycache__/extract_source_assets_test.cpython-314.pyc +0 -0
  550. package/skills/ui-design/scripts/__pycache__/generated_image_review_collect.cpython-314.pyc +0 -0
  551. package/skills/ui-design/scripts/__pycache__/generated_image_review_collect_test.cpython-314.pyc +0 -0
  552. package/skills/ui-design/scripts/__pycache__/image_plan_lint.cpython-314.pyc +0 -0
  553. package/skills/ui-design/scripts/__pycache__/image_plan_lint_test.cpython-314.pyc +0 -0
  554. package/skills/ui-design/scripts/__pycache__/image_prompt_rewrite.cpython-314.pyc +0 -0
  555. package/skills/ui-design/scripts/__pycache__/image_prompt_rewrite_test.cpython-314.pyc +0 -0
  556. package/skills/ui-design/scripts/__pycache__/layout_balance.cpython-314.pyc +0 -0
  557. package/skills/ui-design/scripts/__pycache__/layout_balance_test.cpython-314.pyc +0 -0
  558. package/skills/ui-design/scripts/__pycache__/normalize_design_json.cpython-314.pyc +0 -0
  559. package/skills/ui-design/scripts/__pycache__/normalize_design_json_test.cpython-314.pyc +0 -0
  560. package/skills/ui-design/scripts/__pycache__/plan_source_layout.cpython-314.pyc +0 -0
  561. package/skills/ui-design/scripts/__pycache__/plan_source_layout_test.cpython-314.pyc +0 -0
  562. package/skills/ui-design/scripts/__pycache__/resolve_source_hint.cpython-314.pyc +0 -0
  563. package/skills/ui-design/scripts/__pycache__/resolve_source_hint_test.cpython-314.pyc +0 -0
  564. package/skills/ui-design/scripts/__pycache__/resolve_source_input.cpython-314.pyc +0 -0
  565. package/skills/ui-design/scripts/__pycache__/resolve_source_input_test.cpython-314.pyc +0 -0
  566. package/skills/ui-design/scripts/__pycache__/scaffold_ui_artifact.cpython-314.pyc +0 -0
  567. package/skills/ui-design/scripts/__pycache__/source_usage_check.cpython-314.pyc +0 -0
  568. package/skills/ui-design/scripts/__pycache__/source_usage_check_test.cpython-314.pyc +0 -0
  569. package/skills/ui-design/scripts/__pycache__/text_readability_pixel.cpython-314.pyc +0 -0
  570. package/skills/ui-design/scripts/__pycache__/visual_quality_gate.cpython-314.pyc +0 -0
  571. package/skills/ui-design/scripts/__pycache__/visual_quality_gate_test.cpython-314.pyc +0 -0
  572. /package/skills/ai-image/scripts/{generate_test.mjs → generate.selftest.mjs} +0 -0
  573. /package/skills/ai-image/scripts/{generate_from_plan_test.mjs → generate_from_plan.selftest.mjs} +0 -0
package/src/types.ts ADDED
@@ -0,0 +1,960 @@
1
+ /**
2
+ * ============================================================
3
+ * src/types.ts —— 全局核心类型定义
4
+ * ------------------------------------------------------------
5
+ * 这个文件是项目的"类型字典",所有模块都从这里 import 类型。
6
+ * 新手阅读建议:从上往下,每个类型上方有"何时用 / 为何这么设计"的注释。
7
+ *
8
+ * 设计原则:
9
+ * - 形状跟 OpenAI Chat Completions API 对齐(多 provider 兼容性最好)
10
+ * - 不用 class,全用 interface / type alias(更轻、更易读)
11
+ * - 一切尽量简单:能用基本类型就不引第三方
12
+ * ============================================================
13
+ */
14
+
15
+ import type { z } from 'zod';
16
+ import type { AskQuestionSpec, AskQueueState, AskSource } from './askBridge.js';
17
+ import type { ToolGate } from './toolGate.js';
18
+
19
+ // ---------------- 1. 消息 (Message) ----------------
20
+ //
21
+ // Message 是 LLM 对话历史的最小单元,会被原样发到 LLM,也会被压缩、保存、回放。
22
+ // 我们采用 OpenAI Chat Completions 的形态(role + content + tool_calls/tool_call_id),
23
+ // 因为 DeepSeek、月之暗面、智谱、火山、OpenRouter 等绝大多数中国 / 国际 provider
24
+ // 都按此协议兼容。
25
+ //
26
+ // 四种 role:
27
+ // system —— 系统提示词,固定放在最前面
28
+ // user —— 用户输入
29
+ // assistant —— 模型回答(可能含 tool_calls 表示要调工具)
30
+ // tool —— 工具执行结果,必须配对一个 tool_call_id
31
+
32
+ /** 助手要调用的"一次工具调用";arguments 是 JSON 字符串(OpenAI 协议如此规定)。 */
33
+ export interface ToolCall {
34
+ /** 这次调用的唯一 id(OpenAI 返回的,要原样回传到 tool 消息的 tool_call_id) */
35
+ id: string;
36
+ type: 'function';
37
+ function: {
38
+ name: string;
39
+ /** JSON 字符串!不是对象。需要 JSON.parse 后再交给 Zod 校验 */
40
+ arguments: string;
41
+ };
42
+ }
43
+
44
+ // ---------------- 1.1 多模态内容块 ----------------
45
+ //
46
+ // OpenAI Chat Completions 兼容的多模态输入使用 content 数组:
47
+ // [{ type: 'text', text: '...' }, { type: 'image_url', image_url: { url } }]
48
+ // 这里保持协议字段名,不做自定义抽象,方便 MiniMax / 火山 / Kimi 直接消费。
49
+
50
+ export type ImageDetail = 'low' | 'default' | 'high';
51
+
52
+ export interface ChatImageUrl {
53
+ url: string;
54
+ detail?: ImageDetail;
55
+ max_long_side_pixel?: number;
56
+ }
57
+
58
+ export interface ChatVideoUrl {
59
+ url: string;
60
+ detail?: ImageDetail;
61
+ fps?: number;
62
+ }
63
+
64
+ export type ChatContentPart =
65
+ | { type: 'text'; text: string }
66
+ | { type: 'image_url'; image_url: ChatImageUrl }
67
+ // v1 只正式暴露图片入口;视频先保留协议类型,后续接 Files API / fps 等策略。
68
+ | { type: 'video_url'; video_url: ChatVideoUrl };
69
+
70
+ export interface ImageInputSpec {
71
+ source: string;
72
+ detail?: ImageDetail;
73
+ maxLongSidePixel?: number;
74
+ }
75
+
76
+ /**
77
+ * 用户消息关联的附件展示元数据。
78
+ *
79
+ * content bytes、绝对路径和访问令牌不属于会话历史;宿主打开历史时可按 id
80
+ * 临时补充 previewUrl。LLM client 会在序列化请求前剥离整个 attachments 字段。
81
+ */
82
+ export interface MessageAttachmentRef {
83
+ id: string;
84
+ name: string;
85
+ mime: string;
86
+ size: number;
87
+ sha256?: string;
88
+ previewUrl?: string;
89
+ }
90
+
91
+ /** Stable, credential-free reference to an element selected in the browser. */
92
+ export interface MessageBrowserReference {
93
+ id: string;
94
+ url: string;
95
+ tabId: string;
96
+ selector: string;
97
+ snapshotRef?: string;
98
+ tag?: string;
99
+ role?: string;
100
+ accessibleName?: string;
101
+ text?: string;
102
+ attributes: Record<string, string>;
103
+ boundingBox?: { x: number; y: number; width: number; height: number };
104
+ pageRevision: string;
105
+ capturedAt: number;
106
+ }
107
+
108
+ /**
109
+ * 所有 Message variant 共享的可选字段。
110
+ *
111
+ * timestamp(v2 新增):本地 unix millis(Date.now())。
112
+ * - 用途:UI 渲染 turn 边界横线(duration / 时间显示)
113
+ * - 由 loop.ts 在 push 进 history 时填充
114
+ * - **不发给 LLM**:client.ts 在序列化 messages 时剥掉此字段(避免破坏 OpenAI 协议合规)
115
+ * - 旧 last-context.json 不带此字段时 fallback Date.now()
116
+ */
117
+ export type Message = (
118
+ | {
119
+ role: 'system';
120
+ content: string;
121
+ timestamp?: number;
122
+ /**
123
+ * v2.x 新增:UI 临时提示(slash 命令输出等),不持久化、不算作真正的 system prompt。
124
+ *
125
+ * - saveContext(persistContext.ts)写盘前过滤掉 _ephemeral=true 的 system 消息
126
+ * - MessageList 识别此标记走暗灰单行样式(其他 system 消息保持 hide)
127
+ * - 其他场景(LLM 调用等)暂时不过滤;短消息无害,下个版本再做 runQuery 入参过滤
128
+ * - 已知限制:本期 LLM 收到 ephemeral 消息(不影响功能,仅噪声)
129
+ */
130
+ _ephemeral?: true;
131
+ }
132
+ | {
133
+ role: 'user';
134
+ content: string | ChatContentPart[];
135
+ attachments?: MessageAttachmentRef[];
136
+ browserReferences?: MessageBrowserReference[];
137
+ timestamp?: number;
138
+ }
139
+ | {
140
+ role: 'assistant';
141
+ /** 当 tool_calls 非空时 content 通常为 null(OpenAI 协议) */
142
+ content: string | null;
143
+ tool_calls?: ToolCall[];
144
+ /**
145
+ * 思维链字段:DeepSeek-R1 / MiniMax 推理拆分模式(reasoning_split=True)/
146
+ * OpenRouter 等会把模型的"思考"内容放在这里。
147
+ *
148
+ * 必须在多轮工具调用中把上一轮的 reasoning 原样回传,否则模型会"失忆"
149
+ * (断了思维链)。我们的策略是把流式收到的 reasoning 累积后挂在 assistant
150
+ * 消息上,下一轮请求时连同 messages 整个 JSON.stringify 发回去,未知字段
151
+ * 普通 OpenAI 兼容 provider 会忽略,需要它的 provider 会用上。
152
+ *
153
+ * 字段命名兼容多 provider:
154
+ * - reasoning_content: DeepSeek-R1 风格(字符串)
155
+ * - reasoning_details: MiniMax / OpenRouter 风格(结构化数组)
156
+ * - reasoning: 少数 fork 的字符串别名
157
+ */
158
+ reasoning_content?: string;
159
+ reasoning_details?: unknown[];
160
+ reasoning?: string;
161
+ timestamp?: number;
162
+ }
163
+ | {
164
+ role: 'tool';
165
+ /** 工具的输出文本(成功时是结果,失败时是 error 字符串) */
166
+ content: string;
167
+ /** 必须对应上面 assistant 消息里某个 ToolCall 的 id */
168
+ tool_call_id: string;
169
+ /** 本地展示元数据;发送 Provider 前会剥离。 */
170
+ display_metadata?: ToolResultMetadata;
171
+ timestamp?: number;
172
+ }
173
+ ) & {
174
+ /**
175
+ * id(v2.x 终极重构新增):本地唯一的、永不改变的身份标识(通常是 UUID)。
176
+ * - 用途:React TUI 列表 commit 阶段,作为 <Static> 稳定不动的 Key 彻底拦截重绘。
177
+ * - 不发给 LLM:client.ts 在发送给 LLM 序列化消息前自动剔除。
178
+ */
179
+ id?: string;
180
+ };
181
+
182
+ // ---------------- 2. 工具 (Tool) ----------------
183
+ //
184
+ // 这是 minimal-agent 对 kakadeai Tool 接口的极简化版本。
185
+ // kakadeai 原版有 ~30 个字段(UI 渲染、权限、telemetry...),我们只保留 7 个核心字段。
186
+ // 凡是模型能"看到"的部分(name / description / inputSchema),都和 kakadeai 一字不差,
187
+ // 这样 prompt 工程的成果可以复用。
188
+
189
+ /** 工具执行结果:要么成功(输出字符串),要么失败(错误描述)。 */
190
+ export interface AgentResultMetadata {
191
+ kind: 'agent';
192
+ agentType: 'explore' | 'general';
193
+ description: string;
194
+ agentId?: string;
195
+ status?: 'running' | 'completed' | 'failed' | 'stopped' | 'interrupted';
196
+ isolation: 'none' | 'worktree';
197
+ turns: number;
198
+ toolCalls: number;
199
+ failedToolCalls: number;
200
+ /** 子任务从进入协调器到结束的总耗时。 */
201
+ durationMs: number;
202
+ changedFiles: string[];
203
+ /**
204
+ * 代码调研类子任务的「实际覆盖文件」清单(从 tool call 历史提取)。
205
+ * 用于父 agent / 宿主做覆盖度自检;非调研类可能为空。
206
+ */
207
+ coveredFiles?: string[];
208
+ worktree?: {
209
+ id: string;
210
+ branch: string;
211
+ baseSha: string;
212
+ status: 'ready' | 'applied' | 'discarded' | 'needs_attention';
213
+ };
214
+ }
215
+
216
+ export type FileActivityKind = 'read' | 'created' | 'modified' | 'generated' | 'deleted';
217
+ export type FileVerification = 'passed' | 'failed' | 'not_run';
218
+ export type ConversationFilePurpose = 'source' | 'deliverable' | 'support';
219
+ export interface FilePatchSummary {
220
+ unifiedDiff?: string;
221
+ beforeHash?: string;
222
+ afterHash: string;
223
+ additions: number;
224
+ deletions: number;
225
+ truncated: boolean;
226
+ omittedReason?: 'too_large';
227
+ }
228
+
229
+ /** Structured local file output. Paths are always workspace-relative. */
230
+ export interface FileActivityMetadata {
231
+ kind: 'file_activity';
232
+ files: Array<{
233
+ relativePath: string;
234
+ activity: FileActivityKind;
235
+ sha256?: string;
236
+ mime?: string;
237
+ verification: FileVerification;
238
+ purpose: ConversationFilePurpose;
239
+ patch?: FilePatchSummary;
240
+ }>;
241
+ }
242
+
243
+ export interface DeliverableManifest {
244
+ runId?: string;
245
+ conversationKey?: string;
246
+ status: 'draft' | 'verified' | 'final';
247
+ summary: string;
248
+ files: Array<{
249
+ relativePath: string;
250
+ sha256?: string;
251
+ mime?: string;
252
+ label?: string;
253
+ size?: number;
254
+ modifiedAt?: number;
255
+ sourceToolCallId?: string;
256
+ verification: FileVerification;
257
+ purpose: 'deliverable';
258
+ }>;
259
+ links?: Array<{ url: string; title?: string }>;
260
+ browserEvidence?: Array<{ tabId: string; url: string; screenshotId?: string }>;
261
+ warnings: string[];
262
+ }
263
+
264
+ /** File-search candidates. Discovery alone never makes a file important to a conversation. */
265
+ export interface FileDiscoveryMetadata {
266
+ kind: 'file_discovery';
267
+ files: Array<{
268
+ relativePath: string;
269
+ size: number;
270
+ modifiedAt: number;
271
+ }>;
272
+ }
273
+
274
+ /** A formal result published to the user by PresentResult. */
275
+ export interface ResultManifestMetadata {
276
+ kind: 'result_manifest';
277
+ manifest: DeliverableManifest;
278
+ }
279
+
280
+ export type ProcessCommandKind = 'test' | 'typecheck' | 'build' | 'check' | 'other';
281
+ export type ProcessExecutionStatus = 'started' | 'running' | 'completed' | 'failed' | 'stopped';
282
+
283
+ /** Structured process state shared by Bash, PowerShell, TaskOutput and the evidence ledger. */
284
+ export interface ProcessExecutionMetadata {
285
+ kind: 'process_execution';
286
+ shell: 'bash' | 'powershell';
287
+ mode: 'foreground' | 'background';
288
+ taskId?: string;
289
+ commandKind: ProcessCommandKind;
290
+ status: ProcessExecutionStatus;
291
+ exitCode?: number | null;
292
+ }
293
+
294
+ /** Agent 子任务的结构化阶段进度;仅供宿主展示,不写入会话历史或发送给 LLM。 */
295
+ export interface SubagentProgress {
296
+ kind: 'subagent';
297
+ phase: 'queued' | 'preparing' | 'analyzing' | 'using_tool' | 'drafting' | 'waiting_owner';
298
+ queuePosition?: number;
299
+ activeCount?: number;
300
+ maxConcurrent?: number;
301
+ turn?: number;
302
+ toolName?: string;
303
+ toolDescription?: string;
304
+ outputChars?: number;
305
+ }
306
+
307
+ export type ToolProgressDetail = SubagentProgress;
308
+
309
+ export type ToolResultMetadata =
310
+ | AgentResultMetadata
311
+ | FileActivityMetadata
312
+ | FileDiscoveryMetadata
313
+ | ResultManifestMetadata
314
+ | ProcessExecutionMetadata;
315
+
316
+ export type ToolResult =
317
+ | {
318
+ ok: true;
319
+ content: string;
320
+ metadata?: ToolResultMetadata;
321
+ recovery?: 'none' | 'retry' | 'change-input' | 'user-action';
322
+ sensitivity?: 'public' | 'local' | 'sensitive';
323
+ visionImages?: ImageInputSpec[];
324
+ visionNote?: string;
325
+ }
326
+ | {
327
+ ok: false;
328
+ error: string;
329
+ metadata?: ToolResultMetadata;
330
+ recovery?: 'none' | 'retry' | 'change-input' | 'user-action';
331
+ sensitivity?: 'public' | 'local' | 'sensitive';
332
+ visionImages?: ImageInputSpec[];
333
+ visionNote?: string;
334
+ };
335
+
336
+ // visionImages:工具想让(视觉)模型「亲眼看一下」的图像(如浏览器关键节点实况截图)。
337
+ // 主循环在回填工具结果后,把它们组装成一条带图的 user 消息喂给模型自我核验(见 loop.ts)。
338
+ // 通用能力,不绑任何具体工具;模型不支持识图时主循环丢弃、优雅降级。
339
+ //
340
+ // ★ 成功和失败**两个分支都能带图**,因为「这步成不成」与「要不要看图」是两个正交
341
+ // 维度——而出错时那张截图恰恰最该看(权限弹窗、验证拦截、意外的前台窗口,全靠
342
+ // 它才看得见)。历史坑:失败分支曾经不带图,于是 ComputerUse 为了附上错误现场
343
+ // 把失败**返回成 ok:true**。后果远超「注释不准」:前端显示成功、失败计数永远归零、
344
+ // 连续失败熔断因此从未触发过一次(那时它还建在遥测日志上;现已内移到
345
+ // ComputerUseService,按运行 + 动作指纹隔离)。
346
+ // 让类型能表达真话,工具才不必撒谎。
347
+ //
348
+ // visionNote:跟这批图一起给模型的一句说明,拼在通用核验提示之后。
349
+ // 内核不需要(也不应该)知道图是什么——「这几张是 1 秒间隔的连续帧」「淡化区只是
350
+ // 没变化、不是被禁用」这类语义只有工具自己清楚,而看图的人不知道就会误读。
351
+ // 与 Tool.gateRequest 同构:机制在内核,语义在工具。
352
+
353
+ /**
354
+ * 工具调用时的环境态透传。与结构化输入分开,不会暴露给模型。
355
+ * 需要这些上下文的工具实现 `callWithContext()`,executeTool 统一调度,
356
+ * 避免按工具名写特判分支。
357
+ */
358
+ export interface ToolCallContext {
359
+ /** 当前 runQuery() 主循环的运行时历史(含 system/user/assistant/tool 消息)。 */
360
+ history?: readonly Message[];
361
+ /** Per-conversation mutable state; file freshness and background tasks must not leak across sessions. */
362
+ sessionState?: import('./session/sessionState.js').SessionState;
363
+ /** 同一用户回合内共享的 Advisor 调用计数,防止模型循环咨询。 */
364
+ advisorCalls?: { used: number; max: number };
365
+ /** 区分主模型自动咨询与用户显式 /advisor ask。 */
366
+ advisorInvocation?: 'agent' | 'manual';
367
+ /**
368
+ * 主循环使用的 provider —— Agent 等「工具内部再起子查询」的派生工具用它
369
+ * 跑嵌套 runQuery(子 agent 与主 agent 同一模型,不另配凭据)。
370
+ */
371
+ provider?: Provider;
372
+ /**
373
+ * 主循环的工具执行闸门 —— 子 agent 继承同一审批策略(否则可写子 agent
374
+ * 就成了绕过宿主审批的后门)。type-only import,toolGate.ts 零依赖无环。
375
+ */
376
+ toolGate?: ToolGate;
377
+ /**
378
+ * 本次调用的 tool_call id,供调用级进度事件精确关联 UI 卡片。
379
+ */
380
+ toolCallId?: string;
381
+ /** 同一用户回合内共享的 Agent 子任务派生计数,防失控 fan-out(仿 advisorCalls)。 */
382
+ agentCalls?: { used: number; max: number };
383
+ subagentConfig?: {
384
+ maxConcurrent: number;
385
+ timeoutMs: number;
386
+ exploreMaxTurns: number;
387
+ generalMaxTurns: number;
388
+ defaultWriteIsolation: 'none' | 'worktree';
389
+ };
390
+ /** 上报长时工具的最新进度;宿主缺席时由 loop 提供的实现安全降级。 */
391
+ reportProgress?: (message: string, detail?: ToolProgressDetail) => void;
392
+ /** 当前用户原始输入及其稳定身份,供需要证据校验的受控工具使用。 */
393
+ currentUserInput?: string;
394
+ userMessageId?: string;
395
+ promptCache?: PromptCacheContext;
396
+ sessionId?: string;
397
+ workspaceId?: string;
398
+ /** Trusted working directory for this run; avoids process-global cwd leakage across Desktop sessions. */
399
+ cwd?: string;
400
+ /** 本机记忆权限由宿主明确声明;不可信宿主必须为 denied。 */
401
+ memoryAccess?: import('./runtime/agentRuntimeContext.js').MemoryAccessInput;
402
+ /**
403
+ * Browser actions are scoped to the owning conversation/run by the host.
404
+ * `supervised` 由宿主声明「存在可见浏览器 + 真人可接管/resume」(仅 Desktop 置 true):
405
+ * 内核据此决定遇到 CAPTCHA/登录等关卡时能否交人处理;缺省/未监督(CLI -p、TUI、gateway)
406
+ * 绝不阻塞等人,改为据实非阻塞返回。
407
+ */
408
+ browserRun?: {
409
+ conversationKey: string;
410
+ runId: string;
411
+ profileId?: string;
412
+ supervised?: boolean;
413
+ /**
414
+ * Host-issued grants for this user turn. Page content can never add grants.
415
+ * Observe/interact are the normal supervised-browser baseline; upload and
416
+ * final submit must originate from the user's task.
417
+ */
418
+ grants?: import('./tools/webbrowser/browserRunRegistry.js').BrowserActionGrant[];
419
+ taskGrantId?: string;
420
+ /** Canonical roots from which this browser run may upload files. */
421
+ allowedUploadRoots?: string[];
422
+ };
423
+ /**
424
+ * Host-issued native desktop-control scope. Never derived from model arguments.
425
+ *
426
+ * ⚠️ **有意的例外,别当成漏网之鱼**:这里(以及上面 `browserRun.grants`)确实
427
+ * `import` 了具体工具的类型。内核对它**一个字段都不读**,纯透传给工具,
428
+ * 之所以不换成结构子集或 `unknown`:那会逼工具侧在几十处 narrow/cast,
429
+ * 把类型安全从"编译器保证"降级成"人记得写对",代价远大于收益。
430
+ *
431
+ * 真正必须守住的那条线是 **`src/web/protocol.ts` 零工具依赖** —— 它是
432
+ * desktop 与 server 两个外部消费方的类型真值,一个工具的内部重构不该顺着
433
+ * 协议波及它们。那条线已改为「协议声明 `ComputerObservation` 结构契约、
434
+ * 工具编译期断言兼容」,并由 `test/kernelPurity.test.ts` 守着。
435
+ */
436
+ computerRun?: import('./tools/computeruse/protocol.js').ComputerUseRunContext;
437
+ /**
438
+ * Trusted host bridge for pausing a native Computer Use action while the
439
+ * owner handles credentials, OTP, CAPTCHA, permissions, or a manual
440
+ * takeover. It is never serialized to the native helper or exposed to the
441
+ * model.
442
+ */
443
+ computerIntervention?: {
444
+ inspect(
445
+ state: import('./tools/computeruse/protocol.js').ComputerState,
446
+ signal?: AbortSignal,
447
+ ): Promise<{
448
+ resolution: 'none' | 'resumed' | 'cancelled';
449
+ state?: import('./tools/computeruse/protocol.js').ComputerState;
450
+ }>;
451
+ pause(
452
+ reason: import('./humanIntervention.js').HumanInterventionReason,
453
+ summary: string,
454
+ signal?: AbortSignal,
455
+ ): Promise<{
456
+ resolution: 'resumed' | 'cancelled';
457
+ state?: import('./tools/computeruse/protocol.js').ComputerState;
458
+ }>;
459
+ };
460
+ }
461
+
462
+ export interface Tool<TInput = unknown> {
463
+ /** 工具名,必须和 kakadeai 一致:'Read' / 'Edit' / 'Write' / 'Glob' / 'Grep' */
464
+ name: string;
465
+
466
+ /**
467
+ * 给模型看的描述(会出现在 LLM 的 tools 字段里)。
468
+ * 可以是静态字符串,也可以是函数(函数版本方便注入运行时信息,如 cwd)。
469
+ */
470
+ description: string | (() => string);
471
+
472
+ /** Zod schema:模型返回的 arguments JSON 会用它校验和解析 */
473
+ inputSchema: z.ZodType<TInput>;
474
+
475
+ /**
476
+ * JSON Schema 形式的参数描述,会原样塞进 LLM 请求的 tools 字段。
477
+ * 我们手写而不是从 Zod 自动转换,原因:
478
+ * - 零依赖(不用引 zod-to-json-schema)
479
+ * - 教学清晰:学生能直接看到"模型看到的是什么"
480
+ * 与 Zod schema 保持一致是开发者的责任(可在测试里断言)。
481
+ */
482
+ parameters: object;
483
+
484
+ /** 是否只读?(read/glob/grep = true;edit/write = false)—— 仅用于元信息 */
485
+ isReadOnly?: boolean;
486
+
487
+ /** 多个调用是否能并发执行?(read/glob/grep = true;edit/write = false) */
488
+ isConcurrencySafe?: boolean;
489
+
490
+ /** 输出超过这个字符数会被截断(防止把巨大文件灌进上下文) */
491
+ maxResultSizeChars?: number;
492
+
493
+ /** Synchronous host/runtime probe used before the tool is shown to the model. */
494
+ resolveAvailability?(
495
+ runtime: import('./runtime/agentRuntimeContext.js').AgentRuntimeContext,
496
+ ): ToolAvailability;
497
+
498
+ /**
499
+ * 中断行为(方法,支持动态判断):
500
+ * - 'cancel': 可以安全取消该工具执行,丢弃结果
501
+ * - 'block': 必须执行完该工具,新输入排队等待
502
+ * 缺省/未实现 = 'block'(安全默认)
503
+ */
504
+ interruptBehavior?(): 'cancel' | 'block';
505
+
506
+ /**
507
+ * 给宿主的 ToolGate 决策补充工具侧语义。
508
+ *
509
+ * ⚠️ `input` 可能是 `undefined` —— **参数没通过 zod 校验时也会调它**。
510
+ * 因为「参数烂掉」不等于「身份不明」:运行身份来自宿主注入的 context,
511
+ * 与模型给的参数无关。这种情况下工具应当**照常给出身份**(runContext),
512
+ * 只省略依赖参数的部分(action / isReadOnly),让参数错误由工具层如实报出来。
513
+ *
514
+ * 实测代价:此前参数校验失败时整个 gateRequest 被跳过 → 闸门请求里没有
515
+ * runContext → 桌面端报「运行身份与当前宿主会话不匹配」,把参数格式问题
516
+ * 讲成权限问题,照那个方向根本查不下去。
517
+ */
518
+ gateRequest?(
519
+ input: TInput | undefined,
520
+ context: ToolCallContext,
521
+ ): Partial<Pick<import('./toolGate.js').ToolGateRequest, 'isReadOnly' | 'runContext' | 'action'>>;
522
+
523
+ /**
524
+ * 真正干活的函数。
525
+ * @param input 已被 Zod 校验通过的参数
526
+ * @param signal 用于响应 Ctrl+C 等中断
527
+ */
528
+ call(input: TInput, signal?: AbortSignal): Promise<ToolResult>;
529
+
530
+ /** 仅需要会话运行态的工具实现;普通工具继续使用 call。 */
531
+ callWithContext?(
532
+ input: TInput,
533
+ signal: AbortSignal | undefined,
534
+ context: ToolCallContext,
535
+ ): Promise<ToolResult>;
536
+ }
537
+
538
+ export interface ToolAvailability {
539
+ available: boolean;
540
+ /** Must change when config, executable resolution, or another availability input changes. */
541
+ signature: string;
542
+ }
543
+
544
+ // ---------------- 3. Provider 配置 ----------------
545
+ //
546
+ // minimal-agent 从 .env 环境变量读取配置:
547
+ // MINIMAL_AGENT_BASE_URL - API 地址
548
+ // MINIMAL_AGENT_API_KEY - API key
549
+ // MINIMAL_AGENT_MODEL - 模型名
550
+ // MINIMAL_AGENT_PROVIDER - 友好名称(可选,默认 "env")
551
+ // MINIMAL_AGENT_CONTEXT_WINDOW - 上下文窗口(可选,默认 128000)
552
+
553
+ export interface Provider {
554
+ /** 友好名(仅展示用),如 "deepseek" */
555
+ name: string;
556
+
557
+ /** API 完整端点 URL,如 "https://api.deepseek.com/v1/chat/completions" */
558
+ baseURL: string;
559
+
560
+ /** API key(敏感信息,用户自己填) */
561
+ apiKey: string;
562
+
563
+ /** 模型 id,如 "deepseek-chat" */
564
+ model: string;
565
+
566
+ /** 该模型的上下文窗口(token 数);用于压缩阈值计算 */
567
+ contextWindow: number;
568
+
569
+ /**
570
+ * 自动压缩触发阈值占 contextWindow 的比例(0~1,默认 0.85)。
571
+ *
572
+ * 阈值 = min(contextWindow × compactRatio, contextWindow − 输出 buffer),**provider 无关**:
573
+ * 纯按 contextWindow 缩放,适配所有模型,不绑任何 provider。
574
+ *
575
+ * 可经 .env `MINIMAL_AGENT_COMPACT_RATIO` 或 webchat 设置页配置;缺省时 fallback
576
+ * DEFAULT_COMPACT_RATIO(0.85)。**测试时临时调小(如 0.2)即可轻松触发自动压缩验证。**
577
+ */
578
+ compactRatio?: number;
579
+
580
+ /**
581
+ * 单次 LLM 响应的输出 token 上限(OpenAI `max_tokens`)。
582
+ *
583
+ * **为什么必须显式发**:很多 OpenAI 兼容 provider 的默认输出上限很小——实测火山
584
+ * `doubao-seed-2.0-pro` 默认就 4096,不发 max_tokens 时长输出(如一次性写整篇 PLAN.md)
585
+ * 会在 4096 处被 `finish_reason=length` 硬截断,被引擎判为「截断不可信」而 halt。
586
+ * 它是**上限不是预订**:设大不额外花钱(实测豆包接受到 ≥131072 仍按需返回),只是兜住
587
+ * 小默认值的 provider。可经 .env `MINIMAL_AGENT_MAX_TOKENS` 或 saved config 配置;
588
+ * 缺省时由 config 层给 DEFAULT_MAX_TOKENS。个别 provider 若拒绝过大的值,client 会
589
+ * 自动去掉 max_tokens 重发降级(见 client.ts)。
590
+ */
591
+ maxTokens?: number;
592
+
593
+ /**
594
+ * 请求协议格式:'openai'(Chat Completions,默认)| 'anthropic'(Messages API)。
595
+ * 缺省当 'openai'——兼容旧版只产出 OpenAI 格式对象的 env 自举路径。见 client.ts。
596
+ */
597
+ apiFormat?: 'openai' | 'anthropic';
598
+
599
+ /**
600
+ * 该模型是否支持识图(多模态视觉)。resolveProvider 从所选 ModelConfig 归一成真布尔
601
+ * (条目未显式设则为 true)。发图类消费方(浏览器截图核验等)严格按 `=== true` 判定:
602
+ * 故未经 resolveProvider 的 provider(如纯 env 自举,此处为 undefined)会被当作「不支持」——
603
+ * 保守地不给可能非视觉的端点发图(免触发 400),并优雅降级(不截、不假装核验)。
604
+ */
605
+ supportsVision?: boolean;
606
+ promptCache?: PromptCacheConfig;
607
+ }
608
+
609
+ export type PromptCacheMode = 'auto' | 'session-key' | 'disabled';
610
+
611
+ export interface PromptCacheConfig {
612
+ mode: PromptCacheMode;
613
+ }
614
+
615
+ export interface PromptCacheContext {
616
+ /** Opaque SHA-256 routing key safe to send to a provider. */
617
+ scopeKey: string;
618
+ /** Local-only identity used to derive child scopes; never serialized. */
619
+ conversationKey: string;
620
+ }
621
+
622
+ export interface PromptCacheUsage {
623
+ reported: boolean;
624
+ promptTokens?: number;
625
+ cacheReadTokens?: number;
626
+ cacheMissTokens?: number;
627
+ cacheWriteTokens?: number;
628
+ }
629
+
630
+ export interface RunEvidenceEntry {
631
+ toolName: string;
632
+ callHash: string;
633
+ ok: boolean;
634
+ resultHash: string;
635
+ kind: 'tool' | 'file' | 'delivery' | 'verification' | 'web';
636
+ paths?: string[];
637
+ urls?: string[];
638
+ verification?: FileVerification;
639
+ }
640
+
641
+ export interface RunEvidenceLedger {
642
+ toolCalls: number;
643
+ failedToolCalls: number;
644
+ entries: RunEvidenceEntry[];
645
+ }
646
+
647
+ export interface HarnessDiagnostics {
648
+ promptVersion: 'minimal-agent:prompt:v2';
649
+ basePromptHash: string;
650
+ enabledPolicyIds?: string[];
651
+ enabledCapabilities: string[];
652
+ effectiveToolSetSignature?: string;
653
+ tokenBudget?: {
654
+ contextWindow: number;
655
+ inputLimit: number;
656
+ reservedOutput: number;
657
+ historyTokens: number;
658
+ toolTokens: number;
659
+ transientTokens: number;
660
+ totalInputTokens: number;
661
+ overBudget: boolean;
662
+ };
663
+ stopReason?: 'complete' | 'max_turns' | 'stalled' | 'aborted' | 'error';
664
+ evidence?: RunEvidenceLedger;
665
+ }
666
+
667
+ // ---------------- 4. LLM 流式事件 ----------------
668
+ //
669
+ // LLM 客户端是 AsyncGenerator,逐 chunk yield 这些事件。
670
+ // 上层(loop.ts)按事件类型组装最终的 assistant 消息。
671
+
672
+ export type LlmStreamEvent =
673
+ /** 文本增量(assistant 在打字) */
674
+ | { type: 'text_delta'; delta: string }
675
+ /** 工具调用增量(OpenAI 协议下 tool_calls 也是分片返回的) */
676
+ | {
677
+ type: 'tool_call_delta';
678
+ /** 这是当前 tool_calls 数组里的第几个?(多工具并行调用时) */
679
+ index: number;
680
+ id?: string;
681
+ name?: string;
682
+ argumentsDelta?: string;
683
+ }
684
+ /**
685
+ * 思维链增量(DeepSeek-R1 / MiniMax / OpenRouter)。
686
+ * field 表示 provider 用的是哪个字段名(决定累积时往哪个 key 上拼)。
687
+ * `reasoning_details` 是结构化数组,按片追加;其它两个是字符串增量。
688
+ */
689
+ | {
690
+ type: 'reasoning_delta';
691
+ field: 'reasoning_content' | 'reasoning' | 'reasoning_details';
692
+ /** 字符串增量(reasoning_content / reasoning) */
693
+ delta?: string;
694
+ /** 数组增量(reasoning_details) */
695
+ items?: unknown[];
696
+ }
697
+ /**
698
+ * 流结束。
699
+ *
700
+ * promptTokens(v2.x 新增,可选):本轮请求的**真实** prompt token 数。
701
+ * - 仅当 provider 支持并返回 usage(client 开 `stream_options.include_usage`)时才有;
702
+ * 拿不到(老 provider / 关闭逃生开关)时为 undefined。
703
+ * - 用途:loop 把它接住作为自动压缩的「真实 usage 闭环」权威判据,
704
+ * 校正本地估算对工具 schema / 中文的系统性低估;无此值时调用方 fallback 估算。
705
+ * - ⚠️ 语义是「本轮 prompt 的**总** token 数,含命中缓存的部分」。OpenAI 协议天然如此
706
+ * (cached_tokens 是 prompt_tokens 的子集明细);Anthropic 协议的 input_tokens **不含**
707
+ * 缓存部分,故其解析器必须自行把三段相加后再填进来,否则开启缓存后自动压缩会严重低估。
708
+ *
709
+ * cachedPromptTokens / cacheWriteTokens(可选,纯观测):
710
+ * - cachedPromptTokens = promptTokens 中**命中缓存**的部分(读缓存,计费打折)
711
+ * - cacheWriteTokens = 本轮**写入**缓存的部分(Anthropic 显式打点才有;OpenAI 自动
712
+ * 缓存不单独报告写入量,恒为 undefined)
713
+ * - 只用于展示命中率与验证缓存是否真的生效,不参与任何控制流决策。
714
+ */
715
+ | {
716
+ type: 'done';
717
+ stopReason: 'stop' | 'tool_calls' | 'length' | 'unknown' | 'aborted';
718
+ promptTokens?: number;
719
+ cachedPromptTokens?: number;
720
+ cacheMissTokens?: number;
721
+ cacheWriteTokens?: number;
722
+ promptCacheUsage?: PromptCacheUsage;
723
+ }
724
+ /** 用户主动中断(ESC/Ctrl+C);不显示红色错误,只显示一行提示 */
725
+ | { type: 'interrupted' };
726
+
727
+ // ---------------- 5. Loop 对外的事件 ----------------
728
+ //
729
+ // loop.runQuery() 是 AsyncGenerator,UI 通过 for await 拿这些事件并把它们映射到 React state。
730
+
731
+ /**
732
+ * 工作过程显示阶段标签(UI 的 LiveArea 据此选择文字 / 决定是否隐藏整面板)。
733
+ *
734
+ * idle —— 当前没有任何工作(隐藏 LiveArea)
735
+ * thinking —— 已发请求,等首个 token(reasoning 或 text 或 tool_call)
736
+ * streaming —— 模型在流式输出最终回答文本
737
+ * tool_executing —— 至少一个工具在跑(并行时栈式显示多个)
738
+ * compacting —— 正在跑自动 / reactive / 手动压缩
739
+ */
740
+ export type ProgressStage =
741
+ | 'idle'
742
+ | 'thinking'
743
+ | 'streaming'
744
+ | 'tool_executing'
745
+ | 'compacting';
746
+
747
+ export type CompactionMode = 'llm-summary' | 'snip-fallback';
748
+ export type CompactionTrigger =
749
+ | 'threshold'
750
+ | 'post-budget'
751
+ | 'provider-overflow'
752
+ | 'manual';
753
+ export type CompactionFallbackReason =
754
+ | 'llm-error'
755
+ | 'invalid-summary'
756
+ | 'still-over-budget';
757
+
758
+ /**
759
+ * LiveArea 显示一行工具调用用的快照。
760
+ *
761
+ * 之前定义在 ui/hooks/useChat.ts 中(仅 UI 内部);
762
+ * 工具并行后 loop.ts 和 UI 都要引用这个形状,统一上移到 types.ts。
763
+ */
764
+ export interface ToolStatusState {
765
+ toolName: string;
766
+ argsPreview: string;
767
+ status: 'running';
768
+ /**
769
+ * v2 新增:人话版工具描述(如 "Reading src/foo.ts" 而非 "Read(file_path=...)").
770
+ * 由 loop.ts 的 friendlyToolDescription() 生成;UI 优先用它显示在 spinner 行。
771
+ * 缺省时 UI fallback 到 `${toolName}(${argsPreview})`。
772
+ */
773
+ argsFriendly?: string;
774
+ /**
775
+ * 长时工具的步内实时进度行(如生图 "[ai-image-plan] round 1/1 15/31 t2i → ai_p11.png")。
776
+ * 由调用级 tool_progress 事件更新;LiveArea 有则追加显示——
777
+ * 治「单步十几分钟静态无变化被误判死机」(2026-07-02 生图假卡死事故)。缺省 = 无进度可示。
778
+ */
779
+ progress?: string;
780
+ progressDetail?: ToolProgressDetail;
781
+ }
782
+
783
+ export type LoopEvent =
784
+ /** 文本流(同 LlmStreamEvent.text_delta) */
785
+ | { type: 'text'; delta: string }
786
+ /**
787
+ * 用户消息刚 push 进 history(loop 入口)。
788
+ *
789
+ * 为什么需要这条 event:loop.ts push 用户消息后,到 assistant_message 之前,
790
+ * UI 端 handleEvent 不会触发 bump(stage_change/text/reasoning 都不 bump),
791
+ * 而 useChat 的 history 是 useMemo(..., [version]),version 不变就不重算 →
792
+ * <Static> 直到整轮落定才一次性 commit「用户消息+reasoning+答案」,用户输入无法第一时间置顶。
793
+ * UI 收到此事件立即 bump,让 <Static> 马上把用户消息 commit 进 scrollback(符合 T-A-O-R 顺序)。
794
+ */
795
+ | { type: 'user_message_committed'; message?: Extract<Message, { role: 'user' }> }
796
+ /** 一轮 assistant 消息已完整组装(含可能的 tool_calls) */
797
+ | { type: 'assistant_message'; message: Extract<Message, { role: 'assistant' }> }
798
+ /**
799
+ * 主循环在工具结果之后注入的「带外上下文消息」(当前用于浏览器关键节点实况截图回填)。
800
+ * 宿主收到后应把它当作一条消息追加进对话展示;模型也会在下一轮看到它(已 push 进 history)。
801
+ * 内核为节省上下文会把历史里旧的同类图片消息降级为文字,但宿主展示层可自行保留全部,互不影响。
802
+ */
803
+ | { type: 'injected_message'; message: Message }
804
+ /**
805
+ * 工具开始执行。
806
+ *
807
+ * v2 新增 argsFriendly:人话版工具描述(如 "Reading src/foo.ts"),由 loop.ts 的
808
+ * friendlyToolDescription() 在 yield 此事件时生成。UI 端 useChat handleEvent 接收
809
+ * 后存入 ToolStatusState.argsFriendly 给 LiveArea spinner 行用。
810
+ */
811
+ | {
812
+ type: 'tool_start';
813
+ toolName: string;
814
+ toolCallId: string;
815
+ argsPreview: string;
816
+ argsFriendly?: string;
817
+ }
818
+ /** 长时工具执行中的调用级进度,不写入会话历史。 */
819
+ | {
820
+ type: 'tool_progress';
821
+ toolName: string;
822
+ toolCallId: string;
823
+ message: string;
824
+ detail?: ToolProgressDetail;
825
+ }
826
+ /** 工具结束(成功或失败) */
827
+ | {
828
+ type: 'tool_end';
829
+ toolName: string;
830
+ toolCallId: string;
831
+ ok: boolean;
832
+ content: string;
833
+ metadata?: ToolResultMetadata;
834
+ }
835
+ | { type: 'tool_messages_committed' }
836
+ /** Local-safe harness observability; never contains prompt, memory, arguments, or reasoning text. */
837
+ | { type: 'harness_diagnostics'; diagnostics: HarnessDiagnostics }
838
+ /** 触发了自动压缩 */
839
+ | { type: 'compact_start' }
840
+ | {
841
+ type: 'compact_done';
842
+ before: number;
843
+ after: number;
844
+ /** Optional for wire compatibility with older hosts. */
845
+ trigger?: CompactionTrigger;
846
+ mode?: CompactionMode;
847
+ degraded?: boolean;
848
+ fallbackReason?: CompactionFallbackReason;
849
+ messagesRemoved?: number;
850
+ tokensFreed?: number;
851
+ }
852
+ /**
853
+ * 当前会话上下文用量。真实 usage 不可用时由内核统一估算。
854
+ *
855
+ * cachedPromptTokens / cacheWriteTokens:提示词缓存观测位(纯展示,不参与决策)。
856
+ * 只有 provider 真实报告时才有值;`source:'estimated'` 时恒为 undefined
857
+ * (估算路径没有缓存信息,不能拿估算值冒充命中率)。
858
+ */
859
+ | {
860
+ type: 'context_usage';
861
+ usedTokens: number;
862
+ contextWindow: number;
863
+ remainingTokens: number;
864
+ compactThreshold: number;
865
+ source: 'actual' | 'estimated';
866
+ cachedPromptTokens?: number;
867
+ cacheMissTokens?: number;
868
+ cacheWriteTokens?: number;
869
+ promptCacheUsage?: PromptCacheUsage;
870
+ }
871
+ /** 整轮交互结束(模型不再调工具) */
872
+ | {
873
+ type: 'turn_done';
874
+ completionStatus?: 'completed' | 'delivery_incomplete' | 'delivery_unverified' | 'claims_unverified';
875
+ warning?: string;
876
+ }
877
+ /**
878
+ * 中断事件
879
+ * - reason: 'manual' 用户按ESC/Ctrl+C手动中断
880
+ * - reason: 'queued_input' 有新的排队输入需要在安全点处理
881
+ */
882
+ | { type: 'interrupted'; reason?: 'manual' | 'queued_input' }
883
+ /**
884
+ * 出错(API 报错 / 网络异常等)。
885
+ *
886
+ * code(v2.x 新增,可选):让 `-p --output-format json` 把终结原因映射成稳定的
887
+ * stop_reason,也让 print.ts 区分"致命错误(退出)"与"非致命警告(继续)":
888
+ * - 'llm_error' LLM 调用失败 → 终结,stop_reason='error'
889
+ * - 'max_turns' 撞最大轮数上限 → 终结,stop_reason='max_turns'
890
+ * - 'compact_failed' 自动压缩失败但 loop 想继续 → 非致命,print.ts 只 stderr 警告不退出
891
+ * - 'aborted' 被中断(signal.aborted)
892
+ * 缺省(旧调用方 / 未分类错误)按致命、stop_reason='error' 处理。
893
+ */
894
+ | {
895
+ type: 'error';
896
+ error: string;
897
+ code?: 'llm_error' | 'max_turns' | 'compact_failed' | 'aborted' | 'stalled' | 'context_overflow';
898
+ }
899
+ /**
900
+ * 非致命警告:需冒泡给用户但不终止执行。
901
+ *
902
+ * 通用框架事件(不绑定任何插件)。插件 / 工作流遇到"该提醒但不该报错"的情况
903
+ * (如多余参数被忽略、审批闸门在非交互模式被自动跳过)应 yield 此事件,
904
+ * 而非自定义私有事件 —— 框架 UI 不认插件私有词表。
905
+ * - `-p` 模式:print.ts 落 stderr(权威通道,不受 verbose 控制)
906
+ * - TUI:不渲染成红色 error;插件可另发 plugin_progress 把同文案镜像到状态行
907
+ */
908
+ | { type: 'warning'; message: string }
909
+ /**
910
+ * 插件循环进度(通用化事件,替代旧的 plugin_start / plugin_iteration)。
911
+ *
912
+ * 约定:
913
+ * - 进入循环时 yield 一次 { current: 0, max, message: <说明> }
914
+ * - 每轮迭代 yield 一次 { current: N, max }
915
+ * - UI 把 current/max 渲染为进度数字,message 用于状态描述
916
+ * - current/max 都可省略 = 纯文案进度(如工作流步骤的人话 title——
917
+ * 嵌套块的块内序号对用户是噪声时,插件只发 message,UI 不渲染数字)
918
+ */
919
+ | {
920
+ type: 'plugin_progress';
921
+ pluginId: string;
922
+ current?: number;
923
+ max?: number;
924
+ message?: string;
925
+ }
926
+ /**
927
+ * 思维链流式片段。
928
+ *
929
+ * 来源:DeepSeek-R1 / MiniMax reasoning_split / OpenRouter 等 provider 的 reasoning_delta。
930
+ * loop.ts 同时把它累积成字符串挂在 assistant 消息上回传(保持思维链连续)。
931
+ * UI 端 useChat 把它累积进 reasoningPreview(100ms 节流 + 环形截断),由 LiveArea
932
+ * 在 thinking 阶段短尾部显示;assistant_message 落定后
933
+ * 整段思维链随消息进 history,由 MessageList 提交进 scrollback(💭 块),live 预览清空。
934
+ */
935
+ | { type: 'reasoning'; delta: string }
936
+ /**
937
+ * Progress 阶段切换。
938
+ *
939
+ * loop.ts 在以下时机 yield:
940
+ * - 进入新一轮 LLM 调用前 → 'thinking'
941
+ * - 首个 text_delta 到来时 → 'streaming'(用布尔 flag 防重复)
942
+ * - 进入工具并行执行段前 → 'tool_executing'
943
+ * - 进入自动/reactive 压缩前 → 'compacting'
944
+ *
945
+ * turn_done / interrupted / error 后 UI 端自行 reset 到 'idle'(loop 不再额外 yield)。
946
+ */
947
+ | { type: 'stage_change'; stage: ProgressStage }
948
+ /**
949
+ * 执行中向用户提问(AskUserQuestion 工具触发,经 askBridge)。
950
+ *
951
+ * 这是「问答 over wire」的出站事件:TUI 不靠它(TUI 走 askBridge 内存 handler 直接弹界面),
952
+ * 但 `-p --output-format stream-json` 子进程的 askBridge handler 会 emit 本事件到 stdout,
953
+ * 让远程通道(webchat / 网关)收到问题、渲染选择、把答案经 stdin 的 `ask_answer` 回灌。
954
+ * requestId 用于关联问题与答案(一轮内可多次提问)。
955
+ */
956
+ | { type: 'ask'; requestId: string; questions: AskQuestionSpec[]; source?: AskSource }
957
+ /** 问题在本回合所有者队列中的状态;不写入 Session 历史。 */
958
+ | { type: 'ask_status'; source: AskSource; state: AskQueueState; queuePosition?: number; queuedCount?: number };
959
+ // 注:插件私有事件(如 workflow-runner 的 workflow_*)不再写在这里。
960
+ // 插件通过 PluginEvent 开放契约 yield 任意 type 字符串的事件,UI 静默忽略未识别项。