Repository navigation
feat(server): add /compact context compaction on every agent - #252
Merged
Merged
Conversation
A user message of exactly /compact now compacts the thread's provider context instead of being sent as a prompt. Each adapter declares how it compacts: Codex and OpenCode run their native compaction, Claude and Grok send /compact as a turn, Cursor sends /compress, and an adapter that declares nothing fails loudly. Messages sent while a thread compacts queue and are replayed in order once it finishes, or are reported as not sent if compaction fails or the session stops. Claude also gains an Auto-compact after setting (100,000 to 1,000,000 tokens), reports its auto-compact threshold, and asks through the existing question UI whether to compact an old session on resume. Ported from pingdotgg#9293 Ported from pingdotgg#10112 Ported from pingdotgg#11107 Ported from pingdotgg#8144 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…on-server # Conflicts: # CHANGELOG.md
TheDarkPhantom
enabled auto-merge
September 30, 2026 11:53
…on-server # Conflicts: # CHANGELOG.md
This was referenced Sep 30, 2026
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.
The fork only observed compaction. Nothing could trigger it, so a long thread kept growing until the provider compacted it on its own terms. This ports upstream's
/compactcommand (server, contracts, shared only; the web UI comes later).How it works
/compactwith no attachments is intercepted byProviderCommandReactorand routed to the newProviderService.compactThreadinstead of being sent as a prompt. It is rejected when the thread has no conversation yet, or while a turn is running.compaction(a required field onProviderAdapterShape, following refactor(server): let adapters declare context compaction pingdotgg/t3code#10112):thread/compact/start, and a finishedcontextCompactionitem now emitsthread.state.changed: compacted.session.summarize({ auto: false })and mapssession.compacted./compactas a turn, and Cursor sends/compress.unsupported, which fails with a validation error.ProviderCompaction.ts, soProviderService.tsonly gains a few call sites. It allows one compaction per thread and uses a 10-minute timeout. A native run that times out blocks retries until it reports back or the session restarts. A slash-command run waits for its own turn to settle, and if that turn completes without reporting a compaction, one is synthesized. The compacted event carries the/compactmessage id asrequestId./compactpending row while messages queue behind it. It clears that row on acontext-compactionorprovider.turn.start.failedactivity whoserequestIdmatches, or when the reactor sets the session back to ready.beforeTokens/afterTokens, taken from the provider when it reports them (Claude'scompact_boundary) and otherwise from the last two context-window readings. The activity summary reads "Compacted context 899K → 0 tokens".autoCompactWindowsetting (100000 to 1000000). A settings patch with any other value is rejected, and a bad value already stored decodes to empty.ThreadTokenUsageSnapshot.autoCompactThreshold.onUserDialogwithsupportedDialogKinds: ["resume_return"], surfaced through the existing AskUserQuestion user-input path with "Compact and continue" / "Keep full history" / "Don't ask again".packages/shared/src/claudeCompaction.ts./compactas a slash command.No DB migrations. The web-only follow-ups (pingdotgg#11103, pingdotgg#9623, pingdotgg#9430, and the web half of pingdotgg#8144) are listed in FUTURE_ENHANCEMENTS.md.
Ported from pingdotgg#9293, pingdotgg#10112, pingdotgg#11107 and pingdotgg#8144.
Tests cover reactor
/compactrouting, the empty-thread rejection, queue and replay order, queued-message cancellation on failure, per-adapter compaction (Codex, OpenCode, native and slash-command in ProviderService, unsupported, timeout quarantine), the projection's pending-row handling, ingestionrequestIdand token sizes, the Claude setting and dialog, the settings decode, and the shared copy.Done by Claude Opus 5.5 (1M context) in Claude Code.
🤖 Generated with Claude Code