* fix(ai-chat): strip unclosed <summary> tag leaking into compaction summary
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(ai-chat): strip analysis before matching summary to avoid scratchpad leak
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* feat(ai-chat): summary-based conversation compaction
Replace drop-oldest compaction with summary-based partial compaction: when
a send would cross the context-window trigger, summarize the older prefix
into one message and keep the recent tail verbatim, replacing the prefix in
both the model context and the visible transcript with a collapsible
boundary. Drop-oldest remains a fallback; a circuit breaker disables the
summary round-trip after repeated failures.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* nit
* fix(ai-chat): address review findings on summary compaction
- Stop during an in-flight summary no longer falls through to a destructive
drop-oldest compaction. The aborted controller short-circuits the fallback
and its save, so the cancel path rolls the unsent turn back cleanly instead
of permanently dropping older history (P1).
- Preserve the original chat title across compaction: once the summary
boundary leads the transcript, reuse the title computed before compaction
rather than re-deriving it from the first surviving tail message (P2).
- Strip every <analysis> block from the model's summary, not just the first,
so extra scratchpad blocks can't leak into context (P2).
- Reindent AIChatMessage.svelte / ContextUsageIndicator.svelte (prettier).
Adds regression tests for the abort path, title preservation, and
multi-analysis stripping.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* nit
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>