Skip to content

fix(agent): assistant-attributed compaction summaries + hardened failure paths#48

Merged
urmzd merged 3 commits into
mainfrom
fix/summarize-compaction
Jul 12, 2026
Merged

fix(agent): assistant-attributed compaction summaries + hardened failure paths#48
urmzd merged 3 commits into
mainfrom
fix/summarize-compaction

Conversation

@urmzd

@urmzd urmzd commented Jul 11, 2026

Copy link
Copy Markdown
Owner

Summary

  • Summary attribution: both compaction paths (SummarizeCompactor and tree.Compact) now emit a user-request + assistant-summary pair instead of a single user message. The summary text is model-generated, so it belongs on an assistant turn; the synthetic user turn (types.SummaryRequestText) precedes it because some providers reject histories whose first non-system message is from the assistant (no prefill support). Adds a types.NewAssistantMessage constructor.
  • Compaction thrash fix: a previous summary pair no longer counts toward the summarize threshold, and summarization is skipped before the LLM call when it cannot shrink history (fewer than 3 summarizable messages). Previously a freshly compacted history (1 + 2 + KeepLast messages) sat just below the trigger and re-fired a summarization LLM call on nearly every turn.
  • Mid-stream failure hardening: both paths drained provider streams collecting only text and ignored ErrorDelta, so a rate limit arriving after stream-open could silently replace real history with a truncated/empty summary. SummarizeCompactor now falls back to full history on mid-stream error or empty summary; tree.Compact returns an error and leaves the original branch active and intact.
  • Tests: six new tests covering pair exclusion (asserts zero provider calls), unprofitable-summary skip, mid-stream error fallback, and empty-summary fallback in both paths; existing fixtures extended so they genuinely reach the code paths they claim to exercise.

Test plan

  • go build ./..., go vet ./..., go test ./... — all packages green
  • go test -count=1 ./agent/... — integration tests fresh, no cache
  • just validate — live validation harness, all 8 scenarios PASS against a real model (report regenerated in this PR)
  • Live end-to-end drive against OpenAI: compaction produces the pair shape, recall works across two summary generations, consecutive assistant turns accepted
  • Live failure injection (quota-exhausted Gemini key, real mid-stream 429): compactor leaves history unchanged; tree.Compact errors with main intact
  • CI passes

urmzd added 3 commits July 11, 2026 13:37
…n failure paths

Summaries are model-generated, so both compaction paths now emit a
user-request + assistant-summary pair instead of a single user message
(the synthetic user turn keeps providers without prefill support happy).

Also fixes two issues surfaced while verifying the change live:

- Compaction thrash: a previous summary pair no longer counts toward the
  summarize threshold, and summarization is skipped up front when it
  cannot shrink history — previously a compacted history sat just below
  the trigger and re-fired an LLM call on nearly every turn.
- Mid-stream failures: both SummarizeCompactor and tree.Compact drained
  provider streams collecting only text, ignoring ErrorDelta. A rate
  limit after stream-open could silently replace real history with a
  truncated or empty summary. The compactor now falls back to full
  history; tree.Compact returns an error and leaves the branch intact.

Verified end to end against live OpenAI (compaction shape, recall across
two summary generations, consecutive-assistant acceptance) and a live
429-ing provider (fallbacks hold).
Resolved conflict in agent/tree/compact.go: main moved compaction node
creation into a single WAL transaction; the summary request node now
joins the summary node in that transaction's newNodes list.
golangci-lint's gocyclo flagged (*Tree).Compact at complexity 33 (> 30).
Move shared-node collection and provider summarization into
sharedNodesUnlocked and summarizeMessages with no behavior change.
@urmzd urmzd merged commit 820bc8a into main Jul 12, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant