[FEATURE] Let the agent trigger /compact itself (agent-invokable compaction)

Status Open
Maintainer reply None cached
Activity 7 comments · opened Jun 27, 2026

Preflight Checklist

  • [x] I have searched existing requests and this feature hasn't been requested yet
  • [x] This is a single feature request (not multiple features)
Searched first. The closest existing issues are about adjacent things — #46086 (fine-grained compaction controls), #65114 (manual user-initiated /compact in Cowork), #70364 (/compact shouldn't block user flow), #71625 (blocking PreCompact hook). None of them is what this asks for: the agent itself initiating compaction. See Additional Context.

Problem Statement

When I work in a long-running interactive session, I frequently want to compact context at a moment of my choosing — a clean checkpoint before the agent starts a big new file, or when I can see context filling up. Today I can't get the agent to do this for me.

/compact is a harness-intercepted command, and it can only be triggered three ways:

  1. I manually type /compact myself.
  2. The harness auto-compacts when context fills (I don't control when).
  3. A driver injects it via the Agent SDK (query({ prompt: "/compact", options: { continue: true } })).

The asymmetry that bites me: the agent can already invoke my custom skills/commands autonomously — I can nudge it in natural language ("run my X command") and it does it. But it has no way to invoke /compact. So I can nudge the agent to run everything except compaction.

And the programmatic escape hatch (#3) only exists for SDK/driver-spawned sessions. In the two interactive surfaces I actually sit in front of, there is no way to inject /compact at a chosen point:

  • VS Code extension/compact only works typed in the UI prompt box; the vscode:// URI handler only pre-fills text (no auto-submit), and there's no external injection path.
  • TUI (claude)/compact only works typed at the interactive prompt; nothing lets an outside process inject input into a running session.

Net effect: in VS Code and the TUI I'm stuck manually typing /compact, and a long-running agent can never decide "this is a good point to compact" on its own.

Proposed Solution

Make compaction agent-invokable — the same way custom skills support autonomous invocation by Claude — so I can nudge the agent in natural language ("compact before the next file", "you're getting full, compact now") and it runs /compact itself. The model triggers it; the harness still does the actual summarization.

Ideal UX:

  • I type a plain-language nudge mid-task → the agent invokes compaction itself → I get the normal compact_boundary result and we keep going. No UI typing, no SDK driver required.
  • The agent could also optionally self-trigger at a sensible boundary in long autonomous runs.

Preferred shape: an agent-invokable compaction primitive — expose compaction as a built-in tool, or treat /compact as a skill the model can call autonomously. Cleanest fit with the existing "skills are autonomously invokable" model, and it fixes VS Code + TUI for free.

Alternative Solutions

Alternatives that would also solve it (any one):

  1. A controllable trigger — a setting/hook/command that lets the agent cause compaction rather than only react to it. (The existing PreCompact hook is reactive — it fires when compaction happens; it can't initiate it.)
  2. Interactive-surface parity — a documented way to inject /compact into a running VS Code-extension or TUI session from outside the process (e.g. claude compact --session <id>, or an extension command/IPC), matching what the SDK already allows for drivers.

Workarounds I currently use / have considered:

  • In SDK/driver-spawned sessions I inject /compact via query({ prompt: "/compact", options: { continue: true } }). This works, but it only helps headless/driver sessions — not the interactive VS Code or TUI sessions where I actually feel the context pressure.
  • Manually typing /compact at the right moment — but that defeats the point of a long autonomous run, and I can't always predict the right moment before context is already polluted.

Priority

Medium - Would be very helpful

Feature Category

Interactive mode (TUI)

Use Case Example

Concrete scenario:

  1. I'm deep into a long refactor across several files in the VS Code extension (or the TUI). Context is ~70% full.
  2. The agent is about to open a large file and start a big, self-contained new unit of work — a natural checkpoint where the earlier exploration is no longer needed verbatim.
  3. I type a plain-language nudge: "compact first, then start on the parser."
  4. With this feature: the agent invokes compaction itself, summarizing the now-stale earlier history, then proceeds into the parser work with a clean, focused context.
  5. Today: the agent can't do that. I have to stop, manually type /compact, wait, then re-issue the instruction — and in a long autonomous run I'm not even watching at the right moment, so it auto-compacts later at a worse boundary and loses the framing I cared about.

This would save time and produce better compactions, because the agent (which knows where the logical task boundaries are) gets to choose the compaction point instead of the human guessing or the harness firing blindly on a token threshold.

Additional Context

Verified current state (as of 2026-06, against official docs — SDK slash commands, How Claude Code Works, VS Code):

| Surface | Can /compact be injected programmatically / agent-triggered today? |
|---|---|
| Driver (Agent SDK query) | ✅ Yes — documented (prompt: "/compact", continue: true) |
| VS Code extension | ❌ No external injection; URI handler only pre-fills, doesn't submit |
| TUI (claude) | ❌ No documented input injection into a running session |
| Agent (model) self-invoke | ❌ Not possible — built-in /compact isn't autonomously invokable (unlike custom skills) |

Related but distinct existing issues (this one is specifically about the agent initiating compaction):

  • #46086 — Fine-grained compaction controls (partial / boundary-aware) — about how compaction behaves, not who can trigger it.
  • #65114 — Manual user-initiated /compact in Cowork — user-triggered, not agent-triggered.
  • #70364 — /compact should not block user flow — UX of the existing command.
  • #71625 — PreCompact hook: add blocking mode — reacts to compaction, doesn't initiate it.

View original on GitHub ↗

6 Comments

alexey-max-fedorov · 2 months ago

💯

teshy · 2 months ago

+1 with a concrete use case — your "clean checkpoint before the agent starts a big new file" framing is exactly a pattern we had to half-build externally.

I run Handoff, a three-tab Claude Code workflow (Haiku/Sonnet/Opus) where the driver tab auto-drains a queue of work orders grouped by topic ("tags"). We added a tag-boundary compact checkpoint: when the driver finishes one topic group and the next work order is a different topic, and context is high, it's supposed to compact before starting the new topic — a textbook clean checkpoint.

The wall is exactly the asymmetry you describe. We can detect the ideal compaction moment programmatically (topic boundary + high context), but the agent can't act on it — /compact is harness-only. So the best we can do is stop and ask the human to type /compact, then resume. For an autonomous queue that drains without a human watching, that means it either stalls at the boundary or sails past it into a mid-task auto-compact.

Agent-invokable compaction would let the driver compact at the boundary it already detects, turning our stop-and-ask into a genuine self-checkpoint — no human in the loop just to press the button.

Pairs with #18027 (the agent needs to see its context % to know when to self-compact). Visibility + agent-triggered compaction together close the loop for self-regulating multi-context workflows. Strong support for this one.

kcarriedo · 2 months ago

The asymmetry you described is something we kept running into while building a GTM polling runner that drives multiple Claude Code sessions. The context-sensitive compaction point (end of one work phase, before a new one starts) is exactly where auto-compact fires at the wrong moment -- typically in the middle of a structured output rather than at the clean boundary.

A few things that helped as workarounds while a native primitive doesn't exist:

  1. Driver-injected compaction via Agent SDK works for headless sessions, but as you note it is useless in the TUI or VS Code. What we did for interactive sessions: expose a custom skill (/check-context) that reads the session's approximate context fill from the JSONL transcript size and tells the human "now is a good time to /compact" -- but the human still has to type it. Not autonomous, just better-timed.
  1. For agents that run sequentially across well-defined phases, a workaround that doesn't require new primitives: structure each phase as a separate SDK session spawn. Compaction effectively becomes "end the session and start fresh." Costly for context re-establishment but avoids the harness-timing problem.

The ask for a built-in agent-invokable primitive is the right fix. The compact_boundary result shape already exists in the SDK path -- wiring an equivalent autonomous trigger that works in interactive surfaces closes the gap cleanly. The self-checkpoint-at-topic-boundary case from @teshy's comment is exactly the pattern that benefits most.

Worth also linking #18027 (context visibility) -- the self-compact use case requires both: visibility into "how full am I" and the ability to act on it. Neither alone closes the loop.

junaidtitan · 2 months ago

The friction you're describing is exactly the wall that keeps tripping up longer autonomous pipelines: the harness detects the right compaction moment, but the model has no primitive to act on it.

We approached this from a different angle in cozempic (github.com/Ruya-AI/cozempic): instead of making /compact agent-invokable, keep the session lean enough that compaction pressure never builds in the first place. The guard daemon (cozempic guard) monitors token load from the on-disk JSONL and auto-prunes + reloads at a configurable threshold — so the session always has headroom without a human typing /compact or the model needing to invoke it.

The honest limit: this is threshold-based, not topic-boundary aware. Your "compact before starting on the parser" use case, and @teshy's Handoff topic-boundary checkpoint, want a strategic compact at a chosen moment — a conceptual transition, not just a token count. Cozempic prunes by token load, which doesn't capture that. The agent-invokable primitive you're requesting is still the right native solution for strategic-boundary compaction. Also: the guard terminate-restarts Claude on prune, which works cleanly for CLI/headless sessions but is rougher in the VS Code extension during an active interactive turn.

Where it helps concretely: sessions that fill from pure accumulation (tool output buildup, research/monitor agents, queue runners) rather than task-phase structure — places where you just need headroom maintenance, not boundary detection. That's a real subset of the use case even if it misses the strategic-checkpoint piece.

If you're running headless or CLI pipelines hitting this today while the native primitive doesn't exist: pip install cozempic + cozempic guard is a working interim.

kotenbu135 · 1 month ago

Adding a use case that I think strengthens the "controllable trigger" alternative you listed.

Plan-mode exit as a deterministic compaction point

In a research → plan → implement workflow, plan approval is the sharpest checkpoint that exists. By the time the plan is finalized, most of the context is research-phase residue:

  • Files read exploratorily that turned out to be irrelevant
  • Failed Grep/Glob attempts
  • Rejected design alternatives and the discussion around them
  • Build/test output

What the implementation phase actually needs is just the approved plan and the current contents of the files being edited.

The gap today

The plan-approval exit prompt already offers context handling, but only as a binary:

1. Yes, clear context (69% used) and bypass permissions
2. Yes, and bypass permissions
3. Yes, manually approve edits

Option 1 (clear) drops everything not written into the plan file — #18599 documents this breaking later phases when skill-derived execution procedures don't survive in the plan itself. Option 2 (keep everything) means starting the most context-hungry phase — the edit/test/fix loop — with the least headroom, and if auto-compact fires mid-implementation it degrades the plan by summarization.

There's no middle option: compact, preserving the plan verbatim.

Why this argues for a trigger primitive, not just self-judgment

Your issue frames this as the agent choosing its own compaction point. I'd note that "is now a good time to compact?" is a hard call to make introspectively — but plan-mode exit is an explicit state transition, so the trigger is deterministic. That makes it a good first target for the "controllable trigger" you list under Alternative Solutions (item 1): a hook that can initiate compaction, not just react to it like PreCompact.

Other candidates with the same property: completion of a TodoWrite item, or immediately after high-output commands (npm test, cargo build).

If compaction became agent-invokable as you propose, this would fall out naturally — the agent could invoke it on ExitPlanMode approval. A declarative form would also work:

{
  "planMode": {
    "exitContextStrategy": "compact",
    "preserveVerbatim": ["plan"]
  }
}

Workaround limits

Typing /compact manually after approval is the known practice, but approval flows straight into execution — there's effectively no window to interject. By the time you could type, implementation has already started. This is the same "I'm not watching at the right moment" problem you describe, but with a boundary that's actually machine-detectable.

Related: #18599 (proposes removing the clear-context option from the exit dialog — orthogonal to adding a compact path).

Coamithra · 1 month ago

Not covered yet: compaction as a scripted step in a skill/runbook, rather than an autonomous or nudge-triggered one.

This issue and #78165 both frame agent-invokable compaction as the model deciding when — a nudge ("compact before the parser") or a heuristic ("task boundary + above N%"). A third shape is simpler and deterministic: let a skill body call compaction as a step, like any other command.

My overseer agents fan work out to parallel subagents. The runbook is literally:

loop:
  take the top BATCH of tickets from the backlog
  dispatch each to its own subagent, in parallel
  review the merged result
  compact

Batching is what makes this bite. Each round dumps N subagents' plans, diffs, questions and review output at once, and once the batch is closed none of it is needed verbatim. Context fills in discrete jumps, and the gap between rounds is the only moment where nearly everything is discardable. The model doesn't need to infer that boundary — it's structural, and I already wrote it in the runbook. But compact is the one step I can't express, because it's harness-only. So the runbook either ends in "ask the human to type /compact", defeating an unattended overseer, or runs until auto-compact fires mid-round with N subagents in flight — the worst moment to summarize.

This is a weaker ask than model-initiated compaction and could ship independently: no context gauge (#18027), no threshold, no judgment about when. Just make compaction reachable from a skill/command body.

Any shape works: a Compact tool, /compact invocable via the Skill mechanism, or a !compact-style directive in command frontmatter/body.

And on "just /clear or start a new session": not equivalent for an overseer. Conventions already ruled on, and subagent instructions that kept needing the same correction, are worth carrying between batches; N sets of plans, diffs and review transcripts are not. /clear drops both, so the next batch relitigates what the last one settled — and it puts a human back in the loop.

Showing cached comments. Read the full discussion on GitHub ↗