Context compaction for long-running agents — manual, auto, and the agent asking for it itself (v0.32.0) Loomcycle v0.32.0 introduces context compaction for long-running agents, offering manual, automatic, and self-triggered summarization to prevent context window overflow. The update includes a compact button, auto-compaction based on token usage, and a new tool for agents to request compaction themselves, with per-agent settings and spawn inheritance. Yesterday's v0.26→v0.29 interactive terminal made it possible to drive a loomcycle agent for hours from the Web UI — close the tab, come back, the run is still alive. The natural next problem: a multi-hour conversation eventually crowds the model's context window. v0.32.0 ships the answer as three coordinated triggers around one shared summarizer. Manual: a one-click Compact button in the run terminal header that calls POST /v1/runs/{run id}/compact scope runs:create , gated to a safe boundary — a live interactive run must be parked at awaiting input, mid-turn returns 409 the same iteration-boundary discipline F41 cooperative pause, the steering work's drainSteer, and snapshot all share . Auto: at the top of each iteration the loop checks the previous turn's context footprint against the per-agent autocompact at pct 50..95, off by default ; if crossed, the loop summarizes inline + replaces, debounced by a +1-iteration guard so the now-smaller request can't loop, and skipped when the window is unknown e.g. Ollama . Self: a new Context op=compact tool that sets the loop's compact-request flag, summarized at the next safe boundary — useful for a long autonomous run that filled its window without an operator watching. To make self-compact decisions conscious rather than guessed, Context op=self now reports a context object: {used tokens, max tokens, used pct} alongside the resolved compaction settings, so an agent can do "used pct = compaction.autocompact at pct → call op=compact now". used tokens is computed as input + cache read + cache creation the same true-prompt-footprint formula the v0.29.0 gauge uses, not just input tokens which undercounts under prompt caching . Per-agent settings enabled, target percentage 10..50, keep last n, keep first, autocompact at pct 50..95, model — a cheaper same-provider summary model for cost round-trip through every AgentDef mirror mergedDef + applyOverlay + lookup.SubstrateAgentDef + content-identifying so a fork that changes a compaction field mints a new content sha256; omitempty + normalize-collapse ensures a no-compaction agent hashes byte-identical to pre-feature rows , and through per-run override on POST /v1/runs MergeCompaction is per-field . Spawn inheritance is the asymmetric design call: compaction settings flow DOWN the spawn tree unlike memory scopes / sampling, which are each agent's own — a parent that knows it needs aggressive compaction wants its fan-out children compacted too. Precedence: per-spawn override on Agent.spawn and Agent.parallel spawn parent's effective policy child def's own settings — parent-set wins, child def fills gaps the parent left unset, per-spawn override wins over both, all re-stamped on subCtx so grandchildren inherit recursively. The compacted form is keep-last-N + keep-first, not brutal drop-everything: a CompactionSplit helper snaps the cut to a clean user-turn boundary so a tool use/tool results pair is never split same provider-protocol discipline as the steering work . The pinned task survives verbatim keep first preserves the original instruction . The summary replaces the middle. The recent tail keep last n messages stays verbatim. One summarizer drives all three triggers — loop.Summarize is one-shot, no-tools, target-percentage-parameterized, shared by manual/auto/self; an earlier draft had a separate server.summarizeConversation for the manual path; 461 consolidated to one implementation so a future improvement lands once. Persisted EventContextCompaction marker with trigger/keep n/keep first/before/after; replayTranscript rebuilds the pinned + summary + last-N form on resume/crash-recovery/continuation, so the durable transcript captures the compacted shape the full transcript is retained — non-destructive audit ; OTEL adds a context.compaction span event. Plus the operator-side polish bundled into v0.32.0: a "Stop" button restyled white-on-dark-red so the destructive cancel reads at a glance, distinct from accent-colored primary actions, and a Claude-Desktop-style composer card for the terminal input rounded elevated card with footer row showing the live serving model name and "MCP N " count derived from mcp calls in the transcript . The clean-boundary discipline this is the third subsystem to insist on: cooperative pause F41/RFC X , mid-run steering drainSteer top-of-iteration, never between tool use and tool results , and now compaction. The LLM message graph has structural constraints the runtime has to respect; the provider's protocol is part of the runtime's contract, not just the model's preference. Why this matters: long interactive sessions yesterday's interactive terminal stop dying at the context wall, autonomous long-running agents exp6 self-evolving with snapshot/resume stop hitting context-length-exceeded mid-task, fan-out orchestrators exp5 agent ensembles can let their sub-agents inherit the parent's compaction discipline. And the bit that took the most thinking to get right: the agent participates. Context op=self shows the gauge; the prompt instructs the agent to check it; Context op=compact lets the agent act. Compaction stops being something the runtime does to the agent and becomes something the agent does with the runtime.