Skip to content

feat(chat): auto-compact a web DM at the context threshold (CHE-1807) [merge] - #285

Merged
congvc-dev merged 26 commits into
mainfrom
che-1807-auto-compact-trigger
Oct 17, 2026
Merged

congvc-dev merged 26 commits into
mainfrom
che-1807-auto-compact-trigger

Conversation

@congvc-bot-x99

@congvc-bot-x99 congvc-bot-x99 Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

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 to main as 2b135399996d8072c5a99deb88ef55edb62f49b4; it renumbered the context migration to 630. PR #289 was closed without merging. This PR targets main; origin/main is merged into the branch, so the visible diff is A3 only. Merge stays Cheese's gate.

Conditions

  • Auto-compact needs a daemon that reports context (A1). Old daemons leave NULL, and their runs never trigger it.
  • The trigger covers web DMs only. A channel-bound chat is skipped.
  • A compaction keeps the active-state set the design review required (CHE-1804 P1): queued, dispatched, running, waiting_local_directory, deferred. Send rejection and duplicate suppression are tested in each of the five.
  • Mobile needs no change: it shows the 409 under its existing send-failure rule. Not run on a device.
  • The stuck-task sweeper path is covered through SettleTerminalTaskState, the single entry point of every terminal path. The tests drive completed, failed and cancelled. A swept task is not driven separately.
  • Retrospective tests, added with the implementation and not first: the service resolver and boundary tests. One red test fixture was repaired: a second fixture in one test reused an agent name and now runs as a subtest.

Change

  • Migration 655: agent_task_queue.task_kind, compact_reason, compact_trigger_tokens.
  • After a completed run, the server queues one compaction task when the run's last prompt reached the threshold (agent override over workspace over 80%). The task owns no user input. The claim sets its prompt to the compact command, so the workspace and agent Compact prompt apply.
  • The server writes the reason into the old DM as a compact_notice row: 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.
  • A send while a compaction is active returns 409 chat_compacting. The check runs under the session lock. A manual /compact is marked at enqueue and locks sends the same way. Cancelling the compaction unlocks sends.
  • Failure guard: an automatic compaction that ends without continuing the DM posts 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/sessions and /chat/sessions/{id} return compacting. The chat:session_updated event carries it.
  • Web: the composer is disabled with "Compacting…" and keeps the draft. The notice renders as a muted note. A 409 shows a toast. All five locales are updated.

Correction after review (Sol, P2)

While a DM compacts, a preserved nonempty or /fork draft 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 /fork drafts had no Stop button; the empty-draft control passed). Commit 0b667ec makes ChatInput show Stop whenever compacting is 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 on main 2b135399996d8072c5a99deb88ef55edb62f49b4: 627, 628, 629 (other work), 630 (context), 653, 655 (compaction) are unique, and TestMigrationNumericPrefixesAreUnique and 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 posts Auto-compact failed (cancelled); the stuck-task sweeper (queued expiry, dispatched and running stale, followed by the retry handler) posts Auto-compact failed (failed), leaves no active compaction behind, unlocks sends and holds the 1.1x re-arm rule. waiting_local_directory and deferred are 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) and session response has no compacting field. Web:

⎯⎯⎯⎯⎯⎯⎯ Failed Tests 2 ⎯⎯⎯⎯⎯⎯⎯
AssertionError: expected 'This session is archived' to be 'Compacting…' // Object.is equality
TestingLibraryElementError: Unable to find an accessible element with the role "note"
      Tests  2 failed | 119 passed (121)

Green at fae0b75. These pass:

  • go test ./internal/handler ./internal/service (full packages);
  • the full views chat, locales and settings web tests (1040 tests);
  • go vet, and the views and core typecheck.

Not clean on this X99 runtime: cmd/server TestSweepDispatchedStaleTask failed 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

congvc-bot[bot] 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.
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.
Base automatically changed from che-1806-auto-compact-setting to main October 16, 2026 05:14
congvc-bot[bot] 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.
congvc-bot[bot] 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)
@congvc-bot-x99 congvc-bot-x99 Bot changed the title feat(chat): auto-compact a web DM at the context threshold (CHE-1807) feat(chat): auto-compact a web DM at the context threshold (CHE-1807) [merge] Oct 17, 2026
congvc-bot[bot] 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).
@congvc-bot-x99
congvc-bot-x99 Bot marked this pull request as ready for review October 17, 2026 02:38
congvc-bot[bot] 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.
@congvc-bot-x99
congvc-bot-x99 Bot marked this pull request as draft October 17, 2026 03:15
@congvc-bot-x99
congvc-bot-x99 Bot marked this pull request as ready for review October 17, 2026 03:42
@congvc-dev
congvc-dev merged commit d4978e0 into main Oct 17, 2026
41 checks passed
@congvc-dev
congvc-dev deleted the che-1807-auto-compact-trigger branch October 17, 2026 05:33
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