#17253: fix: propagate lastTurnTotal through usage accumulator for accurate session_status (#17016)
agents
size: XS
experienced-contributor
Cluster:
Memory Management Enhancements
## Problem
After multi-turn tool-use runs (2+ API calls in one response), `session_status` always reports `totalTokens` equal to `contextTokens` (e.g. 200000/200000 = 100%). This happens because `toNormalizedUsage` calculates `total` from accumulated parts (`lastInput + lastCacheRead + lastCacheWrite + accumulated_output`), which inflates beyond `contextTokens` after multiple loops.
Fixes #17016
## Solution
Track `lastTurnTotal` in the usage accumulator — the total tokens from the most recent API call (not accumulated across turns). Use this value directly in `toNormalizedUsage` instead of reconstructing it from parts.
## Changes
- `src/agents/pi-embedded-runner/run.ts`:
- Added `lastTurnTotal` field to `UsageAccumulator` type
- `mergeUsageIntoAccumulator` captures per-call total (prefers `usage.total`, falls back to sum of fields)
- `toNormalizedUsage` returns `lastTurnTotal` instead of computing from accumulated parts
## Testing
All 36 pi-embedded-runner tests pass. The fix ensures `deriveSessionTotalTokens` (which already has correct "do NOT clamp" logic) receives accurate per-turn data.
## Local Validation
- `pnpm build` ✅
- `pnpm check` (oxlint) ✅
- Relevant test suites pass ✅
## Contribution Checklist
- [x] Focused scope — single fix per PR
- [x] Clear "what" + "why" in description
- [x] AI-assisted (Codex/Claude) — reviewed and tested by human
- [x] Local validation run (`pnpm build && pnpm check`)
*AI-assisted (Claude). Reviewed by human.
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
Fixed `session_status` reporting incorrect 100% context usage after multi-turn tool-use by tracking `lastTurnTotal` separately from accumulated totals. Previously, `toNormalizedUsage` reconstructed total from accumulated parts (`lastInput + lastCacheRead + lastCacheWrite + output`), which inflated beyond `contextTokens` across multiple API calls. Now `lastTurnTotal` captures per-call total directly and returns it unchanged, ensuring `deriveSessionTotalTokens` receives accurate single-turn data for context calculations.
- Added `lastTurnTotal` field to `UsageAccumulator` type and initialization
- Modified `mergeUsageIntoAccumulator` to capture per-turn total (prefers `usage.total`, falls back to sum)
- Updated `toNormalizedUsage` to return `lastTurnTotal` instead of computing from parts
- Removed obsolete `lastPromptTokens` calculation that was mixing accumulated and per-turn values
- Aligns with existing "do NOT clamp" logic in `deriveSessionTotalTokens` (src/agents/usage.ts:137-142)
<h3>Confidence Score: 5/5</h3>
- Safe to merge with minimal risk - focused fix with clear logic and comprehensive test coverage
- Simple, well-documented change that addresses a clear bug. The fix correctly separates accumulated vs. per-turn tracking, follows existing patterns (similar to `lastCacheRead`/`lastCacheWrite`/`lastInput`), and all 36 pi-embedded-runner tests pass. The solution is minimal and surgical - no refactoring or unnecessary changes.
- No files require special attention
<sub>Last reviewed commit: 28e2327</sub>
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#13841: fix: use last attempt prompt tokens for session total instead of ac...
by 1kuna · 2026-02-11
83.5%
#22387: fix: session_status context tracking undercount for cached providers
by 1ucian · 2026-02-21
82.5%
#22701: fix(reply): make usage footer reflect full turn usage and avoid tra...
by artwalker · 2026-02-21
80.6%
#13895: fix(usage): exclude cache tokens from context-window accounting
by zerone0x · 2026-02-11
79.0%
#8477: TUI: persist session token totals when usage metadata is missing
by LarHope · 2026-02-04
76.1%
#15126: fix(status): avoid false 100% context usage when totals mirror context
by AlexAnys · 2026-02-13
75.9%
#17109: fix: preserve responseUsage across session resets
by Limitless2023 · 2026-02-15
74.7%
#15173: fix(session): reset totalTokens after compaction when estimate unav...
by EnzoGaillardSystems · 2026-02-13
73.9%
#20603: fix(gateway): scan all agents in usage.cost RPC (#20558)
by lailoo · 2026-02-19
73.5%
#20650: fix(gateway): include deleted/reset sessions in usage.cost RPC (#20...
by lailoo · 2026-02-19
73.3%