- Added compaction.asyncEnabled (Async Compaction, default on): when
context enters the pre-threshold band [threshold - lead, threshold)
with lead = clamp(threshold * 0.125, 8192, 32000), maintenance
speculatively summarizes in the background off a branch snapshot
(first configured LLM-backed method: remote, handoff, or soft) using
a side session id isolated from the live turn. Crossing the threshold
splices the armed result in instantly instead of blocking on a
summarization round-trip. Armed results are invalidated by branch
changes, reset boundaries, model switches that strand provider-native
replay payloads, and context growth past keepRecentTokens (which
re-speculates); extensions registering session_before_compact keep
exact blocking semantics (speculation disabled).
- Reworked handoff to commit in place: /handoff and the auto handoff
method now write the generated document as a regular compaction entry
on the current session (summary = document + <files> tag, cut from
prepareCompaction) instead of starting a new session. SessionHandoff
shrank to a document generator; session_before_switch/session_switch
no longer fire with reason "handoff"; mid-turn maintenance no longer
suppresses the handoff preference; overflow recovery can apply an
armed handoff result.
- Extracted the shared auto-compaction commit tail
(#commitAutoCompactionResult / #commitCompactionEntry) used by the
blocking production path, the armed speculative apply, manual
compaction, and manual handoff.
- Status line pulses the auto-compact icon while a speculation runs and
holds it in accent once a result is armed.
- Exported remotePreserveReusable from pi-agent-core/compaction for
apply-time validation of speculative remote results.
- Replaced legacy `compaction.strategy` and `remoteEnabled` settings with `compaction.methodOrder` across session maintenance, schema, and tests.
- Added automatic fallback mechanism to try subsequent compaction methods upon failure or unsupported model capabilities.
- Added mouse drag-and-drop reordering support and click handlers to multi-select settings submenus.
- Updated documentation and test suites to reflect ordered compaction strategy preferences and fallback chains.
getContextBreakdown used message position (anchorIndex >= pending.cutoffCount) as a proxy for usage freshness. After a mid-run compaction rebased the in-flight snapshot, an in-flight provider response whose request predated the compaction landed past the rebase cutoff carrying pre-compaction usage, so it out-ranked the rebased estimate and reported the pre-compaction token count (~2.6x the real one). That phantom overflow tripped the "freed too little context to make progress" guard and drove the frame-rescue path on a byte-identical tokensBefore.
Assistant context snapshots now carry a monotonic compaction epoch, bumped in rebaseAfterCompaction and stamped at message-record time. A post-cutoff anchor whose epoch predates the pending snapshot's epoch is no longer trusted over the rebased estimate.
Fixes#8887
- Replaced time-based sleeps and polling loops with event-driven promise resolvers and fake timers across agent and tool tests.
- Migrated test suites to share in-memory auth storage and fixtures using lifecycle hooks.
- Updated catalog model definitions, metadata, and configurations.
- Remove redundant definedness, null, and type checks across test suites in multiple packages.
- Clean up unused assertions, metadata tests, and obsolete test cases.
- Add good versus bad test filter guidelines and requirements to project documentation.
Main renamed/refactored #tryShakeRescueForDeadEnd + #emitShakeRescueNotice into
the tiered #rescueCompactionDeadEnd (elide, then image drop, notices emitted
internally), so a textually-clean merge of this branch left calls to undefined
private methods. Re-express the !preparation rescue through the new API:
progress = prepareCompaction succeeding on the rewritten branch, skipElide when
falling through from a shake pass (the image tier still gets a chance), and
historyRewritten flagged whenever a tier freed content even without progress.
Restore the baseline dead-end remedy text (image drop is automated now, so the
manual /shake images suggestion is stale) and align the rescue-refit regression
test with main's continuation gating (auto-continue after compaction now
requires an active goal or queued work).
- Prevented compaction from reopening a settled terminal answer unless queued work or an active goal remains.
- Ran auto-learn capture in an abortable detached agent with constrained tools and isolated provider state.
- Replaced primary-turn capture coverage with private-capture regression tests.
Fixes#5715
When the single most-recent turn is itself over budget, prepareCompaction
returns undefined (findCutPoint never cuts inside a tool result, so the kept
tail has nothing on the summarizable side) and summary compaction cannot
start. The !preparation short-circuit in #runAutoCompaction emitted the
"Compaction freed too little context to make progress" warning and paused,
never running the artifact-backed shake elide rescue that #3786 wired into the
post-maintenance guard — so snapcompact/context-full maintenance looped the
warning with no attempt to shrink the oversized tail.
Run the same elide rescue before pausing, re-prepare on the shrunken branch,
and fall through to a normal compaction when the tail became summarizable
(writing a compaction entry anchors the stale billed usage so the auto-continue
re-check cannot re-trip). Only pause with a single warning when nothing is
elide-eligible. Flag historyRewritten on a rescue that offloaded content so
overflow recovery does not re-restore the just-failed turn onto the elided tail.
Fixes#4786
- Added test coverage for auto-compaction entry warning attribution during dead-end scenarios.
- Verified automatic continuation and warning suppression when image-drop recovery successfully clears context pressure.
- Mocked session context usage and image-drop functionality to simulate high-usage state recovery.
- Update in-flight context snapshots after historical messages are modified by compaction or elision.
- Prevent stale run-start token counts from triggering false-positive dead-end "no progress" warnings during auto-continuation.
- Add regression test to verify that prompt headroom measurements correctly account for post-compaction context sizes.
- Made CompactionSettings.reserveTokens optional so field presence carries provenance; the proportional small-window fallback only applies to genuinely defaulted reserves.
- Clamped the fallback reserve to >= 1 and the derived threshold strictly below the context window.
- Changed the coding-agent settings-schema default from 16384 to unset so Settings.get() no longer materializes a default that masks provenance.
Cherry-pick of the reserve-budget clamp only (resolveBudgetReserveTokens + no-op compaction guard): applies compaction.ts + agent-session.ts + compaction/shake/progress-guard tests. Excludes unrelated Julia prelude timeout and ai/test churn from the PR head.
- Added a last-resort recovery step to run `shake("elide")` on oversized message tails when auto-compaction cannot otherwise free enough context.
- Re-tests the context headroom and auto-continue predicates after a successful rescue before falling back to pausing maintenance.
- Updated the dead-end warning message to suggest running `/shake images` for irreducible, image-only tails.
Drop the persisted assistant error before #runAutoCompaction so the kept region is clean, then re-append it on COMPACTION_CHECK_NONE without a fresh compaction entry — covers no-model, hook-cancel, and compaction-error paths. Same rollback for response.incomplete recovery.
Fixes#3747
Split active-context vs persisted-history removal in #checkCompaction so the persisted assistant error stays on the branch unless context promotion or compaction is actually scheduled.
Fixes#3747
Removed recoverable context-overflow and incomplete-response assistant errors from both active context and persisted session history before compaction/promotion schedules the retry.
Fixes#3747
- Renamed the `find` and `search` tools to `glob` and `grep` respectively across the codebase to improve command clarity.
- Implemented full-stack support for the renamed tools, including CLI arguments, system prompts, SDK exports, and tool registration.
- Added automated migration logic in `settings` to transform legacy `find` and `search` configuration keys to their new equivalents.
- Updated the `collab-web` renderer registry to ensure backwards compatibility with legacy tool outputs.
The post-maintenance headroom guard returned residualTokens < triggerContextTokens
as a secondary check after the recovery-band test. When stale/tool-output pruning
already drove the trigger (postMaintenanceContextTokens) below the band before this
pass, that strict-less comparison made a residual which merely held the line at/under
the band report a false no-progress, suppressing a valid auto-continue and emitting a
spurious warning even though the next turn could no longer re-trip threshold compaction.
The recovery band sits strictly under the compaction threshold, so reaching it already
guarantees the next turn cannot re-trip. Make the band authoritative (residual <= band)
and drop the trigger argument. Adds a regression covering the sub-band trigger case.
(cherry picked from commit 31cf2dc7a30c4134f7a351d61065eca76543f154)
Addresses PR #3412 review (roboomp blocking + codex P2 + Copilot nits):
- The overflow/incomplete retry no longer reuses the COMPACTION_RECOVERY_BAND
hysteresis. Reusing it required residual context below 0.8×threshold, which
turned a recoverable overflow (e.g. 150k on a 200k window, under the ~170k
threshold) into a manual dead-end. Add #compactionCreatedRetryFit, which
measures the rebuilt prompt against the usable fit budget
(contextWindow - effectiveReserveTokens) and is evaluated AFTER the failed
assistant is dropped, so the just-failed turn is excluded.
- The threshold auto-continue keeps the stricter recovery-band check
(#compactionCreatedHeadroom) — that path is the snapcompact thrash guard.
- Split the no-progress warning so each path warns on its own signal.
- Alias errorIsFromBeforeCompaction as assistantPredatesCompaction in the
threshold-usage path for clarity; de-duplicate the rationale comment.
Adds two regression tests (recoverable overflow retries; non-fitting overflow
pauses + warns), mutation-verified against the band-vs-fit split.
(cherry picked from commit f8cf45b2740f04d8776a84521ba563b779d65b25)
prepareCompaction keeps the most-recent turn verbatim (findCutPoint never
cuts at tool results), so when that single turn already exceeds the
compaction threshold the rewritten context stays above threshold. The
context-full / snapcompact auto-compaction success tail scheduled the
agent-authored auto-continue (and the overflow/incomplete retry)
unconditionally, so the next agent_end re-entered #checkCompaction over
the same oversized tail and re-fired forever.
This is the residual loop left after #3247 capped snapcompact's own frame
projection: once #computeSnapcompactMaxFrames drops the frame cap below
one frame, snapcompact is skipped and the context-full summarizer path
still creates no headroom, so the loop persists on that path.
- #runAutoCompaction now gates the continuation and the overflow/
incomplete retry on a post-maintenance headroom check
(#compactionCreatedHeadroom), reusing the shake recovery-band
hysteresis from #2275 (consolidated as the shared
COMPACTION_RECOVERY_BAND). When a pass frees too little it pauses
automatic maintenance and emits a single warning instead of looping.
- The post-turn threshold check ignores an assistant's stale
pre-compaction usage so the scheduled auto-continue can't re-trip on
the kept assistant's old high token count.
Adds a regression test covering the no-headroom (pause + warn, no
continuation) and headroom (auto-continue, no warn) paths; both
assertions are mutation-verified against the guard.
(cherry picked from commit 6fcbbe2b3075827ee621acaee8efa2c586eedd3e)