formatCompactionReport function
- AutoCompactorPass pass, {
- required bool auto,
- bool details = false,
Auto/manual compaction run methods (moved from agent_cli.dart under the
repo's 2800-line size gate). Same library, so private state is in scope.
Formats the in-chat compaction report block (issue #276): tokens
before → after, freed count/percent, WHICH ENGINE did the summarizing
(the smol/main role — review major 3: a report that doesn't name
the engine can't be judged), how many records were hidden vs
summarized, and — when the pass actually wrote summary text — the
summary in a fenced block so the user can eyeball — and copy — what
the transcript was condensed to. A pass with no summary text (all
evictions went to hide, or the model returned blank — issue #578)
omits the block: an empty ```-fence says nothing and reads as a bug.
Pure; _AgentCliCompactionReportPrinter.print renders it.
gh-1636: the internal checkpoint text is debug output, not
conversation. By default (details false) the report is ONE short
marker line — auto-compacted · ENGINE: N → M tokens (F freed · P%); the records: line and the fenced summary only render with
details: true (the tui.showCompactionDetails opt-in, or the
manual /compact — the on-demand expansion). The summary itself is
never lost: it stays in the session file, reachable via
compact_expand.
Implementation
/// Formats the in-chat compaction report block (issue #276): tokens
/// before → after, freed count/percent, WHICH ENGINE did the summarizing
/// (the `smol`/`main` role — review major 3: a report that doesn't name
/// the engine can't be judged), how many records were hidden vs
/// summarized, and — when the pass actually wrote summary text — the
/// summary in a fenced block so the user can eyeball — and copy — what
/// the transcript was condensed to. A pass with no summary text (all
/// evictions went to hide, or the model returned blank — issue #578)
/// omits the block: an empty ```-fence says nothing and reads as a bug.
/// Pure; [_AgentCliCompactionReportPrinter.print] renders it.
///
/// gh-1636: the internal checkpoint text is debug output, not
/// conversation. By default ([details] false) the report is ONE short
/// marker line — `auto-compacted · ENGINE: N → M tokens (F freed ·
/// P%)`; the `records:` line and the fenced summary only render with
/// `details: true` (the `tui.showCompactionDetails` opt-in, or the
/// manual `/compact` — the on-demand expansion). The summary itself is
/// never lost: it stays in the session file, reachable via
/// `compact_expand`.
List<String> formatCompactionReport(
AutoCompactorPass pass, {
required bool auto,
bool details = false,
}) {
final freedRaw = pass.tokensBefore - pass.tokensAfter;
// A restamped estimator can report a slightly larger after-count (same
// clamp as onDone's HEP end frame): "-30 freed" reads as a bug.
final freed = freedRaw < 0 ? 0 : freedRaw;
final pct = pass.tokensBefore == 0
? 0
: (freed * 100 / pass.tokensBefore).round();
final engine = pass.fallback == null ? '' : ' · ${pass.fallback}';
final passSuffix = pass.pass == 1 ? '' : ' · pass ${pass.pass}';
final header = '${auto ? 'auto-compacted' : 'compacted'}$engine$passSuffix';
// gh-1636: the default report — one line, no checkpoint text.
if (!details) {
return [
'$header: ${pass.tokensBefore} → ${pass.tokensAfter} tokens '
'($freed freed · $pct%)',
];
}
final summary = pass.summary?.trim();
return [
header,
'tokens: ${pass.tokensBefore} → ${pass.tokensAfter} '
'($freed freed · $pct%)',
// Issue #673 AC3: the local-trim valve frees tokens WITHOUT hiding
// session records or folding a summary — a bare "0 hidden · 0
// summarized" next to a big freed count cannot describe a real
// compaction. Name the in-memory drop so the line is truthful for
// BOTH engines.
if (pass.droppedMessages > 0)
'records: ${pass.droppedMessages} dropped (in-memory) · '
'${pass.hiddenRecords} hidden · '
'${pass.summarizedMessages} summarized'
else
'records: ${pass.hiddenRecords} hidden · '
'${pass.summarizedMessages} summarized',
if (summary != null && summary.isNotEmpty) ...[
'summary:',
'```',
_balanceSummaryFences(summary),
'```',
],
];
}