@pentoshi/clai 3.9.2 → 3.9.3

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 (331) hide show
  1. package/dist/agent/compaction-attempt.d.ts +22 -0
  2. package/dist/agent/compaction-attempt.js +69 -0
  3. package/dist/agent/compaction-attempt.js.map +1 -0
  4. package/dist/agent/compaction-summary.d.ts +27 -0
  5. package/dist/agent/compaction-summary.js +62 -0
  6. package/dist/agent/compaction-summary.js.map +1 -1
  7. package/dist/agent/context-breakdown.d.ts +2 -0
  8. package/dist/agent/context-breakdown.js +37 -0
  9. package/dist/agent/context-breakdown.js.map +1 -1
  10. package/dist/agent/context-manager.d.ts +7 -1
  11. package/dist/agent/context-manager.js +64 -15
  12. package/dist/agent/context-manager.js.map +1 -1
  13. package/dist/agent/continue-orient.d.ts +8 -0
  14. package/dist/agent/continue-orient.js +26 -3
  15. package/dist/agent/continue-orient.js.map +1 -1
  16. package/dist/agent/durable-envelope.d.ts +39 -0
  17. package/dist/agent/durable-envelope.js +195 -0
  18. package/dist/agent/durable-envelope.js.map +1 -0
  19. package/dist/agent/events.d.ts +21 -0
  20. package/dist/agent/loop-guard.d.ts +13 -5
  21. package/dist/agent/loop-guard.js +114 -1
  22. package/dist/agent/loop-guard.js.map +1 -1
  23. package/dist/agent/outcomes.d.ts +29 -0
  24. package/dist/agent/outcomes.js +118 -3
  25. package/dist/agent/outcomes.js.map +1 -1
  26. package/dist/agent/plan-decision.js +8 -3
  27. package/dist/agent/plan-decision.js.map +1 -1
  28. package/dist/agent/plan-tool.d.ts +5 -0
  29. package/dist/agent/plan-tool.js +166 -6
  30. package/dist/agent/plan-tool.js.map +1 -1
  31. package/dist/agent/reliability-policy.d.ts +11 -6
  32. package/dist/agent/reliability-policy.js +19 -13
  33. package/dist/agent/reliability-policy.js.map +1 -1
  34. package/dist/agent/request-budget.d.ts +24 -0
  35. package/dist/agent/request-budget.js +59 -0
  36. package/dist/agent/request-budget.js.map +1 -0
  37. package/dist/agent/responder-context.js +2 -2
  38. package/dist/agent/responder-context.js.map +1 -1
  39. package/dist/agent/responder-parent.d.ts +30 -0
  40. package/dist/agent/responder-parent.js +82 -0
  41. package/dist/agent/responder-parent.js.map +1 -0
  42. package/dist/agent/runner.d.ts +14 -1
  43. package/dist/agent/runner.js +759 -211
  44. package/dist/agent/runner.js.map +1 -1
  45. package/dist/agent/scope-context.d.ts +5 -0
  46. package/dist/agent/scope-context.js +7 -1
  47. package/dist/agent/scope-context.js.map +1 -1
  48. package/dist/agent/session-policy.js +1 -0
  49. package/dist/agent/session-policy.js.map +1 -1
  50. package/dist/agent/stop-summary.js +13 -7
  51. package/dist/agent/stop-summary.js.map +1 -1
  52. package/dist/agent/task-analyzer.js +7 -3
  53. package/dist/agent/task-analyzer.js.map +1 -1
  54. package/dist/agent/task-evidence.js +2 -0
  55. package/dist/agent/task-evidence.js.map +1 -1
  56. package/dist/agent/task-sync.d.ts +11 -0
  57. package/dist/agent/task-sync.js +31 -0
  58. package/dist/agent/task-sync.js.map +1 -1
  59. package/dist/agent/tool-call-parser.d.ts +6 -13
  60. package/dist/agent/tool-call-parser.js +186 -82
  61. package/dist/agent/tool-call-parser.js.map +1 -1
  62. package/dist/agent/tool-history.d.ts +8 -2
  63. package/dist/agent/tool-history.js +8 -1
  64. package/dist/agent/tool-history.js.map +1 -1
  65. package/dist/agent/turn-outcome.d.ts +4 -1
  66. package/dist/agent/turn-outcome.js +16 -2
  67. package/dist/agent/turn-outcome.js.map +1 -1
  68. package/dist/app/adapters/agent-event-adapter.js +27 -0
  69. package/dist/app/adapters/agent-event-adapter.js.map +1 -1
  70. package/dist/app/adapters/current-agent-adapter.js +1 -0
  71. package/dist/app/adapters/current-agent-adapter.js.map +1 -1
  72. package/dist/app/adapters/current-jobs-adapter.js +4 -3
  73. package/dist/app/adapters/current-jobs-adapter.js.map +1 -1
  74. package/dist/app/adapters/current-store-adapter.js +4 -3
  75. package/dist/app/adapters/current-store-adapter.js.map +1 -1
  76. package/dist/app/adapters/current-updates-adapter.d.ts +1 -1
  77. package/dist/app/adapters/current-updates-adapter.js +34 -5
  78. package/dist/app/adapters/current-updates-adapter.js.map +1 -1
  79. package/dist/app/adapters/quiet-meta-tools.js +2 -1
  80. package/dist/app/adapters/quiet-meta-tools.js.map +1 -1
  81. package/dist/app/controllers/job-controller.d.ts +4 -3
  82. package/dist/app/controllers/job-controller.js +9 -6
  83. package/dist/app/controllers/job-controller.js.map +1 -1
  84. package/dist/app/controllers/plan-controller.js +14 -0
  85. package/dist/app/controllers/plan-controller.js.map +1 -1
  86. package/dist/app/controllers/responder-settlement.js +2 -2
  87. package/dist/app/controllers/responder-settlement.js.map +1 -1
  88. package/dist/app/controllers/session-compact-helper.d.ts +23 -1
  89. package/dist/app/controllers/session-compact-helper.js +117 -7
  90. package/dist/app/controllers/session-compact-helper.js.map +1 -1
  91. package/dist/app/controllers/session-context-usage.d.ts +24 -0
  92. package/dist/app/controllers/session-context-usage.js +89 -0
  93. package/dist/app/controllers/session-context-usage.js.map +1 -0
  94. package/dist/app/controllers/session-controller.d.ts +17 -17
  95. package/dist/app/controllers/session-controller.js +122 -124
  96. package/dist/app/controllers/session-controller.js.map +1 -1
  97. package/dist/app/controllers/session-prompt-queue.d.ts +3 -0
  98. package/dist/app/controllers/session-prompt-queue.js +20 -1
  99. package/dist/app/controllers/session-prompt-queue.js.map +1 -1
  100. package/dist/app/controllers/session-responder.js +16 -6
  101. package/dist/app/controllers/session-responder.js.map +1 -1
  102. package/dist/app/controllers/session-turn-request.d.ts +18 -0
  103. package/dist/app/controllers/session-turn-request.js +31 -0
  104. package/dist/app/controllers/session-turn-request.js.map +1 -0
  105. package/dist/app/controllers/turn-continuation.d.ts +14 -0
  106. package/dist/app/controllers/turn-continuation.js +46 -0
  107. package/dist/app/controllers/turn-continuation.js.map +1 -0
  108. package/dist/app/events/app-event.d.ts +21 -0
  109. package/dist/app/events/app-event.js +1 -0
  110. package/dist/app/events/app-event.js.map +1 -1
  111. package/dist/app/ports/agent-port.d.ts +7 -0
  112. package/dist/app/ports/jobs-port.d.ts +4 -3
  113. package/dist/app/ports/persistence-port.d.ts +11 -0
  114. package/dist/app/ports/updates-port.d.ts +8 -0
  115. package/dist/attachments/service.js +13 -2
  116. package/dist/attachments/service.js.map +1 -1
  117. package/dist/commands/providers.js +13 -10
  118. package/dist/commands/providers.js.map +1 -1
  119. package/dist/commands/update.d.ts +4 -0
  120. package/dist/commands/update.js +14 -0
  121. package/dist/commands/update.js.map +1 -1
  122. package/dist/llm/adapters/anthropic-tools.d.ts +14 -1
  123. package/dist/llm/adapters/anthropic-tools.js +36 -5
  124. package/dist/llm/adapters/anthropic-tools.js.map +1 -1
  125. package/dist/llm/adapters/gemini-tools.d.ts +3 -1
  126. package/dist/llm/adapters/gemini-tools.js +5 -2
  127. package/dist/llm/adapters/gemini-tools.js.map +1 -1
  128. package/dist/llm/adapters/ollama-tools.js +8 -3
  129. package/dist/llm/adapters/ollama-tools.js.map +1 -1
  130. package/dist/llm/adapters/openai-tools.js +8 -1
  131. package/dist/llm/adapters/openai-tools.js.map +1 -1
  132. package/dist/llm/agentrouter.js +2 -0
  133. package/dist/llm/agentrouter.js.map +1 -1
  134. package/dist/llm/anthropic.d.ts +8 -0
  135. package/dist/llm/anthropic.js +68 -9
  136. package/dist/llm/anthropic.js.map +1 -1
  137. package/dist/llm/aws-mantle.js +60 -12
  138. package/dist/llm/aws-mantle.js.map +1 -1
  139. package/dist/llm/bynara.js +2 -0
  140. package/dist/llm/bynara.js.map +1 -1
  141. package/dist/llm/capabilities.d.ts +7 -0
  142. package/dist/llm/capabilities.js +22 -0
  143. package/dist/llm/capabilities.js.map +1 -1
  144. package/dist/llm/gemini.d.ts +3 -0
  145. package/dist/llm/gemini.js +71 -11
  146. package/dist/llm/gemini.js.map +1 -1
  147. package/dist/llm/groq.d.ts +20 -1
  148. package/dist/llm/groq.js +32 -4
  149. package/dist/llm/groq.js.map +1 -1
  150. package/dist/llm/http.d.ts +29 -0
  151. package/dist/llm/http.js +122 -29
  152. package/dist/llm/http.js.map +1 -1
  153. package/dist/llm/kimchi.js +2 -0
  154. package/dist/llm/kimchi.js.map +1 -1
  155. package/dist/llm/nvidia.js +2 -0
  156. package/dist/llm/nvidia.js.map +1 -1
  157. package/dist/llm/ollama.d.ts +5 -0
  158. package/dist/llm/ollama.js +53 -6
  159. package/dist/llm/ollama.js.map +1 -1
  160. package/dist/llm/openai.js +2 -0
  161. package/dist/llm/openai.js.map +1 -1
  162. package/dist/llm/openrouter.js +2 -0
  163. package/dist/llm/openrouter.js.map +1 -1
  164. package/dist/llm/qwen-cloud.js +2 -0
  165. package/dist/llm/qwen-cloud.js.map +1 -1
  166. package/dist/llm/router.d.ts +16 -0
  167. package/dist/llm/router.js +79 -23
  168. package/dist/llm/router.js.map +1 -1
  169. package/dist/llm/sampling.d.ts +32 -0
  170. package/dist/llm/sampling.js +48 -0
  171. package/dist/llm/sampling.js.map +1 -0
  172. package/dist/llm/stream-progress.d.ts +4 -0
  173. package/dist/llm/stream-progress.js +43 -0
  174. package/dist/llm/stream-progress.js.map +1 -0
  175. package/dist/llm/system-messages.d.ts +29 -0
  176. package/dist/llm/system-messages.js +51 -0
  177. package/dist/llm/system-messages.js.map +1 -0
  178. package/dist/llm/token-usage.d.ts +4 -1
  179. package/dist/llm/token-usage.js +56 -4
  180. package/dist/llm/token-usage.js.map +1 -1
  181. package/dist/llm/tool-protocol.js +30 -0
  182. package/dist/llm/tool-protocol.js.map +1 -1
  183. package/dist/os/process-tree.d.ts +15 -0
  184. package/dist/os/process-tree.js +77 -0
  185. package/dist/os/process-tree.js.map +1 -0
  186. package/dist/prompts/embedded.js +1 -1
  187. package/dist/prompts/embedded.js.map +1 -1
  188. package/dist/prompts/system.agent.md +13 -12
  189. package/dist/repl/prompt-line.d.ts +5 -0
  190. package/dist/repl/prompt-line.js +7 -1
  191. package/dist/repl/prompt-line.js.map +1 -1
  192. package/dist/repl.js +61 -41
  193. package/dist/repl.js.map +1 -1
  194. package/dist/safety/classifier.js +98 -44
  195. package/dist/safety/classifier.js.map +1 -1
  196. package/dist/safety/engagement-policy.d.ts +8 -0
  197. package/dist/safety/engagement-policy.js +52 -7
  198. package/dist/safety/engagement-policy.js.map +1 -1
  199. package/dist/safety/patterns.d.ts +44 -0
  200. package/dist/safety/patterns.js +168 -37
  201. package/dist/safety/patterns.js.map +1 -1
  202. package/dist/store/config.d.ts +9 -1
  203. package/dist/store/config.js +51 -1
  204. package/dist/store/config.js.map +1 -1
  205. package/dist/store/history-index.d.ts +12 -0
  206. package/dist/store/history-index.js +47 -18
  207. package/dist/store/history-index.js.map +1 -1
  208. package/dist/store/history.d.ts +5 -2
  209. package/dist/store/history.js +153 -62
  210. package/dist/store/history.js.map +1 -1
  211. package/dist/store/plan.d.ts +81 -5
  212. package/dist/store/plan.js +406 -46
  213. package/dist/store/plan.js.map +1 -1
  214. package/dist/store/redaction-cache.d.ts +12 -0
  215. package/dist/store/redaction-cache.js +51 -0
  216. package/dist/store/redaction-cache.js.map +1 -0
  217. package/dist/store/responder-settlement.d.ts +5 -1
  218. package/dist/store/responder-settlement.js +42 -30
  219. package/dist/store/responder-settlement.js.map +1 -1
  220. package/dist/store/scope.js +36 -27
  221. package/dist/store/scope.js.map +1 -1
  222. package/dist/store/task-transitions.d.ts +19 -0
  223. package/dist/store/task-transitions.js +46 -0
  224. package/dist/store/task-transitions.js.map +1 -0
  225. package/dist/tools/capabilities.js +33 -18
  226. package/dist/tools/capabilities.js.map +1 -1
  227. package/dist/tools/command-intent.d.ts +24 -0
  228. package/dist/tools/command-intent.js +158 -4
  229. package/dist/tools/command-intent.js.map +1 -1
  230. package/dist/tools/definitions.d.ts +5 -1
  231. package/dist/tools/definitions.js +162 -21
  232. package/dist/tools/definitions.js.map +1 -1
  233. package/dist/tools/fs.d.ts +16 -0
  234. package/dist/tools/fs.js +122 -46
  235. package/dist/tools/fs.js.map +1 -1
  236. package/dist/tools/image.js +1 -1
  237. package/dist/tools/image.js.map +1 -1
  238. package/dist/tools/jobs.d.ts +78 -4
  239. package/dist/tools/jobs.js +542 -115
  240. package/dist/tools/jobs.js.map +1 -1
  241. package/dist/tools/net-ping-sweep.d.ts +3 -1
  242. package/dist/tools/net-ping-sweep.js +64 -26
  243. package/dist/tools/net-ping-sweep.js.map +1 -1
  244. package/dist/tools/nmap-runner.js +5 -2
  245. package/dist/tools/nmap-runner.js.map +1 -1
  246. package/dist/tools/pdf.js +50 -7
  247. package/dist/tools/pdf.js.map +1 -1
  248. package/dist/tools/registry.js +154 -96
  249. package/dist/tools/registry.js.map +1 -1
  250. package/dist/tools/shell.d.ts +24 -2
  251. package/dist/tools/shell.js +113 -28
  252. package/dist/tools/shell.js.map +1 -1
  253. package/dist/tools/tool-types.d.ts +2 -0
  254. package/dist/tools/validate.d.ts +8 -5
  255. package/dist/tools/validate.js +177 -7
  256. package/dist/tools/validate.js.map +1 -1
  257. package/dist/tools/wordlists.js +69 -17
  258. package/dist/tools/wordlists.js.map +1 -1
  259. package/dist/tui/state.d.ts +4 -0
  260. package/dist/tui/state.js +88 -2
  261. package/dist/tui/state.js.map +1 -1
  262. package/dist/tui-v2/actions/keymap.js +3 -8
  263. package/dist/tui-v2/actions/keymap.js.map +1 -1
  264. package/dist/tui-v2/app/App.js +52 -4
  265. package/dist/tui-v2/app/App.js.map +1 -1
  266. package/dist/tui-v2/app/commands/config-commands.js +5 -2
  267. package/dist/tui-v2/app/commands/config-commands.js.map +1 -1
  268. package/dist/tui-v2/app/commands/picker-commands.js +3 -0
  269. package/dist/tui-v2/app/commands/picker-commands.js.map +1 -1
  270. package/dist/tui-v2/app/plan-lifecycle.d.ts +1 -1
  271. package/dist/tui-v2/app/plan-lifecycle.js +2 -1
  272. package/dist/tui-v2/app/plan-lifecycle.js.map +1 -1
  273. package/dist/tui-v2/components/composer/composer-input-box.d.ts +1 -1
  274. package/dist/tui-v2/components/composer/composer-input-box.js +12 -3
  275. package/dist/tui-v2/components/composer/composer-input-box.js.map +1 -1
  276. package/dist/tui-v2/components/jobs/jobs-panel.js +19 -6
  277. package/dist/tui-v2/components/jobs/jobs-panel.js.map +1 -1
  278. package/dist/tui-v2/components/plan/plan-view.js +9 -6
  279. package/dist/tui-v2/components/plan/plan-view.js.map +1 -1
  280. package/dist/tui-v2/components/status/status-line.d.ts +15 -0
  281. package/dist/tui-v2/components/status/status-line.js +33 -25
  282. package/dist/tui-v2/components/status/status-line.js.map +1 -1
  283. package/dist/tui-v2/components/transcript/assistant-message.js +17 -9
  284. package/dist/tui-v2/components/transcript/assistant-message.js.map +1 -1
  285. package/dist/tui-v2/components/transcript/compacted-row.js +49 -22
  286. package/dist/tui-v2/components/transcript/compacted-row.js.map +1 -1
  287. package/dist/tui-v2/components/transcript/intro-card.js +3 -0
  288. package/dist/tui-v2/components/transcript/intro-card.js.map +1 -1
  289. package/dist/tui-v2/components/transcript/thinking-block.js +2 -1
  290. package/dist/tui-v2/components/transcript/thinking-block.js.map +1 -1
  291. package/dist/tui-v2/components/transcript/transcript-view.js +27 -2
  292. package/dist/tui-v2/components/transcript/transcript-view.js.map +1 -1
  293. package/dist/tui-v2/components/transcript/use-transcript-selection.js +57 -6
  294. package/dist/tui-v2/components/transcript/use-transcript-selection.js.map +1 -1
  295. package/dist/tui-v2/composer/composer-editor.js +12 -6
  296. package/dist/tui-v2/composer/composer-editor.js.map +1 -1
  297. package/dist/tui-v2/rendering/incremental-strip.d.ts +11 -0
  298. package/dist/tui-v2/rendering/incremental-strip.js +89 -0
  299. package/dist/tui-v2/rendering/incremental-strip.js.map +1 -0
  300. package/dist/tui-v2/rendering/plan-view.d.ts +12 -0
  301. package/dist/tui-v2/rendering/plan-view.js +71 -2
  302. package/dist/tui-v2/rendering/plan-view.js.map +1 -1
  303. package/dist/tui-v2/rendering/streaming-markdown.d.ts +25 -0
  304. package/dist/tui-v2/rendering/streaming-markdown.js +108 -0
  305. package/dist/tui-v2/rendering/streaming-markdown.js.map +1 -0
  306. package/dist/tui-v2/rendering/thinking-tail.d.ts +5 -0
  307. package/dist/tui-v2/rendering/thinking-tail.js +26 -0
  308. package/dist/tui-v2/rendering/thinking-tail.js.map +1 -0
  309. package/dist/tui-v2/state/transcript-hydrate.js +6 -2
  310. package/dist/tui-v2/state/transcript-hydrate.js.map +1 -1
  311. package/dist/tui-v2/state/transcript-reducer.js +146 -25
  312. package/dist/tui-v2/state/transcript-reducer.js.map +1 -1
  313. package/dist/tui-v2/state/transcript-types.d.ts +6 -0
  314. package/dist/tui-v2/state/transcript-types.js +17 -0
  315. package/dist/tui-v2/state/transcript-types.js.map +1 -1
  316. package/dist/types.d.ts +29 -0
  317. package/dist/types.js.map +1 -1
  318. package/dist/ui/intro-header.d.ts +1 -0
  319. package/dist/ui/intro-header.js +10 -13
  320. package/dist/ui/intro-header.js.map +1 -1
  321. package/dist/ui/markdown.js +9 -2
  322. package/dist/ui/markdown.js.map +1 -1
  323. package/dist/ui/mentions.d.ts +5 -0
  324. package/dist/ui/mentions.js +66 -7
  325. package/dist/ui/mentions.js.map +1 -1
  326. package/dist/ui/thinking.d.ts +5 -1
  327. package/dist/ui/thinking.js +3 -2
  328. package/dist/ui/thinking.js.map +1 -1
  329. package/dist/version.generated.d.ts +2 -2
  330. package/dist/version.generated.js +2 -2
  331. package/package.json +2 -1
