@armadra/agent 0.3.0 → 0.5.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 (527) hide show
  1. package/CHANGELOG.md +257 -0
  2. package/README.md +263 -95
  3. package/THIRD_PARTY_NOTICES.md +34 -0
  4. package/dist/acp.d.ts +18 -0
  5. package/dist/acp.js +19 -0
  6. package/dist/agent/limits.d.ts +38 -0
  7. package/dist/agent/limits.js +127 -0
  8. package/dist/agent/loop-guard.d.ts +38 -0
  9. package/dist/agent/loop-guard.js +95 -0
  10. package/dist/agent/loop.d.ts +4 -0
  11. package/dist/agent/loop.js +7 -0
  12. package/dist/agent/prompt-rules.d.ts +12 -0
  13. package/dist/agent/prompt-rules.js +18 -0
  14. package/dist/agent/reminders.d.ts +59 -0
  15. package/dist/agent/reminders.js +327 -0
  16. package/dist/agent/retry.d.ts +1 -1
  17. package/dist/agent/retry.js +2 -1
  18. package/dist/agent/session-cache.d.ts +5 -0
  19. package/dist/agent/session-cache.js +18 -2
  20. package/dist/agent/session-classifier.d.ts +18 -0
  21. package/dist/agent/session-classifier.js +105 -0
  22. package/dist/agent/session-compaction.d.ts +35 -6
  23. package/dist/agent/session-compaction.js +157 -31
  24. package/dist/agent/session-core.d.ts +40 -1
  25. package/dist/agent/session-extensions.d.ts +61 -0
  26. package/dist/agent/session-extensions.js +129 -0
  27. package/dist/agent/session-images.d.ts +23 -0
  28. package/dist/agent/session-images.js +97 -0
  29. package/dist/agent/session-plan.d.ts +21 -0
  30. package/dist/agent/session-plan.js +524 -0
  31. package/dist/agent/session-rewind.d.ts +81 -0
  32. package/dist/agent/session-rewind.js +354 -0
  33. package/dist/agent/session-run.d.ts +28 -1
  34. package/dist/agent/session-run.js +157 -6
  35. package/dist/agent/session-settings.d.ts +49 -0
  36. package/dist/agent/session-settings.js +95 -0
  37. package/dist/agent/session-subagent.d.ts +36 -24
  38. package/dist/agent/session-subagent.js +259 -129
  39. package/dist/agent/session-sync.d.ts +10 -3
  40. package/dist/agent/session-sync.js +37 -8
  41. package/dist/agent/session-telemetry.d.ts +39 -0
  42. package/dist/agent/session-telemetry.js +231 -0
  43. package/dist/agent/session-tools.js +63 -3
  44. package/dist/agent/session.d.ts +33 -29
  45. package/dist/agent/session.js +91 -126
  46. package/dist/agent/subagent-registry.d.ts +91 -0
  47. package/dist/agent/subagent-registry.js +494 -0
  48. package/dist/agent/system-prompt.d.ts +6 -3
  49. package/dist/agent/system-prompt.js +7 -2
  50. package/dist/agent/tool-runner.d.ts +8 -1
  51. package/dist/agent/tool-runner.js +72 -6
  52. package/dist/agent/types-w5.d.ts +192 -0
  53. package/dist/agent/types-w5.js +10 -0
  54. package/dist/agent/types.d.ts +55 -4
  55. package/dist/agent/types.js +2 -0
  56. package/dist/agent/worktree.d.ts +36 -0
  57. package/dist/agent/worktree.js +86 -0
  58. package/dist/agents/builtin.d.ts +14 -0
  59. package/dist/agents/builtin.js +39 -0
  60. package/dist/agents/catalog.d.ts +43 -0
  61. package/dist/agents/catalog.js +82 -0
  62. package/dist/agents/discover.d.ts +35 -0
  63. package/dist/agents/discover.js +83 -0
  64. package/dist/agents/external.d.ts +82 -0
  65. package/dist/agents/external.js +326 -0
  66. package/dist/agents/parse.d.ts +18 -0
  67. package/dist/agents/parse.js +116 -0
  68. package/dist/agents/result.d.ts +32 -0
  69. package/dist/agents/result.js +67 -0
  70. package/dist/agents/task-control.d.ts +17 -0
  71. package/dist/agents/task-control.js +17 -0
  72. package/dist/agents/task-record.d.ts +78 -0
  73. package/dist/agents/task-record.js +141 -0
  74. package/dist/agents/types.d.ts +46 -0
  75. package/dist/agents/types.js +8 -0
  76. package/dist/ai/apis/anthropic-compat.d.ts +36 -0
  77. package/dist/ai/apis/anthropic-compat.js +92 -0
  78. package/dist/ai/apis/anthropic-messages.js +3 -2
  79. package/dist/ai/apis/anthropic-request.d.ts +7 -6
  80. package/dist/ai/apis/anthropic-request.js +10 -28
  81. package/dist/ai/apis/cache-params.d.ts +11 -2
  82. package/dist/ai/apis/cache-params.js +25 -6
  83. package/dist/ai/apis/google-generative-ai.js +3 -2
  84. package/dist/ai/apis/openai-compat.d.ts +4 -1
  85. package/dist/ai/apis/openai-compat.js +8 -1
  86. package/dist/ai/apis/openai-completions.js +3 -2
  87. package/dist/ai/apis/openai-responses.js +3 -2
  88. package/dist/ai/http.d.ts +28 -6
  89. package/dist/ai/http.js +41 -8
  90. package/dist/ai/image-limits.d.ts +45 -0
  91. package/dist/ai/image-limits.js +68 -0
  92. package/dist/ai/providers/builtin.d.ts +18 -6
  93. package/dist/ai/providers/builtin.js +135 -6
  94. package/dist/ai/providers/catalog-data.js +17 -13
  95. package/dist/ai/providers/catalog.d.ts +60 -7
  96. package/dist/ai/providers/catalog.js +197 -38
  97. package/dist/ai/providers/channels.d.ts +33 -3
  98. package/dist/ai/providers/channels.js +108 -7
  99. package/dist/ai/providers/enrich.d.ts +6 -3
  100. package/dist/ai/providers/enrich.js +19 -4
  101. package/dist/ai/providers/models-dev-cache.d.ts +28 -24
  102. package/dist/ai/providers/models-dev-cache.js +92 -78
  103. package/dist/ai/providers/models-dev-data.d.ts +7 -0
  104. package/dist/ai/providers/models-dev-data.js +32 -0
  105. package/dist/ai/providers/models-dev-snapshot.d.ts +50 -0
  106. package/dist/ai/providers/models-dev-snapshot.js +137 -0
  107. package/dist/ai/providers/models-dev.d.ts +51 -10
  108. package/dist/ai/providers/models-dev.js +132 -39
  109. package/dist/ai/providers/registry.d.ts +28 -11
  110. package/dist/ai/providers/registry.js +112 -65
  111. package/dist/ai/providers/suggest.d.ts +18 -0
  112. package/dist/ai/providers/suggest.js +72 -0
  113. package/dist/ai/sse.d.ts +6 -2
  114. package/dist/ai/sse.js +22 -2
  115. package/dist/ai/types.d.ts +37 -4
  116. package/dist/ai/types.js +5 -0
  117. package/dist/bundle/ama.cjs +41979 -21147
  118. package/dist/checkpoints/backend.d.ts +61 -0
  119. package/dist/checkpoints/backend.js +135 -0
  120. package/dist/checkpoints/blobs.d.ts +60 -0
  121. package/dist/checkpoints/blobs.js +203 -0
  122. package/dist/checkpoints/gc.d.ts +47 -0
  123. package/dist/checkpoints/gc.js +144 -0
  124. package/dist/checkpoints/git-head.d.ts +15 -0
  125. package/dist/checkpoints/git-head.js +89 -0
  126. package/dist/checkpoints/index.d.ts +17 -0
  127. package/dist/checkpoints/index.js +17 -0
  128. package/dist/checkpoints/replay.d.ts +48 -0
  129. package/dist/checkpoints/replay.js +154 -0
  130. package/dist/checkpoints/restore.d.ts +86 -0
  131. package/dist/checkpoints/restore.js +263 -0
  132. package/dist/checkpoints/settings.d.ts +14 -0
  133. package/dist/checkpoints/settings.js +23 -0
  134. package/dist/checkpoints/shadow-git.d.ts +108 -0
  135. package/dist/checkpoints/shadow-git.js +491 -0
  136. package/dist/checkpoints/shadow-restore.d.ts +25 -0
  137. package/dist/checkpoints/shadow-restore.js +128 -0
  138. package/dist/checkpoints/tracker.d.ts +64 -0
  139. package/dist/checkpoints/tracker.js +192 -0
  140. package/dist/checkpoints/types.d.ts +99 -0
  141. package/dist/checkpoints/types.js +12 -0
  142. package/dist/cli/args.d.ts +26 -7
  143. package/dist/cli/args.js +75 -82
  144. package/dist/cli/bootstrap.js +40 -4
  145. package/dist/cli/codemode-notice.d.ts +21 -0
  146. package/dist/cli/codemode-notice.js +56 -0
  147. package/dist/cli/compose-agents.d.ts +27 -0
  148. package/dist/cli/compose-agents.js +111 -0
  149. package/dist/cli/compose-extensions.d.ts +29 -0
  150. package/dist/cli/compose-extensions.js +44 -0
  151. package/dist/cli/compose-session.d.ts +8 -0
  152. package/dist/cli/compose-session.js +76 -2
  153. package/dist/cli/compose-store.d.ts +1 -1
  154. package/dist/cli/compose-store.js +3 -1
  155. package/dist/cli/compose.d.ts +17 -4
  156. package/dist/cli/compose.js +60 -14
  157. package/dist/cli/default-model.d.ts +38 -1
  158. package/dist/cli/default-model.js +96 -9
  159. package/dist/cli/deps.d.ts +42 -0
  160. package/dist/cli/exit-codes.d.ts +12 -0
  161. package/dist/cli/exit-codes.js +15 -0
  162. package/dist/cli/fake-visibility.d.ts +13 -0
  163. package/dist/cli/fake-visibility.js +26 -0
  164. package/dist/cli/from-prompt.d.ts +18 -0
  165. package/dist/cli/from-prompt.js +49 -0
  166. package/dist/cli/help-text.d.ts +4 -0
  167. package/dist/cli/help-text.js +102 -0
  168. package/dist/cli/main.d.ts +9 -2
  169. package/dist/cli/main.js +77 -3
  170. package/dist/cli/proxy.d.ts +51 -0
  171. package/dist/cli/proxy.js +135 -0
  172. package/dist/cli/startup-screen.d.ts +29 -0
  173. package/dist/cli/startup-screen.js +51 -2
  174. package/dist/cli/startup-steps.d.ts +1 -1
  175. package/dist/cli/startup-steps.js +21 -13
  176. package/dist/cli/subcommands/config.d.ts +22 -3
  177. package/dist/cli/subcommands/config.js +119 -21
  178. package/dist/cli/subcommands/context.js +4 -1
  179. package/dist/cli/subcommands/doctor.js +33 -1
  180. package/dist/cli/subcommands/init.js +2 -1
  181. package/dist/cli/subcommands/models-discover.d.ts +15 -9
  182. package/dist/cli/subcommands/models-discover.js +58 -52
  183. package/dist/cli/subcommands/models.d.ts +2 -0
  184. package/dist/cli/subcommands/models.js +33 -14
  185. package/dist/cli/subcommands/probe-runner.d.ts +96 -0
  186. package/dist/cli/subcommands/probe-runner.js +264 -0
  187. package/dist/cli/subcommands/providers-probe.d.ts +34 -0
  188. package/dist/cli/subcommands/providers-probe.js +87 -0
  189. package/dist/cli/subcommands/providers.d.ts +3 -2
  190. package/dist/cli/subcommands/providers.js +53 -51
  191. package/dist/cli/subcommands/sessions-export.d.ts +10 -0
  192. package/dist/cli/subcommands/sessions-export.js +59 -0
  193. package/dist/cli/subcommands/sessions-search.d.ts +13 -0
  194. package/dist/cli/subcommands/sessions-search.js +103 -0
  195. package/dist/cli/subcommands/sessions.d.ts +6 -3
  196. package/dist/cli/subcommands/sessions.js +58 -3
  197. package/dist/cli/subcommands/stats.d.ts +17 -0
  198. package/dist/cli/subcommands/stats.js +198 -0
  199. package/dist/cli/system-prompt-arg.d.ts +11 -0
  200. package/dist/cli/system-prompt-arg.js +34 -0
  201. package/dist/codemode/capability.d.ts +24 -7
  202. package/dist/codemode/capability.js +38 -10
  203. package/dist/codemode/host-side.d.ts +14 -0
  204. package/dist/codemode/host-side.js +24 -1
  205. package/dist/codemode/modes.d.ts +4 -11
  206. package/dist/codemode/modes.js +5 -27
  207. package/dist/codemode/tool.d.ts +18 -14
  208. package/dist/codemode/tool.js +76 -31
  209. package/dist/compaction/breaker.d.ts +25 -9
  210. package/dist/compaction/breaker.js +47 -17
  211. package/dist/compaction/estimate.d.ts +11 -3
  212. package/dist/compaction/estimate.js +64 -22
  213. package/dist/compaction/image-budget.d.ts +45 -0
  214. package/dist/compaction/image-budget.js +115 -0
  215. package/dist/compaction/post-compact.d.ts +38 -0
  216. package/dist/compaction/post-compact.js +152 -0
  217. package/dist/compaction/protect.d.ts +27 -0
  218. package/dist/compaction/protect.js +56 -0
  219. package/dist/compaction/prune-tier.d.ts +58 -12
  220. package/dist/compaction/prune-tier.js +120 -54
  221. package/dist/compaction/summarize-tier.d.ts +23 -4
  222. package/dist/compaction/summarize-tier.js +100 -29
  223. package/dist/config/checker.d.ts +28 -0
  224. package/dist/config/checker.js +97 -0
  225. package/dist/config/init.d.ts +6 -2
  226. package/dist/config/init.js +12 -5
  227. package/dist/config/json-schema.d.ts +1 -0
  228. package/dist/config/json-schema.js +98 -4
  229. package/dist/config/key-docs.d.ts +22 -0
  230. package/dist/config/key-docs.js +174 -0
  231. package/dist/config/merge.d.ts +12 -9
  232. package/dist/config/merge.js +102 -13
  233. package/dist/config/profile.d.ts +2 -0
  234. package/dist/config/profile.js +2 -0
  235. package/dist/config/schema-w5.d.ts +18 -0
  236. package/dist/config/schema-w5.js +109 -0
  237. package/dist/config/schema.d.ts +5 -9
  238. package/dist/config/schema.js +91 -118
  239. package/dist/config/types-w5.d.ts +118 -0
  240. package/dist/config/types-w5.js +20 -0
  241. package/dist/config/types.d.ts +84 -7
  242. package/dist/config/types.js +29 -1
  243. package/dist/drivers/acp/client.d.ts +57 -0
  244. package/dist/drivers/acp/client.js +160 -0
  245. package/dist/drivers/acp/driver.d.ts +31 -0
  246. package/dist/drivers/acp/driver.js +274 -0
  247. package/dist/drivers/acp/testing/fake-agent-main.d.ts +5 -0
  248. package/dist/drivers/acp/testing/fake-agent-main.js +7 -0
  249. package/dist/drivers/acp/testing/fake-agent.d.ts +27 -0
  250. package/dist/drivers/acp/testing/fake-agent.js +211 -0
  251. package/dist/drivers/acp/types.d.ts +285 -0
  252. package/dist/drivers/acp/types.js +36 -0
  253. package/dist/drivers/agents.d.ts +58 -0
  254. package/dist/drivers/agents.js +142 -0
  255. package/dist/drivers/base.d.ts +35 -0
  256. package/dist/drivers/base.js +59 -0
  257. package/dist/drivers/catalog.d.ts +46 -0
  258. package/dist/drivers/catalog.js +167 -0
  259. package/dist/drivers/env.d.ts +20 -0
  260. package/dist/drivers/env.js +46 -0
  261. package/dist/drivers/host-runners.d.ts +18 -0
  262. package/dist/drivers/host-runners.js +45 -0
  263. package/dist/drivers/jsonrpc.d.ts +58 -0
  264. package/dist/drivers/jsonrpc.js +180 -0
  265. package/dist/drivers/native/claude-normalize.d.ts +46 -0
  266. package/dist/drivers/native/claude-normalize.js +106 -0
  267. package/dist/drivers/native/claude-stream.d.ts +29 -0
  268. package/dist/drivers/native/claude-stream.js +456 -0
  269. package/dist/drivers/native/codex-app-server.d.ts +26 -0
  270. package/dist/drivers/native/codex-app-server.js +407 -0
  271. package/dist/drivers/native/codex-normalize.d.ts +38 -0
  272. package/dist/drivers/native/codex-normalize.js +124 -0
  273. package/dist/drivers/native/oneshot.d.ts +28 -0
  274. package/dist/drivers/native/oneshot.js +312 -0
  275. package/dist/drivers/permissions.d.ts +40 -0
  276. package/dist/drivers/permissions.js +92 -0
  277. package/dist/drivers/pids.d.ts +32 -0
  278. package/dist/drivers/pids.js +93 -0
  279. package/dist/drivers/pool.d.ts +28 -0
  280. package/dist/drivers/pool.js +96 -0
  281. package/dist/drivers/probe.d.ts +47 -0
  282. package/dist/drivers/probe.js +172 -0
  283. package/dist/drivers/process.d.ts +48 -0
  284. package/dist/drivers/process.js +100 -0
  285. package/dist/drivers/runner.d.ts +61 -0
  286. package/dist/drivers/runner.js +388 -0
  287. package/dist/drivers/store.d.ts +49 -0
  288. package/dist/drivers/store.js +91 -0
  289. package/dist/drivers/turn.d.ts +41 -0
  290. package/dist/drivers/turn.js +99 -0
  291. package/dist/drivers/types.d.ts +122 -0
  292. package/dist/drivers/types.js +11 -0
  293. package/dist/git/info.d.ts +75 -0
  294. package/dist/git/info.js +191 -0
  295. package/dist/hooks/protocol.js +6 -1
  296. package/dist/hooks/types.d.ts +10 -1
  297. package/dist/hooks/types.js +2 -0
  298. package/dist/host/api-impl.d.ts +7 -0
  299. package/dist/host/api-impl.js +15 -0
  300. package/dist/host/types.d.ts +24 -2
  301. package/dist/host/types.js +4 -0
  302. package/dist/index.d.ts +3 -0
  303. package/dist/index.js +1 -0
  304. package/dist/modes/acp/acp-events.d.ts +46 -0
  305. package/dist/modes/acp/acp-events.js +233 -0
  306. package/dist/modes/acp/acp-mode.d.ts +17 -0
  307. package/dist/modes/acp/acp-mode.js +47 -0
  308. package/dist/modes/acp/acp-server.d.ts +79 -0
  309. package/dist/modes/acp/acp-server.js +315 -0
  310. package/dist/modes/commands-core.d.ts +7 -1
  311. package/dist/modes/commands-core.js +61 -5
  312. package/dist/modes/image-input.d.ts +12 -4
  313. package/dist/modes/image-input.js +22 -5
  314. package/dist/modes/interactive/agent-panels.d.ts +14 -0
  315. package/dist/modes/interactive/agent-panels.js +103 -0
  316. package/dist/modes/interactive/agent-ui.d.ts +73 -0
  317. package/dist/modes/interactive/agent-ui.js +234 -0
  318. package/dist/modes/interactive/approval-dialog.d.ts +40 -7
  319. package/dist/modes/interactive/approval-dialog.js +192 -35
  320. package/dist/modes/interactive/approval-merge.d.ts +41 -0
  321. package/dist/modes/interactive/approval-merge.js +89 -0
  322. package/dist/modes/interactive/clipboard-paste.d.ts +18 -0
  323. package/dist/modes/interactive/clipboard-paste.js +28 -0
  324. package/dist/modes/interactive/commands.d.ts +20 -3
  325. package/dist/modes/interactive/commands.js +75 -16
  326. package/dist/modes/interactive/double-esc.d.ts +20 -0
  327. package/dist/modes/interactive/double-esc.js +34 -0
  328. package/dist/modes/interactive/event-notices.d.ts +32 -0
  329. package/dist/modes/interactive/event-notices.js +79 -0
  330. package/dist/modes/interactive/external-editor.d.ts +16 -0
  331. package/dist/modes/interactive/external-editor.js +39 -0
  332. package/dist/modes/interactive/interactive-mode.d.ts +16 -2
  333. package/dist/modes/interactive/interactive-mode.js +184 -202
  334. package/dist/modes/interactive/key-dispatch.d.ts +18 -2
  335. package/dist/modes/interactive/key-dispatch.js +53 -6
  336. package/dist/modes/interactive/line/line-mode.d.ts +3 -1
  337. package/dist/modes/interactive/line/line-mode.js +28 -9
  338. package/dist/modes/interactive/line/line-render.d.ts +6 -1
  339. package/dist/modes/interactive/line/line-render.js +66 -8
  340. package/dist/modes/interactive/message-view.d.ts +49 -10
  341. package/dist/modes/interactive/message-view.js +262 -46
  342. package/dist/modes/interactive/panels.d.ts +35 -0
  343. package/dist/modes/interactive/panels.js +157 -0
  344. package/dist/modes/interactive/pickers.d.ts +23 -2
  345. package/dist/modes/interactive/pickers.js +48 -15
  346. package/dist/modes/interactive/plan-command.d.ts +40 -0
  347. package/dist/modes/interactive/plan-command.js +129 -0
  348. package/dist/modes/interactive/plan-dialog.d.ts +98 -0
  349. package/dist/modes/interactive/plan-dialog.js +290 -0
  350. package/dist/modes/interactive/plan-flow.d.ts +34 -0
  351. package/dist/modes/interactive/plan-flow.js +98 -0
  352. package/dist/modes/interactive/rewind-command.d.ts +31 -0
  353. package/dist/modes/interactive/rewind-command.js +106 -0
  354. package/dist/modes/interactive/rewind-flow.d.ts +37 -0
  355. package/dist/modes/interactive/rewind-flow.js +151 -0
  356. package/dist/modes/interactive/rewind-list.d.ts +36 -0
  357. package/dist/modes/interactive/rewind-list.js +123 -0
  358. package/dist/modes/interactive/rewind-panel.d.ts +77 -0
  359. package/dist/modes/interactive/rewind-panel.js +309 -0
  360. package/dist/modes/interactive/rewind-text.d.ts +40 -0
  361. package/dist/modes/interactive/rewind-text.js +139 -0
  362. package/dist/modes/interactive/run-indicator.d.ts +51 -0
  363. package/dist/modes/interactive/run-indicator.js +189 -0
  364. package/dist/modes/interactive/session-events.d.ts +24 -0
  365. package/dist/modes/interactive/session-events.js +96 -0
  366. package/dist/modes/interactive/startup-header.d.ts +40 -0
  367. package/dist/modes/interactive/startup-header.js +169 -0
  368. package/dist/modes/interactive/status-area.d.ts +73 -0
  369. package/dist/modes/interactive/status-area.js +190 -0
  370. package/dist/modes/interactive/status-bar.d.ts +107 -16
  371. package/dist/modes/interactive/status-bar.js +306 -81
  372. package/dist/modes/interactive/status-line.d.ts +33 -0
  373. package/dist/modes/interactive/status-line.js +113 -0
  374. package/dist/modes/interactive/subagent-view.d.ts +56 -0
  375. package/dist/modes/interactive/subagent-view.js +154 -0
  376. package/dist/modes/interactive/tasks-report.d.ts +27 -0
  377. package/dist/modes/interactive/tasks-report.js +114 -0
  378. package/dist/modes/interactive/tool-summary.d.ts +46 -0
  379. package/dist/modes/interactive/tool-summary.js +218 -0
  380. package/dist/modes/interactive/tool-view.d.ts +58 -15
  381. package/dist/modes/interactive/tool-view.js +233 -145
  382. package/dist/modes/print/print-mode.d.ts +40 -4
  383. package/dist/modes/print/print-mode.js +161 -8
  384. package/dist/modes/rpc/commands.d.ts +9 -0
  385. package/dist/modes/rpc/commands.js +49 -0
  386. package/dist/modes/rpc/rpc-mode.js +7 -1
  387. package/dist/modes/session-report.d.ts +11 -0
  388. package/dist/modes/session-report.js +48 -1
  389. package/dist/permissions/auto-safe.d.ts +65 -0
  390. package/dist/permissions/auto-safe.js +547 -0
  391. package/dist/permissions/classifier.d.ts +68 -0
  392. package/dist/permissions/classifier.js +186 -0
  393. package/dist/permissions/dangerous.d.ts +5 -0
  394. package/dist/permissions/dangerous.js +1 -1
  395. package/dist/permissions/modes.d.ts +30 -0
  396. package/dist/permissions/modes.js +78 -0
  397. package/dist/permissions/pipeline.d.ts +72 -6
  398. package/dist/permissions/pipeline.js +306 -11
  399. package/dist/permissions/protected.d.ts +19 -0
  400. package/dist/permissions/protected.js +74 -0
  401. package/dist/permissions/readonly-bash.d.ts +30 -0
  402. package/dist/permissions/readonly-bash.js +118 -0
  403. package/dist/permissions/rules.js +3 -0
  404. package/dist/permissions/types.d.ts +92 -3
  405. package/dist/permissions/types.js +3 -0
  406. package/dist/plan/compose.d.ts +9 -0
  407. package/dist/plan/compose.js +19 -0
  408. package/dist/plan/controller.d.ts +71 -0
  409. package/dist/plan/controller.js +27 -0
  410. package/dist/plan/done-markers.d.ts +17 -0
  411. package/dist/plan/done-markers.js +51 -0
  412. package/dist/plan/extract.d.ts +29 -0
  413. package/dist/plan/extract.js +160 -0
  414. package/dist/plan/prompts.d.ts +36 -0
  415. package/dist/plan/prompts.js +89 -0
  416. package/dist/plan/store.d.ts +37 -0
  417. package/dist/plan/store.js +90 -0
  418. package/dist/rpc.d.ts +58 -2
  419. package/dist/rpc.js +7 -0
  420. package/dist/sandbox/bash.d.ts +74 -0
  421. package/dist/sandbox/bash.js +126 -0
  422. package/dist/sandbox/detect.d.ts +48 -0
  423. package/dist/sandbox/detect.js +149 -0
  424. package/dist/sandbox/index.d.ts +5 -0
  425. package/dist/sandbox/index.js +5 -0
  426. package/dist/sandbox/profile.d.ts +33 -0
  427. package/dist/sandbox/profile.js +76 -0
  428. package/dist/sandbox/wrap.d.ts +29 -0
  429. package/dist/sandbox/wrap.js +117 -0
  430. package/dist/sdk.d.ts +42 -5
  431. package/dist/sdk.js +34 -4
  432. package/dist/session/export.d.ts +32 -0
  433. package/dist/session/export.js +187 -0
  434. package/dist/session/redact.d.ts +15 -0
  435. package/dist/session/redact.js +55 -0
  436. package/dist/session/reuse.d.ts +33 -0
  437. package/dist/session/reuse.js +86 -0
  438. package/dist/session/scan.d.ts +34 -0
  439. package/dist/session/scan.js +140 -0
  440. package/dist/session/search.d.ts +52 -0
  441. package/dist/session/search.js +211 -0
  442. package/dist/session/stats-aggregate.d.ts +63 -0
  443. package/dist/session/stats-aggregate.js +163 -0
  444. package/dist/session/stats-index.d.ts +26 -0
  445. package/dist/session/stats-index.js +91 -0
  446. package/dist/session/stats-scan.d.ts +54 -0
  447. package/dist/session/stats-scan.js +236 -0
  448. package/dist/session/types.d.ts +3 -1
  449. package/dist/session/types.js +1 -0
  450. package/dist/skills/builtin.d.ts +31 -0
  451. package/dist/skills/builtin.js +109 -0
  452. package/dist/skills/discover.d.ts +2 -1
  453. package/dist/skills/index-prompt.js +5 -8
  454. package/dist/tools/background-jobs.d.ts +71 -0
  455. package/dist/tools/background-jobs.js +198 -0
  456. package/dist/tools/bash.d.ts +53 -1
  457. package/dist/tools/bash.js +158 -7
  458. package/dist/tools/clipboard-image.d.ts +44 -0
  459. package/dist/tools/clipboard-image.js +148 -0
  460. package/dist/tools/edit.d.ts +2 -0
  461. package/dist/tools/edit.js +18 -3
  462. package/dist/tools/image-file.d.ts +38 -3
  463. package/dist/tools/image-file.js +81 -10
  464. package/dist/tools/image-resize.d.ts +58 -0
  465. package/dist/tools/image-resize.js +97 -0
  466. package/dist/tools/presets.d.ts +40 -8
  467. package/dist/tools/presets.js +65 -19
  468. package/dist/tools/read.d.ts +5 -2
  469. package/dist/tools/read.js +13 -10
  470. package/dist/tools/registry.d.ts +7 -1
  471. package/dist/tools/registry.js +27 -4
  472. package/dist/tools/task-ctl.d.ts +22 -0
  473. package/dist/tools/task-ctl.js +116 -0
  474. package/dist/tools/task.d.ts +22 -10
  475. package/dist/tools/task.js +66 -26
  476. package/dist/tools/todo.d.ts +22 -2
  477. package/dist/tools/todo.js +58 -14
  478. package/dist/tools/truncate.d.ts +15 -0
  479. package/dist/tools/truncate.js +25 -0
  480. package/dist/tools/types.d.ts +113 -0
  481. package/dist/tools/types.js +5 -0
  482. package/dist/tools/write.js +3 -0
  483. package/dist/tui/component.d.ts +8 -2
  484. package/dist/tui/component.js +3 -1
  485. package/dist/tui/components/box.d.ts +6 -1
  486. package/dist/tui/components/box.js +16 -6
  487. package/dist/tui/components/card.d.ts +23 -0
  488. package/dist/tui/components/card.js +37 -0
  489. package/dist/tui/components/editor-history.d.ts +6 -0
  490. package/dist/tui/components/editor-history.js +45 -0
  491. package/dist/tui/components/editor-paste.d.ts +1 -1
  492. package/dist/tui/components/editor-paste.js +4 -4
  493. package/dist/tui/components/editor.d.ts +11 -5
  494. package/dist/tui/components/editor.js +52 -58
  495. package/dist/tui/components/key-value.d.ts +3 -0
  496. package/dist/tui/components/key-value.js +16 -6
  497. package/dist/tui/components/loader.d.ts +37 -7
  498. package/dist/tui/components/loader.js +84 -21
  499. package/dist/tui/components/markdown.d.ts +5 -1
  500. package/dist/tui/components/markdown.js +45 -21
  501. package/dist/tui/components/meter.d.ts +3 -3
  502. package/dist/tui/components/meter.js +13 -11
  503. package/dist/tui/components/select-list.d.ts +23 -1
  504. package/dist/tui/components/select-list.js +76 -13
  505. package/dist/tui/glyphs.d.ts +72 -0
  506. package/dist/tui/glyphs.js +118 -0
  507. package/dist/tui/keybindings.d.ts +5 -0
  508. package/dist/tui/keybindings.js +5 -0
  509. package/dist/tui/theme.d.ts +30 -6
  510. package/dist/tui/theme.js +103 -17
  511. package/dist/tui.d.ts +4 -2
  512. package/dist/tui.js +3 -1
  513. package/docs/acp.md +78 -0
  514. package/docs/agents.md +250 -0
  515. package/docs/codemode.md +28 -10
  516. package/docs/hooks.md +36 -32
  517. package/docs/permissions.md +212 -0
  518. package/docs/plan.md +107 -0
  519. package/docs/providers.md +261 -62
  520. package/docs/rewind-plan.md +181 -0
  521. package/docs/rpc.md +127 -40
  522. package/docs/sandbox.md +215 -0
  523. package/docs/session-format.md +43 -22
  524. package/docs/sessions.md +174 -0
  525. package/docs/tui-design.md +751 -0
  526. package/docs/tui.md +260 -64
  527. package/package.json +15 -2
