Skip to content

fix(llm): keep earlier summaries when summarizing chat context again - #2701

Open
rosetta-livekit-bot[bot] wants to merge 1 commit into
mainfrom
rosary-fume-cooler
Open

rosetta-livekit-bot[bot] wants to merge 1 commit into
mainfrom
rosary-fume-cooler

Conversation

@rosetta-livekit-bot

@rosetta-livekit-bot rosetta-livekit-bot Bot commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Ports livekit/agents#7721 so repeated chat-context summarization preserves earlier summary messages instead of dropping them while rebuilding the context.

Adds the source regression scenario and a patch changeset for @livekit/agents.

Source diff coverage
  • livekit-agents/livekit/agents/llm/chat_context.py: adapted to agents/src/llm/chat_context.ts. The Python ChatMessage.extra["is_summary"] preservation check maps to the TypeScript item.extra?.is_summary representation.
  • tests/test_chat_ctx.py: adapted to agents/src/llm/chat_context.test.ts. The same prior-summary/resummarization scenario and assertions use Vitest, explicit timestamps for deterministic target ordering, and the target FakeLLM exact-input fixture.

No source files were omitted, and no additional infrastructure was required.

Testing

  • pnpm test agents/src/llm/chat_context.test.ts (94 passed)
  • pnpm build (42 packages built successfully)
  • pnpm test agents (3436 passed, 5 skipped, 6 failed in unrelated telemetry/STT tests; standalone rerun reduced this to 3 host-dependent loop_monitor.test.ts failures because this environment exposes process-level rather than thread-level CPU accounting)
  • pnpm lint (baseline failure across pre-existing files; no new lint finding in the added test or changed summarization block)
  • pnpm format:check (baseline failure across 45 pre-existing files; touched additions were formatted directly)

Source: livekit/agents#7721


Ported from livekit/agents#7721

Original PR description

Problem

ChatContext._summarize leaves an earlier summary out of the text it sends to the LLM, to avoid summaries of summaries. When it rebuilds the context, it also drops that earlier summary, because the summary is an assistant message and the rebuild loop discards every user and assistant message from the head. The comment above the loop says prior summaries are kept.

As a result, the second summarization of a context loses the first summary, and whatever it held, without ever passing it to the LLM. TaskGroup with summarize_chat_ctx=True calls _summarize, so a context that already holds a summary loses it there.

Change

Keep head messages marked is_summary when rebuilding the context. The new summary is added after them, before the tail.

Testing

test_summarize_keeps_prior_summary in tests/test_chat_ctx.py summarizes a context that already holds a summary and expects both the earlier and the new summary in the result.

  • Without the change to chat_context.py: uv run pytest --unit -q tests/test_chat_ctx.py gives 1 failed, 82 passed (assert 1 == 2).
  • With the change: 83 passed, 1 skipped. uv run pytest --unit -q tests/ -k "summar or task_group" gives 9 passed, 1 skipped.
  • ruff check and ruff format --check pass on the changed files.

Replaces #7522, which was closed before review.

@rosetta-livekit-bot
rosetta-livekit-bot Bot requested a review from a team as a code owner October 12, 2026 08:11
@changeset-bot

changeset-bot Bot commented Oct 12, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: a182a68

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 41 packages
Name Type
@livekit/agents Patch
@livekit/agents-plugin-anam Patch
@livekit/agents-plugin-anthropic Patch
@livekit/agents-plugin-assemblyai Patch
@livekit/agents-plugin-azure Patch
@livekit/agents-plugin-baseten Patch
@livekit/agents-plugin-bey Patch
@livekit/agents-plugin-cartesia Patch
@livekit/agents-plugin-cerebras Patch
@livekit/agents-plugin-deepgram Patch
@livekit/agents-plugin-did Patch
@livekit/agents-plugin-elevenlabs Patch
@livekit/agents-plugin-fishaudio Patch
@livekit/agents-plugin-google Patch
@livekit/agents-plugin-hume Patch
@livekit/agents-plugin-inworld Patch
@livekit/agents-plugin-krisp Patch
@livekit/agents-plugin-lemonslice Patch
@livekit/agents-plugin-liveavatar Patch
@livekit/agents-plugin-livekit Patch
@livekit/agents-plugin-meta Patch
@livekit/agents-plugin-minimax Patch
@livekit/agents-plugin-mistral Patch
@livekit/agents-plugin-mistralai Patch
@livekit/agents-plugin-neuphonic Patch
@livekit/agents-plugin-openai Patch
@livekit/agents-plugin-perplexity Patch
@livekit/agents-plugin-phonic Patch
@livekit/agents-plugin-protoface Patch
@livekit/agents-plugin-resemble Patch
@livekit/agents-plugin-rime Patch
@livekit/agents-plugin-runway Patch
@livekit/agents-plugin-sarvam Patch
@livekit/agents-plugin-silero Patch
@livekit/agents-plugin-soniox Patch
@livekit/agents-plugin-speechify Patch
@livekit/agents-plugin-synthesia Patch
@livekit/agents-plugin-tavus Patch
@livekit/agents-plugins-test Patch
@livekit/agents-plugin-trugen Patch
@livekit/agents-plugin-xai Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@rosetta-livekit-bot
rosetta-livekit-bot Bot requested a review from longcw October 12, 2026 08:11

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 potential issue.

Devin Review

}

if (it.type === 'function_call' || it.type === 'function_call_output') {
if (it.extra?.is_summary !== true) continue;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Repeated summaries exhaust the model context

After repeated task groups, _summarize retains every earlier summary and adds another. It excludes summaries from toSummarize, so later passes cannot compact them and the model eventually exceeds its context limit.

Learn more

Each call to _summarize replaces ordinary older messages with a new summary. The changed filter keeps all old summaries, while toSummarize excludes them from the next summarization request. TaskGroup calls this with keepLastTurns: 0 at completion, so repeated task groups add one summary each without ever compacting earlier ones. Those messages remain in the model input and can eventually exceed its finite context window.

Example: A session completes many task groups, each yielding a 200-token summary. Even when all raw messages have been compressed, 1,000 summaries alone occupy roughly 200,000 tokens instead of a bounded summary.

Recommended fix: Add a compaction strategy for older summaries, including their content in the new summary source before removing them, while retaining enough summary information to avoid losing earlier facts. Add a repeated-summarization test that checks both preservation of facts and bounded growth.

Devin Review


Was this helpful? React with 👍 or 👎 to provide feedback.

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.

0 participants