@@ -1,14 +1,16 @@
1
1
  /**
2
2
  * Summarizer callback used by SessionController.compact (keeps the controller slim).
3
3
  */
4
- import { completeWithProvider } from "../../llm/router.js";
4
+ import { compactMessagesWithSummary, estimateMessagesTokens, isCompactionMemoryMessage, } from "../../agent/context-manager.js";
5
+ import { completeWithProvider, streamWithProvider } from "../../llm/router.js";
6
+ import { createThinkingStreamParser, stripThinking, } from "../../ui/thinking.js";
5
7
  export async function summarizeForSessionCompact(prompt, opts) {
6
8
  const maxTokens = 2_048;
7
9
  const systemContent = opts.purpose === "plan-implement"
8
10
  ? "Write concise, non-redundant research memory for an agent executing an approved plan. Do not add framing: the PLAN MODE HANDOFF wrapper and active plan are injected separately. For coding target 600–1000 tokens; preserve only verified state, reusable research/artifacts, decisions, blockers, and risks. Security handoffs may be longer to preserve findings and coverage. Never invent or cut a fact mid-token. You are summarizing, not continuing: never emit tool calls or fabricate tool results, file receipts, or transcript lines."
9
11
  : "You compress conversation history into accurate continuation memory. You are SUMMARIZING the past session, not continuing it: do not answer the user, do not perform the next task, and never emit tool calls or fabricate tool results, file-write receipts (bytes/lines/sha256), exit codes, or 'TOOL:'/'[tools: …]' transcript lines. Describe what already happened in your own words.";
10
- const completeSummary = async (p) => {
11
- const response = await completeWithProvider({
12
+ const completeSummary = async (p, onToken) => {
13
+ const request = {
12
14
  provider: opts.provider,
13
15
  model: opts.model,
14
16
  messages: [
@@ -21,12 +23,44 @@ export async function summarizeForSessionCompact(prompt, opts) {
21
23
  temperature: 0.1,
22
24
  maxTokens,
23
25
  signal: opts.signal,
26
+ };
27
+ let rawSummary;
28
+ if (!onToken) {
29
+ rawSummary = (await completeWithProvider(request)).text;
30
+ }
31
+ else {
32
+ const parser = createThinkingStreamParser(onToken, undefined, {
33
+ remember: false,
34
+ });
35
+ const response = await streamWithProvider(request, (token) => parser.push(token), { onStatus: () => undefined });
36
+ parser.finish();
37
+ rawSummary = response.text;
38
+ }
39
+ const parsed = stripThinking(rawSummary);
40
+ if (parsed.visible.trim() || !parsed.hasThinking)
41
+ return rawSummary;
42
+ const retry = await completeWithProvider({
43
+ ...request,
44
+ messages: [
45
+ {
46
+ role: "system",
47
+ content: `${systemContent}\nReturn only the continuation-memory summary. Do not include analysis, reasoning, or <think> tags.`,
48
+ },
49
+ { role: "user", content: p },
50
+ ],
51
+ temperature: 0,
52
+ maxTokens: 8_192,
53
+ thinking: { enabled: false, effort: "none" },
24
54
  });
25
- return response.text;
55
+ const retryVisible = stripThinking(retry.text).visible.trim();
56
+ if (retryVisible && onToken)
57
+ onToken(retryVisible);
58
+ return retry.text;
26
59
  };
27
60
  const chunkSize = 50_000;
28
- if (prompt.length <= chunkSize)
29
- return completeSummary(prompt);
61
+ if (prompt.length <= chunkSize) {
62
+ return completeSummary(prompt, opts.onToken);
63
+ }
30
64
  const chunks = Array.from({ length: Math.ceil(prompt.length / chunkSize) }, (_, index) => prompt.slice(index * chunkSize, (index + 1) * chunkSize));
31
65
  const partials = [];
32
66
  for (let index = 0; index < chunks.length; index += 1) {
@@ -40,6 +74,82 @@ export async function summarizeForSessionCompact(prompt, opts) {
40
74
  ? "Merge these ordered partial plan-mode research memories into one non-redundant implement handoff. Use sections: User goals, Research evidence, Coverage ledger, Confirmed findings, Negative/tested-OK, Untested/open, Artifacts, Durable rules, Plan-mode-only notes, Commands/tools, Current state, Remaining work, Open risks. Complete every fact; never cut mid-token.\n\n" +
41
75
  partials.map((part, index) => `PART ${index + 1}:\n${part}`).join("\n\n")
42
76
  : "Merge these ordered partial session memories into one non-redundant continuation memory. Preserve all concrete facts and unresolved work. Use sections: User goals, Decisions and constraints, Work completed, Commands/tools and results, Current state, Remaining work.\n\n" +
43
- partials.map((part, index) => `PART ${index + 1}:\n${part}`).join("\n\n"));
77
+ partials.map((part, index) => `PART ${index + 1}:\n${part}`).join("\n\n"), opts.onToken);
78
+ }
79
+ export async function runSessionCompaction(options) {
80
+ const emit = (type, payload) => {
81
+ options.emit(options.sequencer.build(type, payload, undefined));
82
+ };
83
+ const beforeTokens = estimateMessagesTokens(options.history);
84
+ if (options.persist) {
85
+ emit("compaction-started", {
86
+ compactionId: options.compactionId,
87
+ beforeTokens,
88
+ });
89
+ }
90
+ let settled = false;
91
+ try {
92
+ const result = await compactMessagesWithSummary(options.history, (prompt, stage) => summarizeForSessionCompact(prompt, {
93
+ provider: options.provider,
94
+ model: options.model,
95
+ signal: options.signal,
96
+ purpose: options.purpose,
97
+ ...(options.persist && stage?.phase !== "map"
98
+ ? {
99
+ onToken: (text) => {
100
+ if (options.isCurrent()) {
101
+ emit("compaction-delta", {
102
+ compactionId: options.compactionId,
103
+ text,
104
+ });
105
+ }
106
+ },
107
+ }
108
+ : {}),
109
+ }), {
110
+ budgetTokens: 0,
111
+ keepRecent: options.keepRecent,
112
+ purpose: options.purpose,
113
+ }, options.sessionTranscript);
114
+ if (!options.isCurrent())
115
+ return result;
116
+ options.commit(result);
117
+ if (options.persist && result.summarized) {
118
+ const summary = [...result.messages]
119
+ .reverse()
120
+ .find((message) => isCompactionMemoryMessage(message))?.content ??
121
+ "Compacted context";
122
+ emit("compaction-completed", {
123
+ compactionId: options.compactionId,
124
+ summary,
125
+ beforeTokens: result.beforeTokens,
126
+ afterTokens: result.afterTokens,
127
+ });
128
+ }
129
+ else if (options.persist) {
130
+ emit("compaction-failed", {
131
+ compactionId: options.compactionId,
132
+ message: "There was no closed history to compact.",
133
+ retainedTokens: beforeTokens,
134
+ });
135
+ }
136
+ if (options.persist)
137
+ settled = true;
138
+ if (options.persist && result.summarized && result.after !== result.before) {
139
+ await options.persistNow();
140
+ }
141
+ return result;
142
+ }
143
+ catch (error) {
144
+ if (options.persist && !settled && options.isCurrent()) {
145
+ const message = error instanceof Error ? error.message : String(error);
146
+ emit("compaction-failed", {
147
+ compactionId: options.compactionId,
148
+ message: /aborted/i.test(message) ? "Compaction was cancelled." : message,
149
+ retainedTokens: beforeTokens,
150
+ });
151
+ }
152
+ throw error;
153
+ }
44
154
  }
45
155
  //# sourceMappingURL=session-compact-helper.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"session-compact-helper.js","sourceRoot":"","sources":["../../../src/app/controllers/session-compact-helper.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAE3D,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC9C,MAAc,EACd,IAMC;IAED,MAAM,SAAS,GAAG,KAAK,CAAC;IACxB,MAAM,aAAa,GACjB,IAAI,CAAC,OAAO,KAAK,gBAAgB;QAC/B,CAAC,CAAC,mhBAAmhB;QACrhB,CAAC,CAAC,4XAA4X,CAAC;IAEnY,MAAM,eAAe,GAAG,KAAK,EAAE,CAAS,EAAmB,EAAE;QAC3D,MAAM,QAAQ,GAAG,MAAM,oBAAoB,CAAC;YAC1C,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,QAAQ,EAAE;gBACR;oBACE,IAAI,EAAE,QAAQ;oBACd,OAAO,EAAE,aAAa;iBACvB;gBACD,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE;aAC7B;YACD,WAAW,EAAE,GAAG;YAChB,SAAS;YACT,MAAM,EAAE,IAAI,CAAC,MAAM;SACpB,CAAC,CAAC;QACH,OAAO,QAAQ,CAAC,IAAI,CAAC;IACvB,CAAC,CAAC;IAEF,MAAM,SAAS,GAAG,MAAM,CAAC;IACzB,IAAI,MAAM,CAAC,MAAM,IAAI,SAAS;QAAE,OAAO,eAAe,CAAC,MAAM,CAAC,CAAC;IAC/D,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CACvB,EAAE,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,EAChD,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,GAAG,SAAS,EAAE,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,SAAS,CAAC,CACvE,CAAC;IACF,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QACtD,IAAI,CAAC,MAAM,EAAE,cAAc,EAAE,CAAC;QAC9B,QAAQ,CAAC,IAAI,CACX,MAAM,eAAe,CACnB,IAAI,CAAC,OAAO,KAAK,gBAAgB;YAC/B,CAAC,CAAC,kBAAkB,KAAK,GAAG,CAAC,OAAO,MAAM,CAAC,MAAM,8KAA8K,MAAM,CAAC,KAAK,CAAC,EAAE;YAC9O,CAAC,CAAC,kBAAkB,KAAK,GAAG,CAAC,OAAO,MAAM,CAAC,MAAM,sHAAsH,MAAM,CAAC,KAAK,CAAC,EAAE,CACzL,CACF,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,MAAM,EAAE,cAAc,EAAE,CAAC;IAC9B,OAAO,eAAe,CACpB,IAAI,CAAC,OAAO,KAAK,gBAAgB;QAC/B,CAAC,CAAC,iXAAiX;YAC/W,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,QAAQ,KAAK,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;QAC7E,CAAC,CAAC,+QAA+Q;YAC7Q,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,QAAQ,KAAK,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAChF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"session-compact-helper.js","sourceRoot":"","sources":["../../../src/app/controllers/session-compact-helper.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import { type ContextUsageSnapshot } from "../../llm/token-usage.js";
2
+ import type { ChatMessage, ProviderId, TokenUsage } from "../../types.js";
3
+ export interface ContextUsageTarget {
4
+ readonly provider?: ProviderId | undefined;
5
+ readonly model?: string | undefined;
6
+ }
7
+ export declare function contextUsageLimit(target: ContextUsageTarget): number;
8
+ export declare function resolveContextUsageSnapshot(target: ContextUsageTarget, history: readonly ChatMessage[], current: ContextUsageSnapshot | undefined): ContextUsageSnapshot | undefined;
9
+ export declare function recordUsageSnapshot(target: ContextUsageTarget, current: ContextUsageSnapshot | undefined, usage: TokenUsage): ContextUsageSnapshot;
10
+ export declare function compactedUsageSnapshot(target: ContextUsageTarget, current: ContextUsageSnapshot | undefined, history: readonly ChatMessage[], afterTokens?: number): ContextUsageSnapshot;
11
+ export interface ContextProjection {
12
+ contextUsage: ContextUsageSnapshot | undefined;
13
+ contextChip: string | undefined;
14
+ }
15
+ export declare function createContextProjector(formatChip: (snapshot: ContextUsageSnapshot) => string): (target: ContextUsageTarget, history: readonly ChatMessage[], current: ContextUsageSnapshot | undefined) => ContextProjection;
16
+ export interface PartialUsageSnapshot {
17
+ contextTokens: number;
18
+ contextLimit?: number | undefined;
19
+ lastCompletionTokens?: number | undefined;
20
+ sessionPromptTokens?: number | undefined;
21
+ sessionCompletionTokens?: number | undefined;
22
+ exact: boolean;
23
+ }
24
+ export declare function restoredUsageSnapshot(target: ContextUsageTarget, usage: PartialUsageSnapshot | ContextUsageSnapshot | undefined): ContextUsageSnapshot | undefined;
@@ -0,0 +1,89 @@
1
+ // Context-usage projection for the session footer.
2
+ //
3
+ // The denominator shown to the user is the request budget that governs the next
4
+ // request (auto-compaction trigger), not the raw model window, so the footer
5
+ // agrees with the moment compaction actually fires.
6
+ import { requestBudgetDenominator } from "../../agent/request-budget.js";
7
+ import { estimateMessagesTokens } from "../../agent/context-manager.js";
8
+ import { applyUsageToSnapshot, snapshotFromEstimate, } from "../../llm/token-usage.js";
9
+ // Effective request budget used as the footer denominator.
10
+ export function contextUsageLimit(target) {
11
+ return requestBudgetDenominator(target.provider, target.model);
12
+ }
13
+ // Prefer the last API `prompt_tokens` as context fill (exact); otherwise
14
+ // estimate from current history so the footer always has a number.
15
+ export function resolveContextUsageSnapshot(target, history, current) {
16
+ const contextLimit = contextUsageLimit(target);
17
+ if (current?.exact && current.contextTokens > 0) {
18
+ return { ...current, contextLimit };
19
+ }
20
+ if (history.length === 0 && !current)
21
+ return undefined;
22
+ const estimated = snapshotFromEstimate(history, target.model, target.provider, current);
23
+ return { ...estimated, contextLimit };
24
+ }
25
+ // Fold provider-reported usage into the snapshot against the request budget.
26
+ export function recordUsageSnapshot(target, current, usage) {
27
+ return applyUsageToSnapshot(current, usage, contextUsageLimit(target));
28
+ }
29
+ // After /compact or auto-compact the exact prompt_tokens are stale: report the
30
+ // post-compaction size until the next API usage report.
31
+ export function compactedUsageSnapshot(target, current, history, afterTokens) {
32
+ const estimated = typeof afterTokens === "number" && afterTokens > 0
33
+ ? afterTokens
34
+ : estimateMessagesTokens(history);
35
+ return {
36
+ contextTokens: estimated,
37
+ contextLimit: contextUsageLimit(target),
38
+ lastCompletionTokens: 0,
39
+ sessionPromptTokens: current?.sessionPromptTokens ?? 0,
40
+ sessionCompletionTokens: current?.sessionCompletionTokens ?? 0,
41
+ exact: false,
42
+ };
43
+ }
44
+ // The estimate walks the whole transcript, so the projection is memoized
45
+ // against the inputs that can change it instead of recomputed per render.
46
+ export function createContextProjector(formatChip) {
47
+ let cache;
48
+ return (target, history, current) => {
49
+ const first = history[0];
50
+ const last = history[history.length - 1];
51
+ const key = [
52
+ target.provider ?? "",
53
+ target.model ?? "",
54
+ history.length,
55
+ first?.content.length ?? 0,
56
+ last?.content.length ?? 0,
57
+ current?.contextTokens ?? -1,
58
+ current?.contextLimit ?? -1,
59
+ current?.lastCompletionTokens ?? -1,
60
+ current?.exact ? 1 : 0,
61
+ ].join("|");
62
+ if (cache?.key === key)
63
+ return cache.value;
64
+ const contextUsage = resolveContextUsageSnapshot(target, history, current);
65
+ const value = {
66
+ contextUsage,
67
+ contextChip: contextUsage ? formatChip(contextUsage) : undefined,
68
+ };
69
+ cache = { key, value };
70
+ return value;
71
+ };
72
+ }
73
+ // Prefer the exact snapshot saved during the live turn; older sessions without
74
+ // a usage payload fall back to an estimate at the call site.
75
+ export function restoredUsageSnapshot(target, usage) {
76
+ if (!usage || usage.contextTokens <= 0)
77
+ return undefined;
78
+ return {
79
+ contextTokens: usage.contextTokens,
80
+ contextLimit: typeof usage.contextLimit === "number" && usage.contextLimit > 0
81
+ ? usage.contextLimit
82
+ : contextUsageLimit(target),
83
+ lastCompletionTokens: usage.lastCompletionTokens ?? 0,
84
+ sessionPromptTokens: usage.sessionPromptTokens ?? 0,
85
+ sessionCompletionTokens: usage.sessionCompletionTokens ?? 0,
86
+ exact: usage.exact === true,
87
+ };
88
+ }
89
+ //# sourceMappingURL=session-context-usage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-context-usage.js","sourceRoot":"","sources":["../../../src/app/controllers/session-context-usage.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,8 @@
1
1
  import type { ChatMessage, Mode, ProviderId, TokenUsage, ToolResult } from "../../types.js";
2
2
  import { type CompactResult } from "../../agent/context-manager.js";
3
3
  import { type ContextUsageSnapshot } from "../../llm/token-usage.js";
4
+ import { type PartialUsageSnapshot } from "./session-context-usage.js";
5
+ import type { PreviousTurnSignal } from "../../agent/continue-orient.js";
4
6
  import { type SessionWorkspace } from "../../store/session-workspace.js";
5
7
  import type { TranscriptItem as ClassicTranscriptItem } from "../../tui/state.js";
6
8
  import { type AnyAppEvent, type SessionId, type TurnId } from "../events/app-event.js";
@@ -82,23 +84,23 @@ export declare class SessionController implements Disposable {
82
84
  private static readonly AUTOSAVE_MIN_MS;
83
85
  /** Last known context / session token totals for the status strip. */
84
86
  private contextUsage;
87
+ /** Bumped by reset/history load/dispose so late callbacks can be ignored. */
88
+ private lifecycleGeneration;
89
+ private lastTurnResult;
90
+ private restoredPreviousTurn;
91
+ private activeTurnGeneration;
92
+ private readonly projectContext;
85
93
  constructor(deps: SessionControllerDeps);
86
94
  /** Current per-session scratch/output workspace (always bound while live). */
87
95
  get workspace(): SessionWorkspace | undefined;
88
96
  get sessionId(): SessionId;
89
97
  getState(): SessionState;
90
- /**
91
- * Prefer last API prompt_tokens as context fill (exact); otherwise estimate
92
- * from current history so the footer always has a number.
93
- */
98
+ private contextUsageProjection;
99
+ private get usageTarget();
94
100
  private resolveContextUsage;
95
101
  /** Record provider-reported usage (from agent token-usage events). */
96
102
  recordTokenUsage(usage: TokenUsage, model?: string): void;
97
- /**
98
- * After /compact or auto-compact: history was replaced with a short memory
99
- * + recent turns. Drop stale exact prompt_tokens so the footer shows the
100
- * live context size until the next API usage report.
101
- */
103
+ /** After /compact or auto-compact, report the post-compaction context size. */
102
104
  noteContextCompacted(afterTokens?: number): void;
103
105
  /** After history loads, estimate fill until the next API usage report. */
104
106
  private refreshEstimatedContext;
@@ -119,16 +121,11 @@ export declare class SessionController implements Disposable {
119
121
  * Restored from history so the footer matches the live session count.
120
122
  * Accepts partial snapshots (contextLimit optional).
121
123
  */
122
- contextUsage?: ContextUsageSnapshot | {
123
- contextTokens: number;
124
- contextLimit?: number | undefined;
125
- lastCompletionTokens?: number | undefined;
126
- sessionPromptTokens?: number | undefined;
127
- sessionCompletionTokens?: number | undefined;
128
- exact: boolean;
129
- } | undefined;
124
+ contextUsage?: ContextUsageSnapshot | PartialUsageSnapshot | undefined;
130
125
  /** Loaded durable revision; resume advances to a fresh writer generation. */
131
126
  persistenceRevision?: number | undefined;
127
+ /** Last turn outcome or interrupted in-flight checkpoint from history. */
128
+ previousTurn?: PreviousTurnSignal | undefined;
132
129
  /** Per-session scratch/output folder (restored with history). */
133
130
  workspaceFolder?: string | undefined;
134
131
  workspaceCode?: string | undefined;
@@ -153,6 +150,7 @@ export declare class SessionController implements Disposable {
153
150
  persist?: boolean | undefined;
154
151
  }): Promise<CompactResult>;
155
152
  private settlePersistedResponderResults;
153
+ private continuationCheckpoint;
156
154
  persistNow(name?: string): Promise<void>;
157
155
  maybeRefreshTitle(): Promise<void>;
158
156
  estimateContext(): {
@@ -182,6 +180,8 @@ export declare class SessionController implements Disposable {
182
180
  * long agent run still lands tools/messages on disk before abort/crash.
183
181
  */
184
182
  private scheduleAutosave;
183
+ /** Fence the previous lifecycle: running turn, compaction and title. */
184
+ private beginLifecycleGeneration;
185
185
  dispose(): void;
186
186
  private notifyState;
187
187
  }