@@ -1,34 +1,31 @@
1
1
  /**
2
2
  * AgentSessionImpl(设计 §4.2–§4.3、§9、§11.1 第 16 步、§13.1)。[B2]
3
3
  *
4
- * 会话 = SessionManager(JSONL 树,事实来源)+ Agent(上下文消息、队列、run)+ 压缩 / 重试 / Hook 调度。
5
- * - 每条 message_end 落盘为条目;Agent 的上下文 = 活动分支的投影(压缩 / context_edit 后重建)。
6
- * - 首次模型请求前把系统提示 + 工具表作为首条 `system` 消息落盘并 `flush()`(此时才创建文件);
7
- * 之后节或工具表变化落 system 补丁。
8
- * - `prompt()`:运行中且无 streamingBehavior → `AmaError{code:"busy"}`;否则展开(expandPrompt)→
9
- * UserPromptSubmit Hook → 阈值压缩检查 → 会话周期(session-run.ts);周期结束后 resolve。
10
- * - `steer()` / `followUp()`:运行中入队(返回 "queued");空闲时直接以该消息开始一个周期("handled")。
11
- * - `abort()`:中断供应商流、工具、重试等待与压缩;回到 idle 后 resolve;不清队列。
4
+ * 会话 = SessionManager(JSONL 树,事实来源)+ Agent(上下文、队列、run)+ 压缩 / 重试 / Hook / 回滚调度。
5
+ * 每条 message_end 落盘;首次请求前落 system + 工具表并 flush。`prompt()` 运行中且无
6
+ * streamingBehavior → busy;`steer / followUp` 运行中入队、空闲时直接开周期;`abort()` 不清队列。
7
+ * [W5-C0] 设置类方法在 session-settings.ts;扩展点(session-extensions.ts)的调用点:构造时
8
+ * wrapStream、emit 后 onEvent、runPrompt 的 beforePrompts、agent_settled 后 onAgentSettled、
9
+ * getStats 末尾 contributeStats、dispose。
12
10
  */
