← Back to PRs

#17253: fix: propagate lastTurnTotal through usage accumulator for accurate session_status (#17016)

by robbyczgw-cla open 2026-02-15 15:35 View on GitHub →
agents size: XS experienced-contributor
## 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