Compaction
本頁內容尚未翻譯。
Crystal does not reduce context. Before each model round, and again
before the post-turn compaction check, optional microcompaction may
replace old successful tool results with Tool result omitted after compaction. It does not call a model. The last protectTurns user
turns stay intact, then the newest protectTokens of older successful
results stay intact. Older successful results are replaced only when
the estimated size of the removed text is more than minimumTokens.
The placeholder that replaces them is not subtracted from that estimate.
User text, assistant text, and
failed results stay. The walk stops at the previous summary. The
archive, the screen, resume, fork, and export keep the original tool
text. A rewrite is saved on the model transcript. The following compact
decision then uses that transcript’s estimate, because the previous
provider usage still counts the removed text. Microcompaction is off
when microCompaction is omitted. /compact micro toggles it, and
on or off sets it, writes config.json, and does not summarize.
It is refused during a turn or compaction. /status adds a
Microcompaction row only while it is on. Defaults are 2 turns, 40000
protected tokens, and 20000 minimum tokens. protectTurns must be at
least 1. The token counts must be non-negative. Invalid values refuse
startup. Full compaction’s own prune does not follow this switch.
When estimated transcript size or the last model-round usage crosses the lesser of the configured fraction of the model context window and the usable window (context minus reserved output), the host:
- Clears old tool results outside a protected recent band of 2 user turns and 40000 tokens, when that frees more than 20000 tokens.
- Asks for one structured summary of older turns, folding any
previous summary, and keeps a recent tail verbatim. The tail is 25%
of the usable window, at least 2000 tokens and at most 32000. That
summary request follows the same
retrypolicy as a model round. The session model writes it unlesscompactionModelis enabled. The summary prompt reservesmin(session model maxTokens, 16384)tokens, and never more than half the effective summary window, so a window smaller than 16384 can still be summarized. A model withoutmaxTokensreserves 16384 when the window is large enough. A summary whose finish reason islengthis not stored. - Stops if the summary request itself cannot fit or the summarizer returns nothing and prune did not help. The turn does not retry compaction in a loop.
CTX percent uses the last model round’s provider usage while a round is
streaming, then a local transcript estimate after each tool batch until the
next round reports. It is not the sum of rounds in
the turn. The status bar can show 100% when usage meets or exceeds the
window. Compaction does not block the session loop: the progress row
stays on Compacting and the composer remains usable.
/compact (alias /summarize) runs immediately and does not wait for
the threshold. When the retained tail already holds every turn, it still
summarizes everything before the latest user turn. A session with nothing
before that turn prints Nothing earlier to compact. It is refused while
a turn is running. /compact model and /compact thinking show or set
the optional summarizer and its gear. /compact summary toggles
showCompactionSummary, and /compact auto (alias automatic) toggles
showAutomaticCompactionSummary. /compact micro toggles microcompaction.
Any of those commands accepts on or off, writes config.json, and does
not summarize. Any other argument is rejected.
compactionModel in config.json is enabled, provider, model,
and optional thinkingEffort. An omitted object means off, and
enabled: false keeps a stored provider, model, and gear unused.
While off, the summary request uses the session client and omits
reasoning. While on, the host opens a separate client and maps that
model’s gear the same way as the approval model: no thinking omits
reasoning, off disables it when the model allows that, and default
or an unsupported gear uses the provider default without changing the
saved gear. Changing the session model does not replace that client.
A side question that must summarize first opens its own compaction
client and releases it; the answer still uses the session model.
The trigger, retained tail, and CTX percent stay on the session
window. The summary prompt budget is the smaller of that window and
the compaction model’s declared window. A summary that cannot fit
takes the existing path that does not write one. /status adds a
Compaction model row only while the switch is on.
crystal, crystal space, and crystal run accept
--compaction-model on|off, --compaction-provider,
--compaction-model-id, and --compaction-thinking for one process.
Those flags are not written to config.json. on needs a saved
selection or a provider and model id on the same command.
User and assistant text in the folded head are replaced
by the summary; they are not kept beside it. The screen keeps the earlier
lines. When showCompactionSummary is on (the default; omitted from
config.json when on, false when off), a manual /compact prints the
stored summary under those lines in a rounded panel titled Earlier context.
Automatic compaction prints Compacted context only, unless
showAutomaticCompactionSummary is on. That switch defaults off, is omitted
from config.json until enabled, and uses the same panel. It does not change
/compact itself. A compaction with no summary text does not print one. A side
question that summarizes a private copy does not print it.
Sessions are written to ~/.crystal/sessions/<id>.json after each
completed turn, after a successful /compact, and on an orderly exit
when the transcript has a user message or a compaction summary. The
file stores the compacted model transcript (live system prompt, one
summary, recent tail, and reasoning items with their readable text and
opaque provider state), the last usage snapshot, and cumulative provider usage.
crystal --resume (-r) opens a terminal selector for this workspace.
crystal --resume <id> loads that file and stays in the process workspace.
crystal --resume <path> lists that directory, asks for trust before the
selector, and enters the directory after a session is chosen. Escape leaves
the process workspace unchanged. crystal --resume all lists every workspace,
shows each path, and enters the chosen session’s workspace after trust.
--workspace and --resume <path> must name the same directory when both
are set. A missing or empty session exits without entering the TTY.
/resume, /resume <path>, and /resume all use the same rules inside a
running session. /resume <id> restores that transcript and stays in the
current workspace. The word all is reserved. A value that is both an
existing directory and a session id is rejected. After a workspace change,
the live system prompt is refreshed from that directory’s Plan/Work text;
the summary and tail are kept. The selector lists resumable sessions newest
first by update time, supports typing to filter by id, preview, or workspace
path, and leaves the current session untouched on Escape. Usage is restored
so the status bar, /status, and the next compact decision
have a baseline. Sessions saved before cumulative usage was introduced retain
an unknown cumulative value rather than treating their last request as the
whole session. /clear starts a new id.
/sessions lists resumable sessions for the current workspace in descending
update order; /sessions all includes every workspace. The current id is
marked and every row keeps the complete id for use with /resume <id> or
/fork <id>. Empty and unreadable session files are omitted.
/fork first persists the current conversation, copies its transcript,
compaction summary, todos, mode, counters, and usage baseline to a new id, and
continues on that id. The source snapshot remains available under its original
id and is not overwritten by the branch. /fork <id> branches a saved session
instead. A branch uses the current workspace and a refreshed live system
prompt. Forking stops a running turn before taking the snapshot; listing
sessions does not.