Skip to content

fix: stabilize gradient cache with budget snapshot, hysteresis, and per-session LTM#144

Merged
BYK merged 3 commits intomainfrom
fix/gradient-cache-bust-stability
May 7, 2026
Merged

fix: stabilize gradient cache with budget snapshot, hysteresis, and per-session LTM#144
BYK merged 3 commits intomainfrom
fix/gradient-cache-bust-stability

Conversation

@BYK
Copy link
Copy Markdown
Owner

@BYK BYK commented May 7, 2026

Summary

Fixes a 79% global cache-bust rate (366/464 turns across all active sessions) caused by three compounding instabilities in tryFitStable().

Root Cause

The raw window's leading-edge message ID shifts on nearly every transform due to:

  1. Budget drift from shared globalscalibratedOverhead (EMA) and ltmTokens are module-level globals shared across all sessions. Interleaved sessions (e.g. gateway at 928K usable vs OpenCode at 118K) contaminate each other's budget calculations, causing rawBudget to swing by ~8-24K tokens between consecutive transforms of the same session.

  2. Token estimate mutationdeduplicateToolOutputs() replaces earlier duplicate tool outputs with compact annotations, changing estimateMessage() costs throughout the window. This shifts the backward-scan cutoff even when the budget is stable.

  3. No tolerance in pin checktryFitStable evicts the pinned window on any overflow (pinnedTokens > rawBudget), even a 1-token overshoot from estimation noise.

Fix (three complementary approaches)

  • Budget snapshot — Store rawBudget in RawWindowCache.pinnedBudget at pin creation. The pin check uses this snapshot instead of the current (possibly drifted) budget.

  • Hysteresis — Pin validity uses pinnedBudget * 1.10 (10% margin) to absorb residual noise from dedup token estimate changes and overhead EMA drift.

  • Per-session ltmTokens — Moved from module-level global to SessionState. setLtmTokens(tokens, sessionID?) stores per-session when ID is provided, with module-level fallback for backward compatibility. Eliminates cross-session budget contamination at the source.

Changes

File Change
packages/core/src/gradient.ts All three fixes: RawWindowCache.pinnedBudget, hysteresis check, per-session ltmTokens in SessionState
packages/core/test/gradient.test.ts Updated LTM tests to use per-session setLtmTokens(tokens, sessionID)
packages/opencode/src/index.ts Pass sessionID to setLtmTokens (6 call sites)
packages/gateway/src/pipeline.ts Pass sessionID to setLtmTokens (4 call sites)
packages/pi/src/index.ts Pass sessionID to setLtmTokens (2 call sites)
.lore.md Updated long-term knowledge

Test Results

All 861 tests pass across 33 files.

BYK added 3 commits May 7, 2026 20:22
Replace N individual TOML fetches from GitHub with a single request to
https://models.dev/api.json — returns all providers/models with pricing.
Filter for anthropic provider, extract cost.input per model. Separate
1h cost cache alongside model discovery cache. Falls back to hardcoded
costs only when models.dev is unreachable.
…er-session LTM

Addresses 79% global cache-bust rate (366/464 turns) caused by three
compounding mechanisms in tryFitStable():

1. Budget snapshot: store rawBudget in RawWindowCache.pinnedBudget at pin
   creation so the pin check uses the same budget the window was built
   against, not a budget that drifted from global state changes.

2. Hysteresis: use pinnedBudget * 1.10 threshold in pin validity check
   to absorb minor fluctuations from deduplicateToolOutputs() token
   estimate changes and overhead EMA drift.

3. Per-session ltmTokens: move from module-level global to SessionState
   to eliminate cross-session budget contamination (e.g. a 928K-usable
   gateway session polluting a 118K-usable OpenCode session's budget).
@BYK BYK merged commit 09bcef3 into main May 7, 2026
1 check passed
@BYK BYK deleted the fix/gradient-cache-bust-stability branch May 7, 2026 20:41
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