Skip to content

Persist the context gauge per session and restore it on switch - #320

Merged
plombeer31 merged 1 commit into
mainfrom
feat/session-context-usage
Sep 3, 2026
Merged

Persist the context gauge per session and restore it on switch#320
plombeer31 merged 1 commit into
mainfrom
feat/session-context-usage

Conversation

@plombeer31

Copy link
Copy Markdown
Collaborator

Problem

The composer's context chip lives only in TUI memory, computed from the live turn's prompt_built event. Two consequences:

  • Relaunch the agent, reopen yesterday's session — the chip is blank until you run another turn, even though the window is already substantially full.
  • Switch between threads and the chip silently keeps the previous thread's numbers (session_switched never touched contextUsage), claiming the new thread is exactly as full as the one you just left.

Change

  • ContextUsageState + contextUsageFromPrompt move from the TUI into src/session/context-usage.ts; the old TUI import paths re-export, so panels/reducers/tests are untouched.
  • executeTurn stamps the turn's window occupancy onto SessionState.contextUsage right before the post-turn save. Every origin (TUI, scheduler, Telegram, HTTP) funnels through it, and the snapshot is the prompt_built estimate refined by the provider's real promptTokens when the completion reports one — the same reduction the chip itself does.
  • session_switched now carries the target session's stored snapshot; the reducer restores the gauge from it, and resets to empty when the session has none (fresh thread, or one written before this field existed).

Sessions serialize as whole-state JSON blobs, so the new optional field needs no migration; old rows just load without it.

Tests

  • store round-trip of the snapshot (+ absence on old rows)
  • runtime integration: turn runs → stored session carries the stamped usage with the tokenizer-refined count
  • reducer: restore-on-switch and reset-when-absent

The composer's context chip was computed only from the live turn's
prompt_built event, so it vanished on relaunch and — worse — switching
threads kept the previous thread's numbers on screen until the next
turn ran.

- Move the ContextUsageState shape + contextUsageFromPrompt projection
  from the TUI into src/session/context-usage.ts (TUI paths re-export)
  so the runtime can use them without a TUI dependency.
- executeTurn now stamps the turn's window occupancy (prompt_built
  estimate, refined by the provider's real promptTokens) onto
  SessionState before the post-turn save — every origin funnels
  through it.
- session_switched carries the stored snapshot; the reducer restores
  the chip from it and resets to empty when the target session has
  none, fixing the stale-gauge-on-switch bug.
@plombeer31
plombeer31 merged commit 28efd37 into main Sep 3, 2026
2 checks passed
praxstack pushed a commit to praxstack/AtomicBot-ai-atomic-agent that referenced this pull request Sep 4, 2026
Conflict resolutions against the context-usage work already on the rc
branch:

- runtime/bootstrap.ts: one save at the end of a turn now stamps both
  the turn's context usage (AtomicBot-ai#320) and the provider/model it ran on
  (AtomicBot-ai#321). Two PRs rewrote the same choke point; keeping either alone
  silently dropped the other's stamp.
- session/index.ts: both barrels re-exported.
- bootstrap.test.ts: the two near-identical turn-stamp tests folded into
  one that asserts both stamps, returned and reloaded.

Also fixes merge-caused breakage between AtomicBot-ai#309 and AtomicBot-ai#315: AtomicBot-ai#309 made
`OpenAiToolCallDelta.index` optional, so the contract probe's
accumulator no longer type-checks and would have keyed every
index-less call into slot 0. It now resolves call identity the way the
stream consumer does — index > id > the call currently open.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant