Skip to content

v0.22.0

Choose a tag to compare

@sblattj sblattj released this 13 Oct 04:37
· 20 commits to main since this release

Added

  • Codex runs now show which model actually ran next to the one you asked for. codex exec --json never names the model, so after ach run --agent codex the harness reads the thread's own rollout file and records the observed model and reasoning effort from its turn_context lines. Usage records whose model was unknown get the observed model. The run verdict (usage.model) keeps requested and observed apart, flags a mismatch as a warning, and when no rollout is found it says the requested model is unverified instead of passing it off as observed. The run summary, ach dash, ach web and ach report show it. Codex transcript records (ach stats) now carry their model and effort, so --by model has real codex rows. A run's own cost is still computed from the stream, before the session file is read, so a codex run without -m shows cost n/a; its pricing warning now names the observed model instead of unknown model "unknown", and ach stats prices the session by that model. (#140)
  • Codex token counters now say what they include and whether anything is missing. Transcript reading supports the modern event_msg/token_count lines (with the latest call's tokens and the stated context window), still reads the legacy token_usage_record, and never counts the same usage twice when a file has both. A child session's file no longer takes its parent's id, and history it replays from its parent is not counted again. Child sessions are linked to their parents, and ach stats reports how many session trees are complete, child-inclusive, or missing children, whose usage stays unknown rather than zero. A codex run's verdict marks its stream totals parent-only when the run spawned child sessions, adds child-inclusive totals from the child rollouts it finds, and lists the missing ones. The run summary, ach dash, ach web and ach report show a partial/complete badge, and a run that has not reported usage yet shows n/a instead of zeros. (#142)

Fixed

  • Context meter: aggregate usage (codex turn.completed, gemini result.stats, a claude result with no per-message usage) is no longer shown as context occupancy. A synthetic codex turn that summed 3,000 tokens against a 1,000-token window reported 300%. Such a turn-total reading now has no percentage; it carries the count as cumulativeTokens and every surface shows occupancy as n/a beside a labelled cumulative count: the dash n/a (cum 3.0k), the HTML report ctx n/a · cumulative 3,000 tok, the run summary ctx n/a (cumulative 3,000 tok, not occupancy), the ach web feed Σ3.0k cum with no gauge bar and the run detail ctx n/a (cumulative 3,000 tok, not occupancy), and ach stats --json with contextPercentage/contextTokens null and a new cumulativeTokens field. Records written before this release that stored a turn-total percentage render the same way. Nothing is clamped to 100, and the overflow warning still fires only on a latest-call reading. totals.contextTokens is now set only for an occupancy reading (#141).
  • Context meter: native latest-call usage and a reported context window are now used when an agent provides them. A usage record's extra.lastTokenUsage ({ inputTokens, cacheReadTokens?, cacheWriteTokens? }) is read as a last-call occupancy reading, and extra.modelContextWindow sets the window with the new windowSource: 'reported' (estimated: false). Each latest-call reading replaces the previous one, so a smaller call after compaction lowers the reading (#141).
  • ach run --agent codex now gets a real context-occupancy reading when the thread's rollout has one. The driver feeds the rollout's latest call of this run (last_token_usage, uncached input plus cache read) and its stated window to the context meter before the run's final reading is sealed, so the summary, registry, report, ach stats --json and totals.contextTokens show a last-call percentage against a reported window instead of n/a (cumulative). A rollout without per-call usage stays cumulative, and compaction is handled because the newest call wins. Rollout records whose token_count line states no window take it from the turn's task_started event (contextWindowSource: 'task_started'). (#141, #142)

Fixes #140
Fixes #141
Fixes #142