Compaction v2 (2/3): ModelSummary and ProviderDefault strategies, delete signal pruning - #198
Open
pbdeuchler wants to merge 4 commits into
Open
Compaction v2 (2/3): ModelSummary and ProviderDefault strategies, delete signal pruning#198pbdeuchler wants to merge 4 commits into
pbdeuchler wants to merge 4 commits into
Conversation
Compaction v2, part 2 (#195). The runtime has known *when* to compact since #194; this supplies *what happens*, makes it selectable from config, and deletes the signal-pruning machinery it replaces. Net diff is negative. - `ModelSummary` is the new default. When the `task` tool is registered it first nudges the model to persist its remaining work; only that reply's `task` calls run and reach the next request (text and other calls are dropped, though the event log keeps the whole reply, so no dangling call is ever sent back to the provider). It then sends the built-in checkpoint instructions and starts the next window from the reply alone, as one user-role message after the static prefix, with a todo reminder when the nudge ran calls. - `ProviderDefault` delegates the rewrite to `Provider::compact` on Halter's trigger only and derives the window it may replace from the provider's `compaction_strategy`. Anthropic keeps the inline summarization request: the shipped `compact_20260112` context edit fires only on the server's own token trigger (50,000 minimum) and cannot be invoked on demand, which would hand the trigger to the server. - `context.compaction = "model_summary" | "provider_default"`. Selecting `provider_default` for a default model whose provider cannot compact fails `HalterBuilder::build`, never the first compaction. - `CompactionContext` is now a runtime-backed engine: `append`, `record`, `infer`, and `execute_tool_calls` run through the turn's own planner, prompt cache, hooks, policy, and event log. The turn loop shares `plan_and_assemble` and `run_provider_request` with it. - Removed: `Provider::compaction_window` and every adapter impl, signal scoring and pruning, `MessageSignal`, `PruneSignalThreshold`, `CompactionWindow`, `SummarySlice`, `SessionState::summaries`, `ContextPlan::carried_summaries`, `context.pre_compaction_target`, `context.prune_signal_threshold`, and the interim `ProviderCompaction`. - `default_compaction_prompt()` is now the context-checkpoint request; it ends by asking for plain text and no tool calls. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014f6squKQimqeu4FLRvHPhT
Make context accounting complete and replayable, make strategy passes transactional, preserve provider chronology and usage, and replace stateless threshold notifications with per-window boundary directives. Add regressions for cap enforcement, rollback, replay, usage, exact thresholds, and CleanWindow rollover prerequisites. Assisted-By: devx/fb87890b-8124-4c12-88e2-65b8e1dbaeca
Assisted-By: devx/fb87890b-8124-4c12-88e2-65b8e1dbaeca
…ger to the runtime Review follow-ups on the compaction v2 remediation commits. - A pass that appends and then fails or finds nothing to compact no longer truncates the event log or rolls back usage. Everything the pass did stays in the log and the session totals; the runtime records a `ContextRestored` event that puts the transcript window and ledger back, applied through the same fold transition replay uses. The manual `compact()` path commits the pass's events before surfacing its error. - `context_boundary` returns notifications only. The runtime compacts on `ContextSettings::compaction_due`; `CompactionDirective`, `CompactionBoundaryResult`, and the `Rollover` trigger are gone. - The ledger is prepared before the turn's boundary baseline is taken, so a fresh session's request base does not read as a crossing. - Stale inline-window docs in the protocol crate and the fold's field list are corrected; README, runtime README, and CHANGELOG follow. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014f6squKQimqeu4FLRvHPhT
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #195. Builds on merged PR #197 / #194, and incorporates the boundary requirements discovered while designing #196.
Cohesive issue lineage
ModelSummaryandProviderDefault, config selection, and deletion of signal pruningCleanWindow; its per-session reminders and forced rollover drove the revised boundary API in this PRSummary
This supplies what happens when #197's ledger says it is time to rewrite context.
ModelSummary (new default)
tasktool is registered, first nudges the model to persist concise remaining work. Onlytaskcalls execute; text and foreign calls are excluded from the next request while the successful exchange remains in the event log.ProviderDefault
Provider::compactonly when Halter's ledger requests it. Provider-side automatic triggers remain disabled.Config and deletion
context.compaction = "model_summary" | "provider_default";model_summaryis the default.provider_defaultfor an unsupported default provider fails duringHalterBuilder::build.context.pre_compaction_target,context.prune_signal_threshold, andProvider::compaction_window.Cohesive-review remediation
The follow-up commit
8fae7e3remediates the findings from reviewing #197 and #198 together:ContextProjectionUpdatedmakes request-base changes replayable; compaction usage and logical-window advancement fold identically in live and replayed state.ErrandOk(None)restore staged transcript, usage, events, and fired-hook state. Empty ModelSummary and ProviderDefault output cannot destroy context. Automatic no-op passes still complete the PreCompact/PostCompact hook pair.SessionState::usage_so_far,TurnCompleted, compaction events, and replay.threshold_notificationsis replaced bycontext_boundary(CompactionBoundary), with session/window identity, previous/current counts, persisted per-window notification IDs, andContinue/Compact/Rolloverdirectives. Successful rewrites advance the logical window and re-arm notifications.Commit
96cb77amakes the boundary tests derive their thresholds from the session's actual prompt and compiled tool specs, keeping their intended ordering stable under both default and all-features builds.Breaking changes
ModelSummary; selectprovider_defaultto retain the prior behavior.Provider::compaction_windowas described above.CompactionStrategy::threshold_notificationsis replaced bycontext_boundary;CompactionTriggergainsRollover.CompactionContextfields are private; use its accessors and action methods.CompactionEffectsandCompactionEventEffectsgainusage.SessionStategainscontext_windowandcompaction_notifications.SessionEventPayloadgainsContextProjectionUpdated; exhaustive matches need a new arm.TokenLedgergains request-base/accounting-version fields; struct literals should use..TokenLedger::default().RuntimeServicesgains context/strategy fields,ContextSettingsgainsmax_tokens, andresolve_response_chaintakes four arguments.The full migration list is recorded in
CHANGELOG.md.Verification
PLAYWRIGHT_DRIVER_VERSION=1.59.1 cargo test --workspace— 937 unit/integration tests plus 5 doctests passed.PLAYWRIGHT_DRIVER_VERSION=1.59.1 cargo test --workspace --all-features— 968 unit/integration tests plus 5 doctests passed.PLAYWRIGHT_DRIVER_VERSION=1.59.1 cargo clippy --workspace --all-targets --all-features -- -D warnings— clean.cargo fmt --all -- --checkandgit diff --check— clean.