← Back to PRs

#11999: fix: add session-growth guard to prevent unbounded session store growth

by reverendrewind open 2026-02-08 17:49 View on GitHub →
agents stale
## Summary Fixes #11971. - Context pruning (cache-ttl) and DM history limiting modify messages in-flight before the API call but never touch the session store. This masks the true session size from the pi-coding-agent library's auto-compaction trigger, causing the JSONL store to grow unbounded. - Non-Anthropic providers sharing the same session then receive the full unpruned history (854K+ tokens observed in production, costing $0.66 in wasted API calls). - Adds a **provider-agnostic pre-prompt guard** in `runEmbeddedPiAgent` that estimates actual stored tokens via `SessionManager.open()` and forces compaction when the store exceeds 80% of the context window. ### Changes | File | Change | |------|--------| | `src/agents/pi-embedded-runner/compact.ts` | Add `estimateSessionFileTokens()` helper | | `src/agents/pi-embedded-runner/run.ts` | Add `SESSION_GROWTH_COMPACTION_THRESHOLD` and pre-prompt guard with try/catch | | `src/agents/pi-embedded-runner/run.session-growth-guard.test.ts` | 6 new tests | ### Design decisions - **Provider-agnostic**: fires regardless of current provider, catching both cache-ttl pruning (Anthropic) and `limitHistoryTurns` (DM sessions) - **Best-effort**: errors in session estimation are caught and logged, never block the prompt - **Runs once** before the retry loop (existing overflow handling covers subsequent growth) - **Threshold at 80%**: above pruning ratios (30-50%) to avoid interference, but catches clearly bloated sessions ## Test plan - [x] 6 new tests pass (threshold logic, compaction success/failure, error resilience, no-session-file, compaction counting) - [x] 8 existing overflow-compaction tests pass (no regressions) - [x] Linter passes (0 warnings, 0 errors) 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3> Adds a pre-prompt “session-growth guard” to `runEmbeddedPiAgent` that estimates the *stored* token count from the session JSONL and forces compaction when it exceeds 80% of the model context window. This is intended to prevent unbounded session store growth when downstream pruning/history-limiting modifies messages only in-flight. Also introduces `estimateSessionFileTokens()` to compute an approximate token count from the on-disk session context, and adds a dedicated test suite for the guard behavior. <h3>Confidence Score: 4/5</h3> - This PR looks safe to merge after fixing a test that relies on an invalid type cast. - The runtime change is isolated (best-effort guard + existing compaction path) and covered by new tests, but one test currently bypasses the real params contract by casting `undefined` to a required `string`, which can mask mismatches between intended and actual runtime states. - src/agents/pi-embedded-runner/run.session-growth-guard.test.ts <!-- greptile_other_comments_section --> <sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub> **Context used:** - Context from `dashboard` - CLAUDE.md ([source](https://app.greptile.com/review/custom-context?memory=fd949e91-5c3a-4ab5-90a1-cbe184fd6ce8)) - Context from `dashboard` - AGENTS.md ([source](https://app.greptile.com/review/custom-context?memory=0d0c8278-ef8e-4d6c-ab21-f5527e322f13)) <!-- /greptile_comment -->

Most Similar PRs