13
- import { modelRefOf } from "../ai/providers/channels.js";
14
11
  import { join } from "node:path";
15
12
  import { AmaError } from "../errors.js";
13
+ import { createSessionClassifier } from "./session-classifier.js";
16
14
  import { buildProjection } from "../session/projection.js";
17
15
  import { Agent } from "./agent.js";
18
16
  import { queuedText } from "./queue.js";
19
17
  import { resolveRetrySettings } from "./retry.js";
20
18
  import { SessionCacheController, resolveCacheSettings } from "./session-cache.js";
21
19
  import { CompactionController } from "./session-compaction.js";
22
- import { makeUserMessage, runPrompt } from "./session-run.js";
20
+ import { makeUserMessage, normalizeOrigin, runPrompt } from "./session-run.js";
23
21
  import { buildSessionState, computeStats, lastAssistantText } from "./session-state.js";
24
22
  import { DEFAULT_SUBAGENT_CONCURRENCY, SubagentPool, runSubagent } from "./session-subagent.js";
25
23
  import { persistMessage, runHookWithEvents, syncSystemMessage } from "./session-sync.js";
24
+ import { SessionExtensions } from "./session-extensions.js";
25
+ import { SessionSettings, providerStream } from "./session-settings.js";
26
26
  import { createToolRunnerOptions } from "./session-tools.js";
27
+ import { RewindController } from "./session-rewind.js";
27
28
  import { convertToLlm } from "./transform.js";
28
- /** `"user"` = 普通用户输入,不写 origin。 */
29
- function normalizeOrigin(origin) {
30
- return origin === undefined || origin === "user" ? undefined : origin;
31
- }
32
29
  export class AgentSessionImpl {
33
30
  options;
34
31
  manager;
@@ -38,10 +35,8 @@ export class AgentSessionImpl {
38
35
  readFiles = new Set();
39
36
  stream;
40
37
  cache;
41
- currentModel;
42
- currentThinking;
43
- allTools = new Map();
44
- activeNames;
38
+ settings;
39
+ extensions;
45
40
  listeners = new Set();
46
41
  compaction;
47
42
  retrySettings;
@@ -50,39 +45,35 @@ export class AgentSessionImpl {
50
45
  stopReason;
51
46
  stopFlag = false;
52
47
  turns = 0;
53
- systemInput;
54
48
  subagentPool;
55
49
  disposed = false;
50
+ classifier;
56
51
  /** 已入队、尚未投递的消息(投递时发 queue_update)。 */
57
52
  queuedMessages = new WeakSet();
53
+ rewinder;
58
54
  constructor(options) {
59
55
  this.options = options;
60
56
  this.manager = options.sessionManager;
61
57
  this.cwd = this.manager.cwd;
62
58
  this.depth = options.depth ?? 0;
63
- this.currentModel = options.model;
64
- this.currentThinking = options.thinkingLevel ?? "off";
65
- for (const tool of options.tools ?? [])
66
- this.allTools.set(tool.name, tool);
67
- this.activeNames = [...(options.activeTools ?? this.allTools.keys())].filter((name) => this.allTools.has(name));
68
- this.systemInput = { ...(options.system ?? {}) };
59
+ this.settings = new SessionSettings(options, {
60
+ core: this,
61
+ assertUsable: () => this.assertUsable(),
62
+ onModelChanged: () => this.compaction.refresh(),
63
+ });
64
+ this.extensions = new SessionExtensions(this, options.extensions);
69
65
  this.retrySettings = resolveRetrySettings(options.retry);
70
66
  this.cache = new SessionCacheController(this, resolveCacheSettings(options.cache), {
71
67
  decider: () => options.warmingDecider?.(),
72
68
  });
73
- this.stream = this.cache.wrapStream((model, context, streamOptions) => {
74
- const api = options.providers.getApi(model.api);
75
- if (api === undefined) {
76
- throw new AmaError("provider_not_found", `no implementation registered for api ${model.api}`);
77
- }
78
- return api.stream(model, context, streamOptions);
79
- });
69
+ // 缓存控制器在最外层(看到扩展改写后的最终请求)
70
+ this.stream = this.cache.wrapStream(this.extensions.wrapStream(providerStream(options.providers)));
80
71
  const runner = createToolRunnerOptions(this);
81
72
  const agentOptions = {
82
73
  hooks: {
83
74
  convertToLlm: (messages) => convertToLlm(messages, {
84
- provider: this.currentModel.provider,
85
- model: this.currentModel.id,
75
+ provider: this.settings.model.provider,
76
+ model: this.settings.model.id,
86
77
  }),
87
78
  beforeToolCall: runner.beforeToolCall,
88
79
  prepareNextTurn: async () => {
@@ -99,17 +90,21 @@ export class AgentSessionImpl {
99
90
  },
100
91
  },
101
92
  stream: this.stream,
102
- getModel: () => this.currentModel,
103
- getThinkingLevel: () => this.currentThinking,
93
+ getModel: () => this.settings.model,
94
+ getThinkingLevel: () => this.settings.thinking,
104
95
  streamOptions: async () => {
105
96
  const apiKey = await this.resolveApiKey();
106
- return apiKey === undefined
107
- ? { sessionId: this.manager.id }
108
- : { apiKey, sessionId: this.manager.id };
97
+ const idle = options.idleTimeoutMs;
98
+ return {
99
+ sessionId: this.manager.id,
100
+ ...(apiKey === undefined ? {} : { apiKey }),
101
+ ...(idle === undefined ? {} : { idleTimeoutMs: idle }),
102
+ };
109
103
  },
110
104
  beforeRequest: async () => {
111
105
  this.syncSystem();
112
106
  this.manager.flush();
107
+ await this.rewinder.ready();
113
108
  },
114
109
  tools: runner,
115
110
  messages: buildProjection(this.manager.branch()).messages,
@@ -124,15 +119,24 @@ export class AgentSessionImpl {
124
119
  this.compaction = new CompactionController(this, options.compaction);
125
120
  const subagents = options.subagents === false ? undefined : options.subagents;
126
121
  this.subagentPool = new SubagentPool(subagents?.maxConcurrent ?? DEFAULT_SUBAGENT_CONCURRENCY);
122
+ this.rewinder = new RewindController({
123
+ core: this,
124
+ running: () => {
125
+ this.assertUsable();
126
+ return this.cycle !== undefined;
127
+ },
128
+ navigate: (targetId, navigateOptions) => this.navigate(targetId, navigateOptions),
129
+ compactAt: (entryId, instructions) => this.compact(instructions, entryId),
130
+ });
127
131
  }
128
132
  // -------------------------------------------------------------------------
129
133
  // SessionCore
130
134
  // -------------------------------------------------------------------------
131
135
  model() {
132
- return this.currentModel;
136
+ return this.settings.model;
133
137
  }
134
138
  thinkingLevel() {
135
- return this.currentThinking;
139
+ return this.settings.thinking;
136
140
  }
137
141
  outputDir() {
138
142
  if (this.options.outputDir !== undefined)
@@ -142,7 +146,7 @@ export class AgentSessionImpl {
142
146
  }
143
147
  async resolveApiKey() {
144
148
  try {
145
- const { provider, channel } = this.currentModel;
149
+ const { provider, channel } = this.settings.model;
146
150
  return (await this.options.providers.resolveApiKey(provider, channel)).apiKey;
147
151
  }
148
152
  catch {
@@ -159,6 +163,7 @@ export class AgentSessionImpl {
159
163
  this.log("warn", `session listener failed on ${event.type}: ${String(error)}`);
160
164
  }
161
165
  }
166
+ this.extensions.onEvent(event);
162
167
  }
163
168
  appendEntry(input) {
164
169
  const entry = this.manager.append(input);
@@ -169,13 +174,13 @@ export class AgentSessionImpl {
169
174
  this.agent.messages = buildProjection(this.manager.branch()).messages;
170
175
  }
171
176
  activeTool(name) {
172
- return this.activeNames.includes(name) ? this.allTools.get(name) : undefined;
177
+ return this.settings.activeTool(name);
173
178
  }
174
179
  tool(name) {
175
- return this.allTools.get(name);
180
+ return this.settings.tool(name);
176
181
  }
177
182
  activeToolNames() {
178
- return [...this.activeNames];
183
+ return this.settings.activeToolNames();
179
184
  }
180
185
  runHook(event, payload, signal) {
181
186
  return runHookWithEvents(this, event, payload, signal);
@@ -192,7 +197,7 @@ export class AgentSessionImpl {
192
197
  // -------------------------------------------------------------------------
193
198
  onAgentEvent(event) {
194
199
  if (event.type === "message_end")
195
- persistMessage(this, event.message);
200
+ this.rewinder.onPersisted(persistMessage(this, event.message));
196
201
  else if (event.type === "agent_start")
197
202
  this.compaction.breaker.startRun();
198
203
  this.emit(event);
@@ -210,7 +215,7 @@ export class AgentSessionImpl {
210
215
  });
211
216
  }
212
217
  syncSystem() {
213
- syncSystemMessage(this, this.systemInput, this.getTools());
218
+ syncSystemMessage(this, this.settings.systemInput, this.getTools());
214
219
  }
215
220
  // -------------------------------------------------------------------------
216
221
  // 周期
@@ -251,6 +256,9 @@ export class AgentSessionImpl {
251
256
  this.retrying = value;
252
257
  },
253
258
  lastAssistantText: () => this.getLastAssistantText(),
259
+ beginTurn: (message) => this.rewinder.beginTurn(message),
260
+ beforePrompts: (prompts) => this.extensions.beforePrompts(prompts),
261
+ afterSettled: () => this.extensions.onAgentSettled(),
254
262
  };
255
263
  }
256
264
  // -------------------------------------------------------------------------
@@ -316,13 +324,21 @@ export class AgentSessionImpl {
316
324
  this.listeners.add(listener);
317
325
  return () => this.listeners.delete(listener);
318
326
  }
319
- /** 手动压缩;运行中 → busy。 */
320
- compact(instructions) {
327
+ /** 手动压缩;运行中 → busy。`cutAt`:以该条目为切点(「摘要到这里」)。 */
328
+ compact(instructions, cutAt) {
321
329
  this.assertUsable();
322
330
  if (this.cycle !== undefined)
323
331
  return Promise.reject(new AmaError("busy", "cannot compact while running"));
324
- return this.startCycle((signal) => this.compaction.compactManual(instructions, signal));
325
- }
332
+ return this.startCycle((signal) => this.compaction.compactManual(instructions, signal, cutAt));
333
+ }
334
+ // [RW-B] 回滚(docs/rewind-plan.md §3;编排与校验在 session-rewind.ts)
335
+ rewindPoints = () => this.rewinder.points();
336
+ rewind = (request) => this.rewinder.rewind(request);
337
+ summarizeFrom = (entryId, instructions) => this.rewinder.summarizeFrom(entryId, instructions);
338
+ summarizeUpTo = (entryId, instructions) => this.rewinder.summarizeUpTo(entryId, instructions);
339
+ canUndoAbortedTurn = () => this.rewinder.canUndoAbortedTurn();
340
+ undoAbortedTurn = () => this.rewinder.undoAbortedTurn();
341
+ checkpointHooks = () => this.rewinder.hooks();
326
342
  async fork(entryId) {
327
343
  this.assertUsable();
328
344
  if (this.cycle !== undefined)
@@ -333,9 +349,7 @@ export class AgentSessionImpl {
333
349
  sessionManager: this.manager.fork(entryId),
334
350
  });
335
351
  }
336
- /**
337
- * `/tree`:同文件换叶子;`summarize` 时为离开的分支写 branch_summary(挂在新叶子下)。
338
- */
352
+ /** `/tree`:同文件换叶子;`summarize` 时为离开的分支写 branch_summary(挂在新叶子下)。 */
339
353
  async navigate(targetId, options = {}) {
340
354
  this.assertUsable();
341
355
  if (this.cycle !== undefined)
@@ -350,83 +364,28 @@ export class AgentSessionImpl {
350
364
  this.cache.onContextChanged();
351
365
  return entry;
352
366
  }
353
- async setModel(ref) {
354
- this.assertUsable();
355
- const lookup = this.options.providers.findModel(ref);
356
- if (!lookup.ok) {
357
- throw new AmaError("model_not_found", `model ${ref} not found`, {
358
- detail: lookup.candidates,
359
- });
360
- }
361
- this.currentModel = lookup.model;
362
- this.compaction.refresh();
363
- const next = modelRefOf(lookup.model);
364
- this.appendEntry({
365
- type: "model_change",
366
- provider: next.provider,
367
- modelId: next.id,
368
- ...(next.channel !== undefined ? { channel: next.channel } : {}),
369
- });
370
- this.emit({ type: "model_changed", model: next });
371
- }
372
- setThinkingLevel(level) {
373
- this.currentThinking = level;
374
- this.appendEntry({ type: "thinking_level_change", thinkingLevel: level });
375
- this.emit({ type: "thinking_level_changed", level });
376
- }
377
- setPermissionMode(mode) {
378
- this.options.permission?.setMode(mode);
379
- this.emit({ type: "permission_mode_changed", mode });
380
- }
381
- setActiveTools(names) {
382
- const unknown = names.filter((name) => !this.allTools.has(name));
383
- if (unknown.length > 0)
384
- throw new AmaError("tool_not_found", `unknown tools: ${unknown.join(", ")}`);
385
- this.activeNames = [...new Set(names)];
386
- }
367
+ // [W5-C0] 设置类(session-settings.ts)
368
+ setModel = (ref) => this.settings.setModel(ref);
369
+ setThinkingLevel = (level) => this.settings.setThinkingLevel(level);
370
+ setPermissionMode = (mode) => this.settings.setPermissionMode(mode);
371
+ setActiveTools = (names) => this.settings.setActiveTools(names);
387
372
  /** 宿主 / SDK 在会话创建后追加工具(下次请求前以 system 补丁声明)。 */
388
- addTool(tool, active = true) {
389
- if (this.allTools.has(tool.name))
390
- throw new AmaError("tool_exists", `tool ${tool.name} already exists`);
391
- this.allTools.set(tool.name, tool);
392
- if (active)
393
- this.activeNames.push(tool.name);
394
- }
395
- /** 更新系统提示的静态部分(SessionStart Hook 的 hookContext、宿主 instructions 等)。 */
396
- updateSystem(patch) {
397
- this.systemInput = { ...this.systemInput, ...patch };
398
- }
373
+ addTool = (tool, active = true) => this.settings.addTool(tool, active);
374
+ updateSystem = (patch) => this.settings.updateSystem(patch);
375
+ getTools = () => this.settings.getTools();
376
+ announceStart = (reason) => this.settings.announceStart(reason);
399
377
  setAutoCompaction(enabled) {
400
378
  this.compaction.setAuto(enabled);
401
379
  }
402
380
  setAutoRetry(enabled) {
403
381
  this.retrySettings = { ...this.retrySettings, enabled };
404
382
  }
405
- getTools() {
406
- return this.activeNames
407
- .map((name) => this.allTools.get(name))
408
- .filter((tool) => tool !== undefined)
409
- .sort((a, b) => a.name.localeCompare(b.name));
410
- }
411
- /** 发 session_start(bootstrap / SDK 在会话就绪后调用一次)。 */
412
- announceStart(reason) {
413
- const event = {
414
- type: "session_start",
415
- sessionId: this.manager.id,
416
- cwd: this.cwd,
417
- reason,
418
- };
419
- const file = this.manager.file();
420
- if (file !== undefined)
421
- event.sessionFile = file;
422
- this.emit(event);
423
- }
424
383
  get state() {
425
384
  return buildSessionState({
426
385
  agent: this.agent,
427
386
  manager: this.manager,
428
- model: this.currentModel,
429
- thinkingLevel: this.currentThinking,
387
+ model: this.settings.model,
388
+ thinkingLevel: this.settings.thinking,
430
389
  permissionMode: this.options.permission?.mode ?? "default",
431
390
  isCompacting: this.compaction.isCompacting,
432
391
  isRetrying: this.retrying,
@@ -449,8 +408,8 @@ export class AgentSessionImpl {
449
408
  }
450
409
  getStats() {
451
410
  const contextTokens = this.compaction.estimate().tokens;
452
- const contextWindow = this.currentModel.contextWindow;
453
- return computeStats({
411
+ const contextWindow = this.settings.model.contextWindow;
412
+ const stats = computeStats({
454
413
  sessionId: this.manager.id,
455
414
  sessionFile: this.manager.file(),
456
415
  branch: this.manager.branch(),
@@ -458,12 +417,14 @@ export class AgentSessionImpl {
458
417
  contextWindow,
459
418
  cache: this.cache.stats({ tokens: contextTokens, window: contextWindow }),
460
419
  });
420
+ return this.extensions.contributeStats(stats);
461
421
  }
462
422
  async dispose() {
463
423
  if (this.disposed)
464
424
  return;
465
425
  await this.abort();
466
426
  this.cache.dispose();
427
+ this.extensions.dispose();
467
428
  this.disposed = true;
468
429
  this.manager.close();
469
430
  this.listeners.clear();
@@ -473,12 +434,16 @@ export class AgentSessionImpl {
473
434
  // -------------------------------------------------------------------------
474
435
  childBase() {
475
436
  return {
476
- model: this.currentModel,
477
- thinkingLevel: this.currentThinking,
478
- activeTools: this.activeNames,
479
- system: this.systemInput,
437
+ model: this.settings.model,
438
+ thinkingLevel: this.settings.thinking,
439
+ activeTools: this.settings.activeNamesRef(),
440
+ system: this.settings.systemInput,
480
441
  };
481
442
  }
443
+ autoClassifier() {
444
+ this.classifier ??= createSessionClassifier(this);
445
+ return this.classifier;
446
+ }
482
447
  spawnSubagent(request) {
483
448
  return runSubagent(this, request, this.subagentPool, (options) => new AgentSessionImpl(options));
484
449
  }
@@ -0,0 +1,91 @@
1
+ /**
2
+ * 子 Agent 任务注册表(docs/wave5-plan.md §7.3–§7.6,D13、D23–D24)。[W5-G]
3
+ *
4
+ * 每个根会话一份(按会话 id 登记;compose-agents.ts 的扩展在会话构造时建,SDK / 测试直接构造的
5
+ * 会话在首次 task 时以缺省环境懒建)。职责:
6
+ * - 解析类型(catalog)→ 选 runner:ama 子会话(session-subagent.ts 的工厂)或外部 runner(W5-E /
7
+ * 宿主,经 `env.runners`);同一 `task(agent=…)` 入口;
8
+ * - 并发池(`subagents.maxConcurrent`,缺省 4)+ 排队上限(`maxPending`,缺省 16,超出报错不要重试);
9
+ * - 前台(等结果)/ 后台(立即返回 taskId,完成后 `<task-notification>` 走父会话 followUp 队列);
10
+ * - `taskId` 续聊:句柄保留 16 个(LRU,释放的只是内存,JSONL 永在),被释放或 resume 后按会话
11
+ * 文件 / 外部会话 id 重新接上;
12
+ * - 结果 > 50 KB 保留头尾并全文落 `outputs/`;轮数耗尽加说明;worktree 隔离;
13
+ * - 事件 `subagent_start / update / end`;父会话 `custom{ama.task}` 记任务快照(带 `status`),
14
+ * resume 时据此重建(未完成标 `interrupted`)。
15
+ */
16
+ import type { SubagentRequest, SubagentResult, SubagentRunner, TaskInfo, TaskRegistryView } from "../tools/types.js";
17
+ import { AgentCatalog, type AgentModelConfig } from "../agents/catalog.js";
18
+ import { SubagentPool, TASK_CUSTOM_TYPE, type AmaRunnerSpec, type TaskHandle } from "../agents/task-record.js";
19
+ import { type TaskControl } from "../agents/task-control.js";
20
+ import type { AgentDefinition, AgentInfo } from "../agents/types.js";
21
+ import type { SessionCore } from "./session-core.js";
22
+ import type { SessionTaskStats } from "./types.js";
23
+ export declare const DEFAULT_SUBAGENT_CONCURRENCY = 4;
24
+ export declare const DEFAULT_MAX_PENDING = 16;
25
+ export declare const DEFAULT_RETAINED = 16;
26
+ export { SubagentPool, TASK_CUSTOM_TYPE, type AmaRunnerSpec, type TaskHandle };
27
+ export type AmaRunnerFactory = (spec: AmaRunnerSpec) => SubagentRunner;
28
+ export interface SubagentEnvironment {
29
+ catalog: AgentCatalog;
30
+ maxConcurrent?: number;
31
+ maxPending?: number;
32
+ retain?: number;
33
+ modelConfig?: AgentModelConfig;
34
+ /** 外部 / 宿主 runner(W5-E `ProcessRunner`、HostApi.runners);没有返回 undefined。 */
35
+ runners?(agent: AgentDefinition): SubagentRunner | undefined;
36
+ now?(): number;
37
+ }
38
+ /** 注册表需要的父会话能力(`SessionCore`;followUp 为 AgentSessionImpl 的公开方法)。 */
39
+ export type RegistryHost = Pick<SessionCore, "manager" | "cwd" | "emit" | "appendEntry" | "outputDir" | "log" | "options"> & {
40
+ followUp?(text: string, options?: {
41
+ origin?: string;
42
+ }): Promise<unknown>;
43
+ waitForIdle?(): Promise<void>;
44
+ };
45
+ /** RPC `get_tasks` / `/tasks`:会话 id → 注册表视图(没有任务时 undefined)。 */
46
+ export declare function taskRegistryView(sessionId: string): TaskRegistryView | undefined;
47
+ /** RPC `get_agents` / `/agents`:会话可用的类型(没有 task 工具、注册表未装配时为空)。 */
48
+ export declare function sessionAgents(sessionId: string): AgentInfo[];
49
+ export declare function registryOf(sessionId: string): SubagentRegistry | undefined;
50
+ /** 取会话的注册表;没有就以 `env`(缺省只有内置类型)新建并登记。 */
51
+ export declare function subagentRegistryFor(host: RegistryHost, env?: SubagentEnvironment): SubagentRegistry;
52
+ export declare class SubagentRegistry implements TaskControl {
53
+ private readonly host;
54
+ private readonly env;
55
+ readonly catalog: AgentCatalog;
56
+ private readonly pool;
57
+ private readonly tasks;
58
+ private readonly retained;
59
+ private seq;
60
+ private disposed;
61
+ private delivery;
62
+ constructor(host: RegistryHost, env: SubagentEnvironment);
63
+ private now;
64
+ list(): readonly TaskInfo[];
65
+ get(taskId: string): TaskInfo | undefined;
66
+ stats(): SessionTaskStats | undefined;
67
+ /** 运行中任务的已有输出(`task_ctl output`);结束后为最终文本。 */
68
+ output(taskId: string): string | undefined;
69
+ /** 等任务结束或超时;超时返回 undefined。 */
70
+ wait(taskId: string, timeoutMs: number): Promise<SubagentResult | undefined>;
71
+ stop(taskId: string): Promise<SubagentResult | undefined>;
72
+ run(request: SubagentRequest, ama: AmaRunnerFactory): Promise<SubagentResult>;
73
+ private continueTask;
74
+ private launch;
75
+ private startedResult;
76
+ private execute;
77
+ private handleFor;
78
+ private emitStart;
79
+ private sink;
80
+ private finish;
81
+ private notify;
82
+ private outputDirectory;
83
+ private outputName;
84
+ private outputFileFor;
85
+ private persist;
86
+ private touch;
87
+ /** 句柄 LRU:超出上限时释放最久未用、空闲的子会话(JSONL 仍在,续聊时重开)。 */
88
+ private retain;
89
+ /** 会话关闭:停止运行中的任务、释放保留的子会话。 */
90
+ dispose(): void;
91
+ }