Skip to content

feat(web): compact a thread from the context meter - #256

Merged
TheDarkPhantom merged 3 commits into
mainfrom
feat/context-compaction-web
Sep 30, 2026
Merged

TheDarkPhantom merged 3 commits into
mainfrom
feat/context-compaction-web

Conversation

@TheDarkPhantom

Copy link
Copy Markdown
Owner

#252 landed context compaction on the server, but the web client had no way to trigger it besides typing /compact, no timeline rendering for it, and no handling of Claude's resume prompt.

This ports the web parts of upstream pingdotgg#9293 and pingdotgg#8144, plus pingdotgg#4772 (ContextWindowMeter.logic.ts), pingdotgg#11103 (drafts survive compaction) and pingdotgg#9623 (compaction folds with a settled turn).

Context meter

Timeline

  • context-compaction activities get their own static divider row (for example "Compacted context 899K → 19K tokens"). They are never grouped into work rows.
  • A lone compaction stays visible. When a settled turn folds other work, the compaction folds with it (fix(web,mobile): fold context compaction under settled turn folds pingdotgg/t3code#9623).
  • While a /compact runs, the working row reads "Compacting context for Ns" with a static icon instead of the pulsing dots. The only repaint is the existing once-a-second timer text.
  • provider.turn.start.failed rows ("Context compaction failed", "Queued message was not sent") still render as error work rows. They now also acknowledge the local send, so the composer stops waiting for a session change that never comes (upstream latestTurnStartFailureId).

Claude resume

  • Adds upstream's "Resume with less context" banner for Claude threads idle for 70 minutes or more with at least 100k tokens. It schedules one timer for when the thread crosses the idle threshold; there is no minute clock. "Keep full history" dismisses it for that snapshot.
  • Fork addition: when the pending user-input request is Claude's native resume question (isClaudeResumeCompactionQuestion), ComposerPendingUserInputPanel shows a dedicated prompt with Compact and continue, Keep full history and Don't ask again. Upstream shows the generic questionnaire here. The answers go through the same option-selection path, so the server-side mapping is unchanged.
  • Answering "Don't ask again" silences the banner on this device (localStorage, per environment and provider instance).

Slash menu

  • /compact (advertised by the server) is offered only as the whole message, with no attachments or contexts, on a thread that can compact. composer-logic.ts itself is unchanged; the filter lives in ChatComposer's menu items.

No server, contract or migration changes. The larger additions went into new files (ContextWindowMeter.logic.ts, contextCompaction.logic.ts, useResumeCompactionBanner.tsx, ClaudeResumeCompactionPrompt.tsx), and the edits to ChatView, ChatComposer and MessagesTimeline stay small and local.

Verification

  • vp test run on the new and touched tests: meter logic and render, compaction state, timeline rows, local-dispatch acknowledgement, resume prompt, settings form, changelog. All pass.
  • tsgo --noEmit -p apps/web, vp lint and vp fmt on the changed paths, and vp run check:avicode all pass.
  • No dev server or client pass has been done yet (see manual checks below).

Manual checks

  • On a Claude thread with conversation, hover the context meter and click Compact context. The divider should appear, and the draft should stay.
  • Try Compact context on a Codex thread.
  • Resume a Claude thread idle for over 70 minutes. Check the banner, and check the dedicated prompt when Claude asks.

Built by Claude Opus 5.5 in Claude Code.

🤖 Generated with Claude Code

TheDarkPhantom and others added 2 commits September 30, 2026 20:40
Web half of context compaction, on top of the server support from #252.

- The context meter gains a Compact context action that sends /compact on
  its own, leaving the draft and its attachments in the composer. It names
  the thread's model and marks Claude's auto-compact threshold.
- The timeline shows a compaction as a static divider, folds it with a
  finished turn's other work, and shows "Compacting context" with a static
  icon while it runs instead of the pulsing dots.
- A failed compaction or dropped queued message now acknowledges the send,
  so the composer no longer waits on a session change that never comes.
- Old Claude threads get the "Resume with less context" banner, and
  Claude's native resume dialog renders as a dedicated prompt with its
  three answers. "Don't ask again" silences the banner on this device.
- /compact appears in the slash menu only as a whole message on a thread
  that can compact.

Ported from pingdotgg#9293
Ported from pingdotgg#8144
Ported from pingdotgg#4772
Ported from pingdotgg#11103
Ported from pingdotgg#9623

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XL labels Sep 30, 2026
…on-web

# Conflicts:
#	CHANGELOG.md
#	apps/web/src/components/ChatView.logic.ts
#	apps/web/src/components/ChatView.tsx
@TheDarkPhantom
TheDarkPhantom merged commit f3872ce into main Sep 30, 2026
12 checks passed
@TheDarkPhantom
TheDarkPhantom deleted the feat/context-compaction-web branch September 30, 2026 13:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant