Repository navigation
feat(chat): auto-compact a web DM at the context threshold (CHE-1807) [merge] - #285
Merged
Merged
Conversation
added 9 commits
October 16, 2026 08:06
Claude: usage of the last main-loop assistant message plus contextWindow
from the result modelUsage. Codex: latest thread/tokenUsage/updated
last.inputTokens and modelContextWindow. The daemon sends an optional
context {tokens, window} on /complete; the server stores it in nullable
agent_task_queue.context_tokens/context_window inside the terminal
transaction. Old daemons leave NULL.
settings.auto_compact {enabled, threshold_pct} (defaults on, 80; 50 to 90,
else 400 naming the field) through a top-level auto_compact field on
PATCH /api/workspaces/{id}; null resets. Per-agent override in
runtime_config.auto_compact, same validation. Settings > Workspace gets an
Auto-compact switch and a Threshold (%) field below Compact prompt.
…re guard (CHE-1807)
After a completed run on a web DM, the server queues one compaction task when the run's last prompt reached the effective threshold (agent override over workspace over the 80% default). The task owns no user input; claim sets its prompt to the compact command. The server writes the reason into the old DM as a compact_notice and leads the new DM's summary with it. A send while a compaction is queued, dispatched, running, waiting_local_directory or deferred returns 409 chat_compacting. A manual /compact is marked at enqueue and locks sends the same way. Every terminal path of an automatic compaction that did not continue the DM posts a failure notice, and a new attempt waits for the context to grow 10% past the failed trigger. Web: composer disabled with Compacting, notice row, 409 toast.
added 4 commits
October 16, 2026 10:07
added 6 commits
October 16, 2026 12:40
…-trigger # Conflicts: # packages/core/workspace/auto-compact.test.ts # packages/core/workspace/auto-compact.ts # server/internal/handler/auto_compact.go # server/pkg/db/generated/agent.sql.go # server/pkg/db/generated/autopilot.sql.go # server/pkg/db/generated/chat.sql.go # server/pkg/db/generated/models.go # server/pkg/db/generated/runtime.sql.go # server/pkg/db/generated/supplement.sql.go # server/pkg/db/generated/wakeup.sql.go
627_agent_task_queue_context (#281) and 627_unpin_archived_chat_sessions (CHE-1801) share numeric prefix 627, which fails TestMigrationNumericPrefixesAreUnique on main. The migration uses ADD COLUMN IF NOT EXISTS, so a database that already applied the old name re-runs it as a no-op.
…e duplicate 627 prefix (CHE-1824) 627_agent_task_queue_context and 627_unpin_archived_chat_sessions share a numeric prefix, which fails TestMigrationNumericPrefixesAreUnique on main. The later-merged migration is renumbered to 630; 628 and 629 stay free for open pull requests. Versions are file basenames, so a database that applied the old name reruns the identical idempotent ADD COLUMN IF NOT EXISTS and records the new version; the legacy row stays. The SQL bytes are unchanged.
The context migration moved to 628 (PR #289) to clear a 627 prefix collision.
added 2 commits
October 16, 2026 13:51
…-migration-627' into che-1807-auto-compact-trigger # Conflicts: # server/migrations/627_agent_task_queue_context.down.sql # server/migrations/627_agent_task_queue_context.up.sql # server/migrations/628_agent_task_queue_context.down.sql # server/migrations/628_agent_task_queue_context.up.sql # server/migrations/630_agent_task_queue_context.down.sql # server/migrations/630_agent_task_queue_context.up.sql
…tion migration to 655 and regenerate sqlc (CHE-1807)
added 2 commits
October 17, 2026 08:30
…acts (CHE-1807) The compacting composer is disabled and the pending task is the compaction, so Queue Send cannot send. A nonempty or /fork draft swapped Stop for a disabled Queue Send. With compacting set, Stop shows whatever the draft holds. Test typing repaired in the same commit (return order of the helper).
added 2 commits
October 17, 2026 09:43
…guard (CHE-1807) Retrospective acceptance tests: cancelling an auto compaction in each of the five active states unlocks sends and posts the failure notice; the stuck-task sweeper (queued expiry, dispatched and running stale) runs the same guard, leaves no active compaction behind and holds the 1.1x re-arm rule. All pass without a production change.
This was referenced Oct 17, 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.
Status
Draft. Layer A3 of CHE-1803 (DM auto-compact). A1 (PR #281) and A2 (PR #282) are merged to
main. The repair PR #290 (CHE-1824) is merged tomainas2b135399996d8072c5a99deb88ef55edb62f49b4; it renumbered the context migration to 630. PR #289 was closed without merging. This PR targetsmain;origin/mainis merged into the branch, so the visible diff is A3 only. Merge stays Cheese's gate.Conditions
queued,dispatched,running,waiting_local_directory,deferred. Send rejection and duplicate suppression are tested in each of the five.SettleTerminalTaskState, the single entry point of every terminal path. The tests drive completed, failed and cancelled. A swept task is not driven separately.Change
agent_task_queue.task_kind,compact_reason,compact_trigger_tokens.compact_noticerow:Auto-compacted: context 164k of 200k tokens (82%) reached the 80% threshold. Continuing in a new DM.The new DM's summary starts with the same reason line. The notice never enters a prompt.chat_compacting. The check runs under the session lock. A manual/compactis marked at enqueue and locks sends the same way. Cancelling the compaction unlocks sends.Auto-compact failed (<status>). Type /compact to retry.A new attempt waits until the context grows 10% past the failed trigger. A failed manual compaction suppresses nothing.GET /chat/sessionsand/chat/sessions/{id}returncompacting. Thechat:session_updatedevent carries it.Correction after review (Sol, P2)
While a DM compacts, a preserved nonempty or
/forkdraft hid Stop and showed a disabled Queue Send. Commit 5945fb0 adds runtime regression tests first (2 failed, 1 passed against the parent, matching Sol's probe: ordinary and/forkdrafts had no Stop button; the empty-draft control passed). Commit 0b667ec makesChatInputshow Stop whenevercompactingis set, and the same tests pass. Both chat surfaces use this input. The draft stays in the editor and nothing is sent. Migration SQL is unchanged. Prefix audit onmain2b135399996d8072c5a99deb88ef55edb62f49b4: 627, 628, 629 (other work), 630 (context), 653, 655 (compaction) are unique, andTestMigrationNumericPrefixesAreUniqueand the sqlc diff are clean.Acceptance coverage added (retrospective)
Commit b95365c adds handler tests that all pass with no production change: cancelling an auto compaction in each of the five active states (
queued,dispatched,running,waiting_local_directory,deferred) unlocks sends and postsAuto-compact failed (cancelled); the stuck-task sweeper (queued expiry, dispatched and running stale, followed by the retry handler) postsAuto-compact failed (failed), leaves no active compaction behind, unlocks sends and holds the 1.1x re-arm rule.waiting_local_directoryanddeferredare excluded from the stale sweep by design, so only cancel drives them. No test exposed a defect, so there is no new red.Evidence
Test-First Gate: commit 8ae363b is tests-only and fails against its parent for the stated behavior (runtime failures, not compile errors). Commit fae0b75 implements it. A later test commit dfc453d and fix commit 36a9ad1 disable the chat page composer, which the first pass missed. The merge commit 80e936d brings A1 in first.
Red at 8ae363b. Go: every new handler test failed, for example
column "task_kind" does not exist (SQLSTATE 42703)andsession response has no compacting field. Web:Green at fae0b75. These pass:
go test ./internal/handler ./internal/service(full packages);chat,localesandsettingsweb tests (1040 tests);go vet, and the views and core typecheck.Not clean on this X99 runtime:
cmd/serverTestSweepDispatchedStaleTaskfailed once in this run and also failed once on A1's CI. It passes when run alone. It is not caused by this PR, which does not touch the sweeper. CI is the authority.Changelog: Web DMs now compact themselves into a new DM when their context reaches the configured share of the window, and say why.
Closes CHE-1807
Refs CHE-1803