@armadra/agent 0.0.0-stage → 0.3.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 (433) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/LICENSE +21 -0
  3. package/README.md +470 -2
  4. package/dist/agent/agent.d.ts +56 -0
  5. package/dist/agent/agent.js +129 -0
  6. package/dist/agent/loop.d.ts +51 -0
  7. package/dist/agent/loop.js +158 -0
  8. package/dist/agent/queue.d.ts +25 -0
  9. package/dist/agent/queue.js +55 -0
  10. package/dist/agent/retry.d.ts +22 -0
  11. package/dist/agent/retry.js +92 -0
  12. package/dist/agent/schema.d.ts +27 -0
  13. package/dist/agent/schema.js +186 -0
  14. package/dist/agent/session-cache.d.ts +100 -0
  15. package/dist/agent/session-cache.js +514 -0
  16. package/dist/agent/session-compaction.d.ts +49 -0
  17. package/dist/agent/session-compaction.js +251 -0
  18. package/dist/agent/session-core.d.ts +103 -0
  19. package/dist/agent/session-core.js +7 -0
  20. package/dist/agent/session-run.d.ts +55 -0
  21. package/dist/agent/session-run.js +246 -0
  22. package/dist/agent/session-state.d.ts +39 -0
  23. package/dist/agent/session-state.js +119 -0
  24. package/dist/agent/session-subagent.d.ts +54 -0
  25. package/dist/agent/session-subagent.js +157 -0
  26. package/dist/agent/session-sync.d.ts +20 -0
  27. package/dist/agent/session-sync.js +111 -0
  28. package/dist/agent/session-tools.d.ts +24 -0
  29. package/dist/agent/session-tools.js +277 -0
  30. package/dist/agent/session.d.ts +117 -0
  31. package/dist/agent/session.js +485 -0
  32. package/dist/agent/system-prompt.d.ts +49 -0
  33. package/dist/agent/system-prompt.js +121 -0
  34. package/dist/agent/tool-runner.d.ts +64 -0
  35. package/dist/agent/tool-runner.js +309 -0
  36. package/dist/agent/transform.d.ts +26 -0
  37. package/dist/agent/transform.js +171 -0
  38. package/dist/agent/types.d.ts +378 -0
  39. package/dist/agent/types.js +21 -0
  40. package/dist/ai/apis/anthropic-messages.d.ts +26 -0
  41. package/dist/ai/apis/anthropic-messages.js +214 -0
  42. package/dist/ai/apis/anthropic-request.d.ts +42 -0
  43. package/dist/ai/apis/anthropic-request.js +282 -0
  44. package/dist/ai/apis/api.d.ts +28 -0
  45. package/dist/ai/apis/api.js +102 -0
  46. package/dist/ai/apis/cache-params.d.ts +48 -0
  47. package/dist/ai/apis/cache-params.js +163 -0
  48. package/dist/ai/apis/google-generative-ai.d.ts +32 -0
  49. package/dist/ai/apis/google-generative-ai.js +249 -0
  50. package/dist/ai/apis/google-request.d.ts +40 -0
  51. package/dist/ai/apis/google-request.js +255 -0
  52. package/dist/ai/apis/openai-compat.d.ts +35 -0
  53. package/dist/ai/apis/openai-compat.js +142 -0
  54. package/dist/ai/apis/openai-completions.d.ts +28 -0
  55. package/dist/ai/apis/openai-completions.js +246 -0
  56. package/dist/ai/apis/openai-request.d.ts +35 -0
  57. package/dist/ai/apis/openai-request.js +303 -0
  58. package/dist/ai/apis/openai-responses-request.d.ts +52 -0
  59. package/dist/ai/apis/openai-responses-request.js +266 -0
  60. package/dist/ai/apis/openai-responses.d.ts +28 -0
  61. package/dist/ai/apis/openai-responses.js +304 -0
  62. package/dist/ai/apis/shared.d.ts +56 -0
  63. package/dist/ai/apis/shared.js +179 -0
  64. package/dist/ai/cache/economics.d.ts +24 -0
  65. package/dist/ai/cache/economics.js +69 -0
  66. package/dist/ai/cache/fingerprint.d.ts +17 -0
  67. package/dist/ai/cache/fingerprint.js +39 -0
  68. package/dist/ai/cache/miss.d.ts +49 -0
  69. package/dist/ai/cache/miss.js +96 -0
  70. package/dist/ai/cache/reporting.d.ts +39 -0
  71. package/dist/ai/cache/reporting.js +103 -0
  72. package/dist/ai/cache/types.d.ts +94 -0
  73. package/dist/ai/cache/types.js +19 -0
  74. package/dist/ai/cache/warmer.d.ts +94 -0
  75. package/dist/ai/cache/warmer.js +224 -0
  76. package/dist/ai/context.d.ts +35 -0
  77. package/dist/ai/context.js +114 -0
  78. package/dist/ai/cost.d.ts +21 -0
  79. package/dist/ai/cost.js +60 -0
  80. package/dist/ai/event-stream.d.ts +33 -0
  81. package/dist/ai/event-stream.js +101 -0
  82. package/dist/ai/fake/fake-provider.d.ts +68 -0
  83. package/dist/ai/fake/fake-provider.js +278 -0
  84. package/dist/ai/fake/fake-script.d.ts +69 -0
  85. package/dist/ai/fake/fake-script.js +142 -0
  86. package/dist/ai/http.d.ts +54 -0
  87. package/dist/ai/http.js +212 -0
  88. package/dist/ai/json-partial.d.ts +17 -0
  89. package/dist/ai/json-partial.js +243 -0
  90. package/dist/ai/overflow.d.ts +22 -0
  91. package/dist/ai/overflow.js +61 -0
  92. package/dist/ai/providers/auth.d.ts +71 -0
  93. package/dist/ai/providers/auth.js +202 -0
  94. package/dist/ai/providers/builtin.d.ts +23 -0
  95. package/dist/ai/providers/builtin.js +148 -0
  96. package/dist/ai/providers/catalog-data.d.ts +5 -0
  97. package/dist/ai/providers/catalog-data.js +19 -0
  98. package/dist/ai/providers/catalog.d.ts +28 -0
  99. package/dist/ai/providers/catalog.js +166 -0
  100. package/dist/ai/providers/channels.d.ts +51 -0
  101. package/dist/ai/providers/channels.js +96 -0
  102. package/dist/ai/providers/enrich.d.ts +34 -0
  103. package/dist/ai/providers/enrich.js +86 -0
  104. package/dist/ai/providers/models-dev-cache.d.ts +53 -0
  105. package/dist/ai/providers/models-dev-cache.js +147 -0
  106. package/dist/ai/providers/models-dev.d.ts +99 -0
  107. package/dist/ai/providers/models-dev.js +315 -0
  108. package/dist/ai/providers/registry.d.ts +114 -0
  109. package/dist/ai/providers/registry.js +458 -0
  110. package/dist/ai/sse.d.ts +32 -0
  111. package/dist/ai/sse.js +140 -0
  112. package/dist/ai/thinking.d.ts +42 -0
  113. package/dist/ai/thinking.js +101 -0
  114. package/dist/ai/types.d.ts +448 -0
  115. package/dist/ai/types.js +19 -0
  116. package/dist/bundle/ama-sandbox.cjs +324 -0
  117. package/dist/bundle/ama.cjs +27837 -0
  118. package/dist/bundle.d.ts +9 -0
  119. package/dist/bundle.js +15 -0
  120. package/dist/cli/args.d.ts +85 -0
  121. package/dist/cli/args.js +408 -0
  122. package/dist/cli/bootstrap.d.ts +18 -0
  123. package/dist/cli/bootstrap.js +399 -0
  124. package/dist/cli/compose-providers.d.ts +37 -0
  125. package/dist/cli/compose-providers.js +107 -0
  126. package/dist/cli/compose-session.d.ts +72 -0
  127. package/dist/cli/compose-session.js +370 -0
  128. package/dist/cli/compose-store.d.ts +24 -0
  129. package/dist/cli/compose-store.js +125 -0
  130. package/dist/cli/compose.d.ts +108 -0
  131. package/dist/cli/compose.js +221 -0
  132. package/dist/cli/default-model.d.ts +16 -0
  133. package/dist/cli/default-model.js +24 -0
  134. package/dist/cli/deps.d.ts +207 -0
  135. package/dist/cli/deps.js +12 -0
  136. package/dist/cli/exit-codes.d.ts +29 -0
  137. package/dist/cli/exit-codes.js +40 -0
  138. package/dist/cli/main.d.ts +27 -0
  139. package/dist/cli/main.js +177 -0
  140. package/dist/cli/runtime.d.ts +90 -0
  141. package/dist/cli/runtime.js +8 -0
  142. package/dist/cli/startup-screen.d.ts +15 -0
  143. package/dist/cli/startup-screen.js +56 -0
  144. package/dist/cli/startup-steps.d.ts +35 -0
  145. package/dist/cli/startup-steps.js +202 -0
  146. package/dist/cli/subcommands/auth.d.ts +12 -0
  147. package/dist/cli/subcommands/auth.js +91 -0
  148. package/dist/cli/subcommands/config.d.ts +53 -0
  149. package/dist/cli/subcommands/config.js +277 -0
  150. package/dist/cli/subcommands/context.d.ts +21 -0
  151. package/dist/cli/subcommands/context.js +42 -0
  152. package/dist/cli/subcommands/doctor.d.ts +11 -0
  153. package/dist/cli/subcommands/doctor.js +246 -0
  154. package/dist/cli/subcommands/init.d.ts +6 -0
  155. package/dist/cli/subcommands/init.js +22 -0
  156. package/dist/cli/subcommands/model-meta.d.ts +16 -0
  157. package/dist/cli/subcommands/model-meta.js +54 -0
  158. package/dist/cli/subcommands/models-cache-probe.d.ts +34 -0
  159. package/dist/cli/subcommands/models-cache-probe.js +190 -0
  160. package/dist/cli/subcommands/models-discover.d.ts +46 -0
  161. package/dist/cli/subcommands/models-discover.js +232 -0
  162. package/dist/cli/subcommands/models.d.ts +40 -0
  163. package/dist/cli/subcommands/models.js +152 -0
  164. package/dist/cli/subcommands/providers-list.d.ts +8 -0
  165. package/dist/cli/subcommands/providers-list.js +97 -0
  166. package/dist/cli/subcommands/providers-plan.d.ts +79 -0
  167. package/dist/cli/subcommands/providers-plan.js +215 -0
  168. package/dist/cli/subcommands/providers.d.ts +27 -0
  169. package/dist/cli/subcommands/providers.js +433 -0
  170. package/dist/cli/subcommands/sessions.d.ts +11 -0
  171. package/dist/cli/subcommands/sessions.js +100 -0
  172. package/dist/codemode/capability.d.ts +37 -0
  173. package/dist/codemode/capability.js +55 -0
  174. package/dist/codemode/declarations.d.ts +44 -0
  175. package/dist/codemode/declarations.js +111 -0
  176. package/dist/codemode/host-side.d.ts +59 -0
  177. package/dist/codemode/host-side.js +253 -0
  178. package/dist/codemode/modes.d.ts +23 -0
  179. package/dist/codemode/modes.js +40 -0
  180. package/dist/codemode/protocol.d.ts +91 -0
  181. package/dist/codemode/protocol.js +114 -0
  182. package/dist/codemode/sandbox-entry.d.ts +25 -0
  183. package/dist/codemode/sandbox-entry.js +323 -0
  184. package/dist/codemode/store.d.ts +26 -0
  185. package/dist/codemode/store.js +53 -0
  186. package/dist/codemode/tool.d.ts +105 -0
  187. package/dist/codemode/tool.js +283 -0
  188. package/dist/compaction/branch-summary.d.ts +30 -0
  189. package/dist/compaction/branch-summary.js +79 -0
  190. package/dist/compaction/breaker.d.ts +32 -0
  191. package/dist/compaction/breaker.js +65 -0
  192. package/dist/compaction/cut-point.d.ts +23 -0
  193. package/dist/compaction/cut-point.js +70 -0
  194. package/dist/compaction/estimate.d.ts +30 -0
  195. package/dist/compaction/estimate.js +114 -0
  196. package/dist/compaction/prune-tier.d.ts +31 -0
  197. package/dist/compaction/prune-tier.js +83 -0
  198. package/dist/compaction/serialize.d.ts +20 -0
  199. package/dist/compaction/serialize.js +115 -0
  200. package/dist/compaction/summarize-tier.d.ts +111 -0
  201. package/dist/compaction/summarize-tier.js +305 -0
  202. package/dist/config/auth-file.d.ts +39 -0
  203. package/dist/config/auth-file.js +92 -0
  204. package/dist/config/context-files.d.ts +30 -0
  205. package/dist/config/context-files.js +77 -0
  206. package/dist/config/init.d.ts +30 -0
  207. package/dist/config/init.js +92 -0
  208. package/dist/config/json-schema.d.ts +14 -0
  209. package/dist/config/json-schema.js +182 -0
  210. package/dist/config/load.d.ts +45 -0
  211. package/dist/config/load.js +97 -0
  212. package/dist/config/merge.d.ts +73 -0
  213. package/dist/config/merge.js +248 -0
  214. package/dist/config/paths.d.ts +38 -0
  215. package/dist/config/paths.js +108 -0
  216. package/dist/config/profile.d.ts +27 -0
  217. package/dist/config/profile.js +65 -0
  218. package/dist/config/schema.d.ts +34 -0
  219. package/dist/config/schema.js +476 -0
  220. package/dist/config/trust.d.ts +42 -0
  221. package/dist/config/trust.js +122 -0
  222. package/dist/config/types.d.ts +190 -0
  223. package/dist/config/types.js +29 -0
  224. package/dist/config/write.d.ts +10 -0
  225. package/dist/config/write.js +25 -0
  226. package/dist/errors.d.ts +28 -0
  227. package/dist/errors.js +30 -0
  228. package/dist/hooks/config.d.ts +49 -0
  229. package/dist/hooks/config.js +102 -0
  230. package/dist/hooks/dispatcher.d.ts +41 -0
  231. package/dist/hooks/dispatcher.js +104 -0
  232. package/dist/hooks/matcher.d.ts +22 -0
  233. package/dist/hooks/matcher.js +108 -0
  234. package/dist/hooks/protocol.d.ts +33 -0
  235. package/dist/hooks/protocol.js +240 -0
  236. package/dist/hooks/runner.d.ts +30 -0
  237. package/dist/hooks/runner.js +143 -0
  238. package/dist/hooks/types.d.ts +147 -0
  239. package/dist/hooks/types.js +20 -0
  240. package/dist/host/api-impl.d.ts +75 -0
  241. package/dist/host/api-impl.js +173 -0
  242. package/dist/host/loader.d.ts +31 -0
  243. package/dist/host/loader.js +147 -0
  244. package/dist/host/types.d.ts +169 -0
  245. package/dist/host/types.js +14 -0
  246. package/dist/host.d.ts +5 -0
  247. package/dist/host.js +4 -0
  248. package/dist/index.d.ts +41 -0
  249. package/dist/index.js +28 -0
  250. package/dist/modes/commands-core.d.ts +44 -0
  251. package/dist/modes/commands-core.js +171 -0
  252. package/dist/modes/image-input.d.ts +27 -0
  253. package/dist/modes/image-input.js +78 -0
  254. package/dist/modes/interactive/approval-dialog.d.ts +48 -0
  255. package/dist/modes/interactive/approval-dialog.js +202 -0
  256. package/dist/modes/interactive/commands.d.ts +41 -0
  257. package/dist/modes/interactive/commands.js +201 -0
  258. package/dist/modes/interactive/completion.d.ts +53 -0
  259. package/dist/modes/interactive/completion.js +157 -0
  260. package/dist/modes/interactive/interactive-mode.d.ts +46 -0
  261. package/dist/modes/interactive/interactive-mode.js +491 -0
  262. package/dist/modes/interactive/key-dispatch.d.ts +29 -0
  263. package/dist/modes/interactive/key-dispatch.js +107 -0
  264. package/dist/modes/interactive/line/line-editor.d.ts +50 -0
  265. package/dist/modes/interactive/line/line-editor.js +232 -0
  266. package/dist/modes/interactive/line/line-mode.d.ts +20 -0
  267. package/dist/modes/interactive/line/line-mode.js +218 -0
  268. package/dist/modes/interactive/line/line-render.d.ts +35 -0
  269. package/dist/modes/interactive/line/line-render.js +171 -0
  270. package/dist/modes/interactive/line/paste-state.d.ts +26 -0
  271. package/dist/modes/interactive/line/paste-state.js +72 -0
  272. package/dist/modes/interactive/message-view.d.ts +77 -0
  273. package/dist/modes/interactive/message-view.js +269 -0
  274. package/dist/modes/interactive/pickers.d.ts +42 -0
  275. package/dist/modes/interactive/pickers.js +115 -0
  276. package/dist/modes/interactive/startup-ui.d.ts +33 -0
  277. package/dist/modes/interactive/startup-ui.js +268 -0
  278. package/dist/modes/interactive/status-bar.d.ts +48 -0
  279. package/dist/modes/interactive/status-bar.js +139 -0
  280. package/dist/modes/interactive/tool-view.d.ts +95 -0
  281. package/dist/modes/interactive/tool-view.js +344 -0
  282. package/dist/modes/print/json-event.d.ts +15 -0
  283. package/dist/modes/print/json-event.js +39 -0
  284. package/dist/modes/print/print-mode.d.ts +17 -0
  285. package/dist/modes/print/print-mode.js +107 -0
  286. package/dist/modes/rpc/commands.d.ts +40 -0
  287. package/dist/modes/rpc/commands.js +263 -0
  288. package/dist/modes/rpc/jsonl.d.ts +16 -0
  289. package/dist/modes/rpc/jsonl.js +55 -0
  290. package/dist/modes/rpc/rpc-mode.d.ts +22 -0
  291. package/dist/modes/rpc/rpc-mode.js +153 -0
  292. package/dist/modes/session-report.d.ts +55 -0
  293. package/dist/modes/session-report.js +278 -0
  294. package/dist/modes/shared.d.ts +13 -0
  295. package/dist/modes/shared.js +52 -0
  296. package/dist/modes/startup-ui-text.d.ts +16 -0
  297. package/dist/modes/startup-ui-text.js +103 -0
  298. package/dist/permissions/broker.d.ts +47 -0
  299. package/dist/permissions/broker.js +107 -0
  300. package/dist/permissions/dangerous.d.ts +47 -0
  301. package/dist/permissions/dangerous.js +370 -0
  302. package/dist/permissions/pipeline.d.ts +51 -0
  303. package/dist/permissions/pipeline.js +181 -0
  304. package/dist/permissions/preview.d.ts +43 -0
  305. package/dist/permissions/preview.js +463 -0
  306. package/dist/permissions/rules.d.ts +58 -0
  307. package/dist/permissions/rules.js +249 -0
  308. package/dist/permissions/types.d.ts +100 -0
  309. package/dist/permissions/types.js +18 -0
  310. package/dist/rpc.d.ts +173 -0
  311. package/dist/rpc.js +13 -0
  312. package/dist/sdk.d.ts +98 -0
  313. package/dist/sdk.js +195 -0
  314. package/dist/session/manager.d.ts +70 -0
  315. package/dist/session/manager.js +278 -0
  316. package/dist/session/migrate.d.ts +19 -0
  317. package/dist/session/migrate.js +53 -0
  318. package/dist/session/projection.d.ts +50 -0
  319. package/dist/session/projection.js +184 -0
  320. package/dist/session/store.d.ts +47 -0
  321. package/dist/session/store.js +210 -0
  322. package/dist/session/tree.d.ts +21 -0
  323. package/dist/session/tree.js +88 -0
  324. package/dist/session/types.d.ts +201 -0
  325. package/dist/session/types.js +18 -0
  326. package/dist/skills/discover.d.ts +60 -0
  327. package/dist/skills/discover.js +160 -0
  328. package/dist/skills/expand.d.ts +35 -0
  329. package/dist/skills/expand.js +46 -0
  330. package/dist/skills/frontmatter.d.ts +27 -0
  331. package/dist/skills/frontmatter.js +157 -0
  332. package/dist/skills/index-prompt.d.ts +13 -0
  333. package/dist/skills/index-prompt.js +42 -0
  334. package/dist/skills/templates.d.ts +52 -0
  335. package/dist/skills/templates.js +177 -0
  336. package/dist/tools/bash.d.ts +49 -0
  337. package/dist/tools/bash.js +222 -0
  338. package/dist/tools/edit-fuzzy.d.ts +36 -0
  339. package/dist/tools/edit-fuzzy.js +129 -0
  340. package/dist/tools/edit.d.ts +38 -0
  341. package/dist/tools/edit.js +241 -0
  342. package/dist/tools/file-mutex.d.ts +8 -0
  343. package/dist/tools/file-mutex.js +29 -0
  344. package/dist/tools/glob.d.ts +44 -0
  345. package/dist/tools/glob.js +217 -0
  346. package/dist/tools/grep.d.ts +39 -0
  347. package/dist/tools/grep.js +179 -0
  348. package/dist/tools/ignore.d.ts +40 -0
  349. package/dist/tools/ignore.js +174 -0
  350. package/dist/tools/image-file.d.ts +31 -0
  351. package/dist/tools/image-file.js +114 -0
  352. package/dist/tools/ls.d.ts +21 -0
  353. package/dist/tools/ls.js +96 -0
  354. package/dist/tools/output-accumulator.d.ts +48 -0
  355. package/dist/tools/output-accumulator.js +106 -0
  356. package/dist/tools/paths.d.ts +20 -0
  357. package/dist/tools/paths.js +58 -0
  358. package/dist/tools/presets.d.ts +71 -0
  359. package/dist/tools/presets.js +128 -0
  360. package/dist/tools/process-tree.d.ts +35 -0
  361. package/dist/tools/process-tree.js +125 -0
  362. package/dist/tools/read.d.ts +24 -0
  363. package/dist/tools/read.js +132 -0
  364. package/dist/tools/registry.d.ts +43 -0
  365. package/dist/tools/registry.js +106 -0
  366. package/dist/tools/shell.d.ts +38 -0
  367. package/dist/tools/shell.js +91 -0
  368. package/dist/tools/task.d.ts +29 -0
  369. package/dist/tools/task.js +107 -0
  370. package/dist/tools/todo.d.ts +28 -0
  371. package/dist/tools/todo.js +107 -0
  372. package/dist/tools/truncate.d.ts +44 -0
  373. package/dist/tools/truncate.js +175 -0
  374. package/dist/tools/types.d.ts +135 -0
  375. package/dist/tools/types.js +19 -0
  376. package/dist/tools/write.d.ts +20 -0
  377. package/dist/tools/write.js +84 -0
  378. package/dist/tui/ansi.d.ts +29 -0
  379. package/dist/tui/ansi.js +420 -0
  380. package/dist/tui/component.d.ts +38 -0
  381. package/dist/tui/component.js +13 -0
  382. package/dist/tui/components/box.d.ts +26 -0
  383. package/dist/tui/components/box.js +65 -0
  384. package/dist/tui/components/container.d.ts +14 -0
  385. package/dist/tui/components/container.js +39 -0
  386. package/dist/tui/components/editor-buffer.d.ts +67 -0
  387. package/dist/tui/components/editor-buffer.js +300 -0
  388. package/dist/tui/components/editor-paste.d.ts +29 -0
  389. package/dist/tui/components/editor-paste.js +64 -0
  390. package/dist/tui/components/editor.d.ts +114 -0
  391. package/dist/tui/components/editor.js +530 -0
  392. package/dist/tui/components/key-value.d.ts +29 -0
  393. package/dist/tui/components/key-value.js +48 -0
  394. package/dist/tui/components/loader.d.ts +35 -0
  395. package/dist/tui/components/loader.js +71 -0
  396. package/dist/tui/components/markdown.d.ts +90 -0
  397. package/dist/tui/components/markdown.js +462 -0
  398. package/dist/tui/components/meter.d.ts +29 -0
  399. package/dist/tui/components/meter.js +47 -0
  400. package/dist/tui/components/overlay.d.ts +24 -0
  401. package/dist/tui/components/overlay.js +52 -0
  402. package/dist/tui/components/select-list.d.ts +57 -0
  403. package/dist/tui/components/select-list.js +179 -0
  404. package/dist/tui/components/spacer.d.ts +11 -0
  405. package/dist/tui/components/spacer.js +16 -0
  406. package/dist/tui/components/text.d.ts +30 -0
  407. package/dist/tui/components/text.js +65 -0
  408. package/dist/tui/keybindings.d.ts +66 -0
  409. package/dist/tui/keybindings.js +120 -0
  410. package/dist/tui/keys.d.ts +38 -0
  411. package/dist/tui/keys.js +275 -0
  412. package/dist/tui/stdin-buffer.d.ts +41 -0
  413. package/dist/tui/stdin-buffer.js +206 -0
  414. package/dist/tui/terminal.d.ts +79 -0
  415. package/dist/tui/terminal.js +153 -0
  416. package/dist/tui/theme.d.ts +31 -0
  417. package/dist/tui/theme.js +199 -0
  418. package/dist/tui/tui.d.ts +103 -0
  419. package/dist/tui/tui.js +363 -0
  420. package/dist/tui/vt-screen.d.ts +46 -0
  421. package/dist/tui/vt-screen.js +251 -0
  422. package/dist/tui.d.ts +30 -0
  423. package/dist/tui.js +31 -0
  424. package/dist/version.d.ts +8 -0
  425. package/dist/version.js +24 -0
  426. package/docs/codemode.md +102 -0
  427. package/docs/hooks.md +196 -0
  428. package/docs/host-api.md +161 -0
  429. package/docs/providers.md +531 -0
  430. package/docs/rpc.md +253 -0
  431. package/docs/session-format.md +119 -0
  432. package/docs/tui.md +170 -0
  433. package/package.json +101 -4
@@ -0,0 +1,251 @@
1
+ /**
2
+ * 会话侧的压缩调度(设计 §9)。[B2]
3
+ *
4
+ * - 阈值检查(新提示前、`prepareNextTurn` 里):估算 > 0.7 ×(窗口 − 预留)→ 档一裁剪;仍 > 窗口 − 预留
5
+ * 且熔断允许 → 档二摘要(trigger `threshold`)。
6
+ * - 溢出恢复(会话 run 结束后,失败尝试已用 context_edit 剔除):PreCompact Hook → 档二摘要(trigger
7
+ * `overflow`,不受「每 run 一次」限制但受跳闸限制)→ 压缩后估算 ≤ 0.8 × 窗口才重试。
8
+ * - 手动 `/compact`:PreCompact(trigger `manual`)→ 摘要;成功清零熔断。
9
+ * PreCompact 的 `decision: "block"` 取消本次压缩;`customInstructions` 追加到摘要提示。
10
+ * [W3-C1b] 阈值 / 手动压缩与分支摘要优先走会话前缀续写(缓存控制器给前缀),溢出恢复不走
11
+ * (前缀本身已超窗口);续写失败回落独立请求并记 warning。
12
+ */
13
+ import { AmaError } from "../errors.js";
14
+ import { CompactionBreaker } from "../compaction/breaker.js";
15
+ import { estimateProjectedTokens } from "../compaction/estimate.js";
16
+ import { planPrune, shouldPrune } from "../compaction/prune-tier.js";
17
+ import { prepareCompaction, runCompaction, } from "../compaction/summarize-tier.js";
18
+ import { prepareBranchSummary, runBranchSummary } from "../compaction/branch-summary.js";
19
+ import { buildProjection } from "../session/projection.js";
20
+ export const DEFAULT_COMPACTION_SETTINGS = {
21
+ enabled: true,
22
+ reserveTokens: 16_384,
23
+ keepRecentTokens: 20_000,
24
+ };
25
+ /** 保留区不超过 (窗口 − 预留) 的 40%,否则小窗口模型上摘要后仍然溢出。 */
26
+ export const KEEP_RECENT_MAX_RATIO = 0.4;
27
+ export class CompactionController {
28
+ breaker;
29
+ settings;
30
+ core;
31
+ compacting = false;
32
+ constructor(core, settings = {}) {
33
+ this.core = core;
34
+ this.settings = { ...DEFAULT_COMPACTION_SETTINGS, ...settings };
35
+ this.breaker = new CompactionBreaker(this.settings.enabled, core.model().contextWindow);
36
+ }
37
+ get isCompacting() {
38
+ return this.compacting;
39
+ }
40
+ /** 模型或开关变化后调用。 */
41
+ refresh() {
42
+ this.breaker.configure(this.settings.enabled, this.core.model().contextWindow);
43
+ }
44
+ setAuto(enabled) {
45
+ this.settings = { ...this.settings, enabled };
46
+ this.refresh();
47
+ }
48
+ estimate() {
49
+ const branch = this.core.manager.branch();
50
+ return estimateProjectedTokens(buildProjection(branch).items, branch);
51
+ }
52
+ budget() {
53
+ const window = this.core.model().contextWindow;
54
+ return window === undefined ? undefined : Math.max(0, window - this.settings.reserveTokens);
55
+ }
56
+ keepRecent() {
57
+ const budget = this.budget();
58
+ if (budget === undefined)
59
+ return this.settings.keepRecentTokens;
60
+ return Math.max(1, Math.min(this.settings.keepRecentTokens, Math.floor(budget * KEEP_RECENT_MAX_RATIO)));
61
+ }
62
+ /** 摘要请求的公共选项;`continuation` 时附上会话前缀续写的材料。 */
63
+ async summarizer(signal, instructions, continuation) {
64
+ const core = this.core;
65
+ const options = {
66
+ stream: core.stream,
67
+ model: core.model(),
68
+ apiKey: await core.resolveApiKey(),
69
+ signal,
70
+ customInstructions: instructions,
71
+ onFallback: (reason) => core.log("warn", `summary by prefix continuation failed (${reason}); used a separate request`),
72
+ };
73
+ if (continuation)
74
+ options.continuation = core.cache?.summaryContinuation();
75
+ return options;
76
+ }
77
+ /** 档一;返回是否裁剪了内容。 */
78
+ prune() {
79
+ const branch = this.core.manager.branch();
80
+ const plan = planPrune(buildProjection(branch).items, { outputDir: this.core.outputDir() });
81
+ for (const item of plan) {
82
+ this.core.appendEntry({
83
+ type: "context_edit",
84
+ targetId: item.targetId,
85
+ replacement: item.replacement,
86
+ reason: "prune",
87
+ });
88
+ }
89
+ if (plan.length > 0)
90
+ this.core.reloadMessages();
91
+ return plan.length > 0;
92
+ }
93
+ /** 阈值检查(档一 → 档二)。失败只记录,不打断 run。 */
94
+ async checkThreshold(signal) {
95
+ if (!this.breaker.autoEnabled || this.compacting || signal.aborted)
96
+ return;
97
+ const window = this.core.model().contextWindow;
98
+ const reserve = this.settings.reserveTokens;
99
+ let tokens = this.estimate().tokens;
100
+ if (shouldPrune(tokens, window, reserve) && this.prune())
101
+ tokens = this.estimate().tokens;
102
+ if (tokens <= window - reserve || !this.breaker.canSummarize())
103
+ return;
104
+ await this.summarize("threshold", signal);
105
+ }
106
+ /** 溢出恢复:返回是否应以新 run 重试。 */
107
+ async recoverOverflow(signal) {
108
+ if (!this.settings.enabled)
109
+ return { retry: false, warning: "context overflow: auto-compaction is disabled" };
110
+ if (this.core.model().contextWindow === undefined) {
111
+ return {
112
+ retry: false,
113
+ warning: "context overflow: model has no contextWindow, auto-compaction is off",
114
+ };
115
+ }
116
+ if (this.breaker.tripped) {
117
+ return {
118
+ retry: false,
119
+ warning: "context overflow: auto-compaction disabled after repeated failures",
120
+ };
121
+ }
122
+ const outcome = await this.summarize("overflow", signal);
123
+ if (outcome.result === undefined) {
124
+ if (signal.aborted)
125
+ return { retry: false };
126
+ return {
127
+ retry: false,
128
+ warning: `context overflow: compaction failed (${outcome.error ?? "unknown"})`,
129
+ };
130
+ }
131
+ if (!this.breaker.shouldRetryAfterCompaction(outcome.tokensAfter ?? Number.POSITIVE_INFINITY)) {
132
+ return {
133
+ retry: false,
134
+ warning: "context overflow: still above 80% of the window after compaction",
135
+ };
136
+ }
137
+ return { retry: true };
138
+ }
139
+ async compactManual(instructions, signal) {
140
+ const outcome = await this.summarize("manual", signal, instructions);
141
+ if (outcome.result === undefined) {
142
+ if (outcome.aborted)
143
+ throw new AmaError("aborted", "compaction aborted");
144
+ throw new AmaError("compaction_failed", outcome.error ?? "compaction failed");
145
+ }
146
+ this.breaker.reset();
147
+ return outcome.result;
148
+ }
149
+ /** `/tree` 离开分支:换叶子,并为离开的那段写 branch_summary(挂在新叶子下)。 */
150
+ async leaveBranch(targetId, instructions, signal) {
151
+ const core = this.core;
152
+ const index = new Map(core.manager.entries().map((entry) => [entry.id, entry]));
153
+ const plan = prepareBranchSummary(index, core.manager.leafId(), targetId);
154
+ core.manager.setLeaf(targetId);
155
+ if (plan === undefined)
156
+ return undefined;
157
+ const draft = await runBranchSummary(plan, await this.summarizer(signal, instructions, true));
158
+ return core.appendEntry({
159
+ type: "branch_summary",
160
+ fromId: draft.fromId,
161
+ summary: draft.summary,
162
+ usage: draft.usage,
163
+ details: draft.details,
164
+ });
165
+ }
166
+ async summarize(trigger, signal, instructions) {
167
+ const core = this.core;
168
+ this.compacting = true;
169
+ core.emit({ type: "compaction_start", trigger });
170
+ const end = (outcome, willRetry) => {
171
+ const event = {
172
+ type: "compaction_end",
173
+ trigger,
174
+ aborted: outcome.aborted,
175
+ willRetry,
176
+ };
177
+ if (outcome.result !== undefined)
178
+ event.result = outcome.result;
179
+ if (outcome.error !== undefined)
180
+ event.error = outcome.error;
181
+ core.emit(event);
182
+ this.compacting = false;
183
+ return outcome;
184
+ };
185
+ const fail = (error, aborted = false) => end({ result: undefined, tokensAfter: undefined, error, aborted }, false);
186
+ const tokensBefore = this.estimate().tokens;
187
+ let customInstructions = instructions;
188
+ const hook = await core.runHook("PreCompact", { tokensBefore, trigger: trigger === "manual" ? "manual" : "auto" }, signal);
189
+ if (hook !== undefined) {
190
+ if (hook.decision === "block" || hook.decision === "deny") {
191
+ return fail(hook.reason ?? "compaction blocked by PreCompact hook", true);
192
+ }
193
+ if (hook.customInstructions !== undefined) {
194
+ customInstructions = [customInstructions, hook.customInstructions]
195
+ .filter(Boolean)
196
+ .join("\n\n");
197
+ }
198
+ }
199
+ if (signal.aborted)
200
+ return fail("aborted", true);
201
+ // 保留区按预算切不出可摘要的前缀(单条消息很大)时逐级缩小,最后只保留最近一个切点。
202
+ const projection = buildProjection(core.manager.branch());
203
+ const keep = this.keepRecent();
204
+ let plan;
205
+ for (const budget of [keep, Math.floor(keep / 4), 1]) {
206
+ plan = prepareCompaction(projection, Math.max(1, budget));
207
+ if (plan !== undefined)
208
+ break;
209
+ }
210
+ if (plan === undefined) {
211
+ if (trigger !== "manual")
212
+ this.breaker.recordSummary(false);
213
+ return fail("nothing to compact");
214
+ }
215
+ try {
216
+ const options = await this.summarizer(signal, customInstructions, trigger !== "overflow");
217
+ const draft = await runCompaction(plan, options);
218
+ if (signal.aborted)
219
+ return fail("aborted", true);
220
+ const entry = {
221
+ type: "compaction",
222
+ summary: draft.summary,
223
+ firstKeptEntryId: draft.firstKeptEntryId,
224
+ tokensBefore,
225
+ details: draft.details,
226
+ };
227
+ if (draft.usage !== undefined)
228
+ entry.usage = draft.usage;
229
+ core.appendEntry(entry);
230
+ core.reloadMessages();
231
+ this.breaker.recordSummary(true);
232
+ const tokensAfter = this.estimate().tokens;
233
+ const result = {
234
+ summary: draft.summary,
235
+ firstKeptEntryId: draft.firstKeptEntryId,
236
+ tokensBefore,
237
+ tokensAfter,
238
+ };
239
+ if (draft.usage !== undefined)
240
+ result.usage = draft.usage;
241
+ const willRetry = trigger === "overflow" && this.breaker.shouldRetryAfterCompaction(tokensAfter);
242
+ return end({ result, tokensAfter, error: undefined, aborted: false }, willRetry);
243
+ }
244
+ catch (error) {
245
+ const aborted = signal.aborted || (error instanceof AmaError && error.code === "aborted");
246
+ if (!aborted)
247
+ this.breaker.recordSummary(false);
248
+ return fail(error instanceof Error ? error.message : String(error), aborted);
249
+ }
250
+ }
251
+ }
@@ -0,0 +1,103 @@
1
+ /**
2
+ * AgentSessionImpl 的装配选项与内部协作接口。[B2]
3
+ *
4
+ * `AgentSessionOptions` 是集成者(B5 bootstrap / B6 sdk)构造会话时注入的全部依赖;
5
+ * `SessionCore` 是 session.ts 交给 session-tools.ts / session-compaction.ts 的内部视图(避免循环 import)。
6
+ */
7
+ import type { WarmingDecisionHandler } from "../ai/cache/types.js";
8
+ import type { Model, ModelThinkingLevel, ProviderRegistryApi } from "../ai/types.js";
9
+ import type { HookDispatcherApi, HookEvent, HookEventPayload, HookOutcome } from "../hooks/types.js";
10
+ import type { ApprovalBroker, PermissionPipelineApi } from "../permissions/types.js";
11
+ import type { SessionManager } from "../session/manager.js";
12
+ import type { SessionEntry, SessionEntryInput } from "../session/types.js";
13
+ import type { SubagentRequest, SubagentResult, ToolDefinition } from "../tools/types.js";
14
+ import type { Agent } from "./agent.js";
15
+ import type { StreamFn } from "./loop.js";
16
+ import type { SessionCacheController } from "./session-cache.js";
17
+ import type { SystemPromptInput } from "./system-prompt.js";
18
+ import type { CacheSettings, CompactionSettings, QueueMode, RetrySettings, SessionEvent } from "./types.js";
19
+ export type PromptExpansion = {
20
+ text: string;
21
+ } | {
22
+ handled: true;
23
+ };
24
+ export interface AgentSessionOptions {
25
+ sessionManager: SessionManager;
26
+ /** 供应商注册表:getApi / resolveApiKey / findModel(setModel 与子 Agent 用)。 */
27
+ providers: ProviderRegistryApi;
28
+ model: Model;
29
+ thinkingLevel?: ModelThinkingLevel;
30
+ /** 全部可用工具(内置 + 宿主 + SDK)。 */
31
+ tools?: readonly ToolDefinition[];
32
+ /** 活动集;缺省 = tools 全部。 */
33
+ activeTools?: readonly string[];
34
+ /** 权限管线(B3);缺省 = 全部放行。 */
35
+ permission?: PermissionPipelineApi;
36
+ /** 审批回答者链:宿主 broker → UI broker;都返回 undefined → deny(无人值守)。 */
37
+ brokers?: readonly ApprovalBroker[];
38
+ /** 无人值守:权限管线把 ask 变 deny。 */
39
+ unattended?: boolean;
40
+ /** 审批超时,缺省 10 分钟(超时 deny)。 */
41
+ approvalTimeoutMs?: number;
42
+ /** 命令式 Hook(B5);缺省无 Hook。 */
43
+ hooks?: HookDispatcherApi;
44
+ /** 系统提示的静态部分(工具与 cwd 由会话填)。 */
45
+ system?: Omit<SystemPromptInput, "tools" | "cwd">;
46
+ compaction?: Partial<CompactionSettings>;
47
+ retry?: Partial<RetrySettings>;
48
+ steeringMode?: QueueMode;
49
+ followUpMode?: QueueMode;
50
+ /** 模板 / `/skill:` 展开(B3 / B7);`handled` = 已作为命令处理,不进模型。 */
51
+ expandPrompt?(text: string): Promise<PromptExpansion>;
52
+ /** 溢出文案识别(B1 的 ai/overflow.ts);缺省用 retry.ts 内置正则。 */
53
+ isContextOverflow?(errorMessage: string): boolean;
54
+ /** 缺省 30 000。 */
55
+ maxToolResultChars?: number;
56
+ /** abort 后等待工具自行结束的上限,缺省 3 000 ms。 */
57
+ abortGraceMs?: number;
58
+ /** 截断全文目录;缺省 `<会话文件目录>/outputs`,内存会话 undefined。 */
59
+ outputDir?: string;
60
+ /** task 深度:主会话 0。 */
61
+ depth?: number;
62
+ /** 子 Agent 的回合上限(maxTurns)。 */
63
+ maxTurns?: number;
64
+ /** 子 Agent 并发上限,缺省 4;`false` 关闭 spawnSubagent。 */
65
+ subagents?: {
66
+ maxConcurrent?: number;
67
+ } | false;
68
+ /** 宿主适配器 id(写进 HookInput.host)。 */
69
+ hostId?: string;
70
+ /** [W3-C1b] 会话层缓存设置(config `cache` 段 + 环境变量,组装根解析);缺省见 DEFAULT_CACHE_SETTINGS。 */
71
+ cache?: Partial<CacheSettings>;
72
+ /** [W3-C1b] 宿主 `cache.onWarmingDecision` 的处理器(每次保温前现取)。 */
73
+ warmingDecider?(): WarmingDecisionHandler | undefined;
74
+ log?(level: "debug" | "info" | "warn" | "error", message: string): void;
75
+ }
76
+ export interface SessionCore {
77
+ readonly options: AgentSessionOptions;
78
+ readonly manager: SessionManager;
79
+ readonly agent: Agent;
80
+ readonly cwd: string;
81
+ readonly depth: number;
82
+ readonly readFiles: Set<string>;
83
+ /** [W3-C1b] 会话层缓存控制器(摘要续写取前缀)。 */
84
+ readonly cache?: SessionCacheController;
85
+ model(): Model;
86
+ thinkingLevel(): ModelThinkingLevel;
87
+ outputDir(): string | undefined;
88
+ stream: StreamFn;
89
+ resolveApiKey(): Promise<string | undefined>;
90
+ emit(event: SessionEvent): void;
91
+ appendEntry(input: SessionEntryInput): SessionEntry;
92
+ /** 从会话管理器重建 Agent 的上下文消息。 */
93
+ reloadMessages(): void;
94
+ activeTool(name: string): ToolDefinition | undefined;
95
+ /** 任一已登记工具(不限于活动集;嵌套调用用)。 */
96
+ tool(name: string): ToolDefinition | undefined;
97
+ activeToolNames(): string[];
98
+ runHook(event: HookEvent, payload: HookEventPayload, signal?: AbortSignal): Promise<HookOutcome | undefined>;
99
+ /** Hook 返回 continue:false 时记下,finishTurn 据此结束 run。 */
100
+ requestStop(reason: string | undefined): void;
101
+ spawnSubagent(request: SubagentRequest): Promise<SubagentResult>;
102
+ log(level: "debug" | "info" | "warn" | "error", message: string): void;
103
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * AgentSessionImpl 的装配选项与内部协作接口。[B2]
3
+ *
4
+ * `AgentSessionOptions` 是集成者(B5 bootstrap / B6 sdk)构造会话时注入的全部依赖;
5
+ * `SessionCore` 是 session.ts 交给 session-tools.ts / session-compaction.ts 的内部视图(避免循环 import)。
6
+ */
7
+ export {};
@@ -0,0 +1,55 @@
1
+ /**
2
+ * 会话级 run 编排(设计 §3.6 重试、§4.2 abort、§6.1 Stop Hook、§9 溢出恢复)。[B2]
3
+ *
4
+ * 一次「会话周期」(prompt 到 agent_settled)可以包含多个 Agent run:
5
+ * - 可重试错误:agent_end{willRetry:true} → 失败尝试 context_edit{reason:"retry"} 剔除 →
6
+ * auto_retry_start → 退避(abort 可打断)→ 新 run(continue);结束时 auto_retry_end。
7
+ * - 溢出 / length 无工具调用:agent_end{willRetry:true} → context_edit{reason:"overflow"} 剔除 →
8
+ * PreCompact → 压缩 → 以新 run 重试**一次**;失败 / 取消则保留剔除、不重试,agent_settled{warning}。
9
+ * - abort:不清队列;落盘 custom_message{customType:"ama.aborted"};不再自动续跑。
10
+ * - 将要停下时发 agent_before_settle 并跑 Stop(子 Agent 为 SubagentStop)Hook:block + reason →
11
+ * 以 reason 作为新 user 消息再跑一轮(上限 3 次,stopHookActive 传给 Hook)。
12
+ * - 最终失败后若 followUp 队列非空,照常投递。
13
+ */
14
+ import type { AssistantMessage, ImageBlock, UserMessage } from "../ai/types.js";
15
+ import type { AgentMessage } from "../session/types.js";
16
+ import type { RunOutcome } from "./loop.js";
17
+ import type { SessionCore } from "./session-core.js";
18
+ import type { CompactionController } from "./session-compaction.js";
19
+ import type { PromptDisposition, RetrySettings } from "./types.js";
20
+ export declare const MAX_STOP_HOOK_CONTINUATIONS = 3;
21
+ export declare const ABORTED_CUSTOM_TYPE = "ama.aborted";
22
+ export type RunDecision = {
23
+ kind: "done";
24
+ } | {
25
+ kind: "aborted";
26
+ } | {
27
+ kind: "retry";
28
+ errorMessage: string;
29
+ } | {
30
+ kind: "overflow";
31
+ } | {
32
+ kind: "failed";
33
+ errorMessage: string;
34
+ };
35
+ export interface RunCycleDeps {
36
+ core: SessionCore;
37
+ compaction: CompactionController;
38
+ retry(): RetrySettings;
39
+ syncSystem(): void;
40
+ stopRequested(): boolean;
41
+ setRetrying(value: boolean): void;
42
+ lastAssistantText(): string | null;
43
+ }
44
+ export declare function decideAfterRun(deps: RunCycleDeps, outcome: RunOutcome, retryAttempt: number, overflowRecovered: boolean): RunDecision;
45
+ /** 用 context_edit 把失败尝试(助手消息与其后补的结果)从上下文剔除。 */
46
+ export declare function excludeFailedAttempt(core: SessionCore, failed: AssistantMessage | undefined, reason: "retry" | "overflow"): void;
47
+ export declare function recordAbort(core: SessionCore): void;
48
+ export declare function runCycle(deps: RunCycleDeps, prompts: AgentMessage[], signal: AbortSignal): Promise<void>;
49
+ export declare function makeUserMessage(text: string, images?: readonly ImageBlock[], origin?: string): UserMessage;
50
+ /**
51
+ * 一次提示:展开(expandPrompt)→ UserPromptSubmit Hook(block 拒绝;updatedPrompt 替换;
52
+ * additionalContext 作为 custom_message 随提示进上下文)→ 阈值压缩检查 → system 同步 →
53
+ * `before_agent_start`(宿主事件同名,由组装根桥接)→ 会话周期。
54
+ */
55
+ export declare function runPrompt(deps: RunCycleDeps, text: string, images: readonly ImageBlock[] | undefined, origin: string | undefined, signal: AbortSignal): Promise<PromptDisposition>;
@@ -0,0 +1,246 @@
1
+ /**
2
+ * 会话级 run 编排(设计 §3.6 重试、§4.2 abort、§6.1 Stop Hook、§9 溢出恢复)。[B2]
3
+ *
4
+ * 一次「会话周期」(prompt 到 agent_settled)可以包含多个 Agent run:
5
+ * - 可重试错误:agent_end{willRetry:true} → 失败尝试 context_edit{reason:"retry"} 剔除 →
6
+ * auto_retry_start → 退避(abort 可打断)→ 新 run(continue);结束时 auto_retry_end。
7
+ * - 溢出 / length 无工具调用:agent_end{willRetry:true} → context_edit{reason:"overflow"} 剔除 →
8
+ * PreCompact → 压缩 → 以新 run 重试**一次**;失败 / 取消则保留剔除、不重试,agent_settled{warning}。
9
+ * - abort:不清队列;落盘 custom_message{customType:"ama.aborted"};不再自动续跑。
10
+ * - 将要停下时发 agent_before_settle 并跑 Stop(子 Agent 为 SubagentStop)Hook:block + reason →
11
+ * 以 reason 作为新 user 消息再跑一轮(上限 3 次,stopHookActive 传给 Hook)。
12
+ * - 最终失败后若 followUp 队列非空,照常投递。
13
+ */
14
+ import { AmaError } from "../errors.js";
15
+ import { classifyFailure, retryDelayMs, sleep } from "./retry.js";
16
+ export const MAX_STOP_HOOK_CONTINUATIONS = 3;
17
+ export const ABORTED_CUSTOM_TYPE = "ama.aborted";
18
+ export function decideAfterRun(deps, outcome, retryAttempt, overflowRecovered) {
19
+ if (outcome.stopReason === "aborted")
20
+ return { kind: "aborted" };
21
+ const last = outcome.lastAssistant;
22
+ if (last === undefined)
23
+ return { kind: "done" };
24
+ const failedStop = last.stopReason === "error" || outcome.stopReason === "length";
25
+ if (!failedStop)
26
+ return { kind: "done" };
27
+ const errorMessage = last.errorMessage ?? (last.stopReason === "length" ? "output hit the token limit" : "error");
28
+ const classifyOptions = deps.core.options.isContextOverflow === undefined
29
+ ? {}
30
+ : { isContextOverflow: deps.core.options.isContextOverflow };
31
+ const kind = classifyFailure(last, classifyOptions);
32
+ if (kind === "overflow") {
33
+ const compaction = deps.compaction;
34
+ const recoverable = !overflowRecovered &&
35
+ compaction.settings.enabled &&
36
+ deps.core.model().contextWindow !== undefined &&
37
+ !compaction.breaker.tripped;
38
+ return recoverable ? { kind: "overflow" } : { kind: "failed", errorMessage };
39
+ }
40
+ const settings = deps.retry();
41
+ if (kind === "retryable" && settings.enabled && retryAttempt < settings.maxRetries) {
42
+ return { kind: "retry", errorMessage };
43
+ }
44
+ return { kind: "failed", errorMessage };
45
+ }
46
+ /** 用 context_edit 把失败尝试(助手消息与其后补的结果)从上下文剔除。 */
47
+ export function excludeFailedAttempt(core, failed, reason) {
48
+ if (failed === undefined)
49
+ return;
50
+ const branch = core.manager.branch();
51
+ const at = branch.findIndex((entry) => entry.type === "message" && entry.message === failed);
52
+ if (at < 0)
53
+ return;
54
+ const targets = [branch[at]?.id];
55
+ for (const entry of branch.slice(at + 1)) {
56
+ if (entry.type === "message" && entry.message.role === "toolResult")
57
+ targets.push(entry.id);
58
+ }
59
+ for (const targetId of targets) {
60
+ if (targetId !== undefined) {
61
+ core.appendEntry({ type: "context_edit", targetId, replacement: null, reason });
62
+ }
63
+ }
64
+ core.reloadMessages();
65
+ }
66
+ export function recordAbort(core) {
67
+ core.appendEntry({
68
+ type: "custom_message",
69
+ customType: ABORTED_CUSTOM_TYPE,
70
+ content: "The user interrupted the previous response before it finished.",
71
+ display: false,
72
+ });
73
+ core.reloadMessages();
74
+ }
75
+ export async function runCycle(deps, prompts, signal) {
76
+ const { core, compaction } = deps;
77
+ let next = prompts;
78
+ let retryAttempt = 0;
79
+ let overflowRecovered = false;
80
+ let stopHooks = 0;
81
+ let warning;
82
+ let announced = false;
83
+ const endRetry = (success, finalError) => {
84
+ if (retryAttempt === 0)
85
+ return;
86
+ const event = {
87
+ type: "auto_retry_end",
88
+ success,
89
+ attempt: retryAttempt,
90
+ };
91
+ if (finalError !== undefined)
92
+ event.finalError = finalError;
93
+ core.emit(event);
94
+ deps.setRetrying(false);
95
+ retryAttempt = 0;
96
+ };
97
+ while (next !== undefined) {
98
+ announced = false;
99
+ let decision = { kind: "done" };
100
+ const outcome = await core.agent.run(next, {
101
+ signal,
102
+ onRunEnd: (result) => {
103
+ decision = decideAfterRun(deps, result, retryAttempt, overflowRecovered);
104
+ return decision.kind === "retry" || decision.kind === "overflow";
105
+ },
106
+ });
107
+ next = undefined;
108
+ const current = decision;
109
+ if (current.kind === "aborted" || signal.aborted) {
110
+ endRetry(false, "aborted");
111
+ recordAbort(core);
112
+ break;
113
+ }
114
+ if (current.kind === "retry") {
115
+ retryAttempt++;
116
+ deps.setRetrying(true);
117
+ excludeFailedAttempt(core, outcome.lastAssistant, "retry");
118
+ const settings = deps.retry();
119
+ const delayMs = retryDelayMs(retryAttempt, settings);
120
+ core.emit({
121
+ type: "auto_retry_start",
122
+ attempt: retryAttempt,
123
+ maxAttempts: settings.maxRetries,
124
+ delayMs,
125
+ errorMessage: current.errorMessage,
126
+ });
127
+ void core.runHook("Notification", {
128
+ notification: {
129
+ kind: "retry",
130
+ message: `retry ${retryAttempt}/${settings.maxRetries}: ${current.errorMessage}`,
131
+ },
132
+ });
133
+ try {
134
+ await sleep(delayMs, signal);
135
+ }
136
+ catch {
137
+ endRetry(false, "aborted");
138
+ recordAbort(core);
139
+ break;
140
+ }
141
+ next = [];
142
+ continue;
143
+ }
144
+ endRetry(current.kind === "done", current.kind === "failed" ? current.errorMessage : undefined);
145
+ if (current.kind === "overflow") {
146
+ overflowRecovered = true;
147
+ excludeFailedAttempt(core, outcome.lastAssistant, "overflow");
148
+ const recovery = await compaction.recoverOverflow(signal);
149
+ if (signal.aborted) {
150
+ recordAbort(core);
151
+ break;
152
+ }
153
+ if (recovery.retry) {
154
+ next = [];
155
+ continue;
156
+ }
157
+ warning = recovery.warning;
158
+ }
159
+ else if (current.kind === "failed") {
160
+ warning = current.errorMessage;
161
+ void core.runHook("Notification", {
162
+ notification: { kind: "error", message: current.errorMessage },
163
+ });
164
+ }
165
+ if (current.kind === "failed" && core.agent.followUpQueue.hasItems()) {
166
+ next = core.agent.followUpQueue.drain();
167
+ continue;
168
+ }
169
+ core.emit({ type: "agent_before_settle" });
170
+ announced = true;
171
+ if (current.kind === "done" &&
172
+ !deps.stopRequested() &&
173
+ stopHooks < MAX_STOP_HOOK_CONTINUATIONS) {
174
+ const event = core.depth > 0 ? "SubagentStop" : "Stop";
175
+ const lastText = deps.lastAssistantText();
176
+ const payload = lastText === null
177
+ ? { stopHookActive: stopHooks > 0 }
178
+ : { lastAssistantText: lastText, stopHookActive: stopHooks > 0 };
179
+ const hook = await core.runHook(event, payload, signal);
180
+ if (hook !== undefined && hook.decision === "block" && !hook.stop && !signal.aborted) {
181
+ stopHooks++;
182
+ next = [makeUserMessage(hook.reason ?? "Continue.", undefined, "hook")];
183
+ continue;
184
+ }
185
+ }
186
+ }
187
+ if (!announced)
188
+ core.emit({ type: "agent_before_settle" });
189
+ const settled = { type: "agent_settled" };
190
+ if (warning !== undefined)
191
+ settled.warning = warning;
192
+ core.emit(settled);
193
+ void core.runHook("Notification", {
194
+ notification: { kind: "settled", message: warning ?? "run finished" },
195
+ });
196
+ }
197
+ export function makeUserMessage(text, images, origin) {
198
+ const message = {
199
+ role: "user",
200
+ content: images !== undefined && images.length > 0 ? [{ type: "text", text }, ...images] : text,
201
+ timestamp: Date.now(),
202
+ };
203
+ if (origin !== undefined)
204
+ message.origin = origin;
205
+ return message;
206
+ }
207
+ /**
208
+ * 一次提示:展开(expandPrompt)→ UserPromptSubmit Hook(block 拒绝;updatedPrompt 替换;
209
+ * additionalContext 作为 custom_message 随提示进上下文)→ 阈值压缩检查 → system 同步 →
210
+ * `before_agent_start`(宿主事件同名,由组装根桥接)→ 会话周期。
211
+ */
212
+ export async function runPrompt(deps, text, images, origin, signal) {
213
+ const { core } = deps;
214
+ let prompt = text;
215
+ if (core.options.expandPrompt !== undefined) {
216
+ const expanded = await core.options.expandPrompt(text);
217
+ if ("handled" in expanded)
218
+ return "handled";
219
+ prompt = expanded.text;
220
+ }
221
+ const hook = await core.runHook("UserPromptSubmit", { prompt }, signal);
222
+ if (hook !== undefined) {
223
+ if (hook.decision === "block" || hook.decision === "deny" || hook.stop) {
224
+ throw new AmaError("prompt_blocked", hook.reason ?? "prompt blocked by UserPromptSubmit hook");
225
+ }
226
+ if (hook.updatedPrompt !== undefined)
227
+ prompt = hook.updatedPrompt;
228
+ }
229
+ const prompts = [makeUserMessage(prompt, images, origin)];
230
+ if (hook?.additionalContext !== undefined && hook.additionalContext !== "") {
231
+ prompts.push({
232
+ role: "custom",
233
+ customType: "ama.hook_context",
234
+ content: hook.additionalContext,
235
+ display: false,
236
+ timestamp: Date.now(),
237
+ });
238
+ }
239
+ await deps.compaction.checkThreshold(signal);
240
+ if (signal.aborted)
241
+ return "handled";
242
+ deps.syncSystem();
243
+ core.emit({ type: "before_agent_start", prompt });
244
+ await runCycle(deps, prompts, signal);
245
+ return "started";
246
+ }