Files
Eduard van Valkenburg f970a699d8 Python: Fix compaction message-id collisions and tool-loop summary persistence (#6299)
* Fix compaction message-id collisions and tool-loop summary persistence

Fixes two bugs in the compaction strategies:

- #5237: incremental group annotation assigned message ids by position
  within the re-annotated slice, so moving the re-annotation start back to
  a previous group start restarted ids at 0 and produced collisions
  (e.g. a user message reusing an assistant message's id), merging groups
  and causing tool-result compaction to wrongly exclude messages.
  group_messages/_ensure_message_ids now take an id_offset and guard
  against existing-id collisions; annotate_message_groups threads the
  slice start index through as the offset.

- #4991: the function-invocation loop copied the message list each
  iteration, so summaries inserted by compaction landed in a throwaway
  copy and were lost across tool-loop iterations (only the persistent
  excluded flags survived). _prepare_messages_for_model_call now compacts
  the list in place when messages is a list, so inserted summaries persist.

Adds regression tests (incremental id uniqueness, existing-id collision
avoidance, idempotency, and tool-loop summary persistence including
streaming and conversation-id modes).

Also adds a summarization.py sample demonstrating SummarizationStrategy
directly with a real client, and reworks advanced.py with tool-call
groups and a real summarizer.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Guard incremental message-id assignment against prefix-id collisions

Addresses PR review on #5237: _ensure_message_ids only guarded against
collisions within the re-annotated slice. A preexisting (e.g. user-supplied)
id in the preserved prefix could still be reassigned in the suffix when the
id was numerically out of position, merging groups across the re-annotation
boundary again.

group_messages/_ensure_message_ids now accept reserved_ids, and
annotate_message_groups passes the preserved prefix's ids so auto-assigned
suffix ids never collide across the full list. Adds a regression test
reproducing the out-of-position prefix-id collision.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
f970a699d8 · 2026-06-04 08:37:59 +00:00
History
..

Context Compaction Samples

This folder demonstrates context compaction patterns introduced by ADR-0019.

Files

  • basics.py — builds a local message list and applies each built-in strategy one at a time.
  • summarization.py — runs SummarizationStrategy directly with a real summarizing chat client.
  • advanced.py — composes multiple strategies with TokenBudgetComposedStrategy, including a real summarizer and tool-call groups.
  • agent_client_overrides.py — shows client defaults, agent-level overrides, and per-run compaction overrides.
  • custom.py — defines a custom strategy implementing the CompactionStrategy protocol.
  • tiktoken_tokenizer.py — shows a TokenizerProtocol implementation backed by tiktoken.
  • compaction_provider.py — uses CompactionProvider with an agent and InMemoryHistoryProvider.

Run samples with:

uv run samples/02-agents/compaction/basics.py
uv run samples/02-agents/compaction/summarization.py  # requires OPENAI_API_KEY
uv run samples/02-agents/compaction/advanced.py  # requires OPENAI_API_KEY
uv run samples/02-agents/compaction/agent_client_overrides.py
uv run samples/02-agents/compaction/custom.py
uv run samples/02-agents/compaction/tiktoken_tokenizer.py
uv run samples/02-agents/compaction/compaction_provider.py  # requires OPENAI_API_KEY