Python: Fix compaction persistence, thresholds, and observability - #7912
Conversation
Preserve compaction summaries across chat middleware boundaries, keep destructive truncation behind its documented threshold, add structured INFO logs, and support preserving the first user group. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 726d66ea-6cff-4cb8-9090-8d919392271d
Python Test Coverage Report •
Python Unit Test Overview
|
|||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Pull request overview
Fixes Python compaction persistence across middleware, separates eviction/truncation thresholds, adds observability, and supports preserving the opening user group.
Changes:
- Synchronizes compaction summaries across middleware-backed model calls.
- Adds explicit threshold gates and optional first-user preservation.
- Emits structured compaction logs with regression coverage.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
_middleware.py |
Propagates linked summaries to durable history. |
_compaction.py |
Adds logging, threshold gates, and preservation support. |
test_clients.py |
Covers middleware and tool-loop persistence. |
test_compaction.py |
Covers logs, thresholds, and preservation. |
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
MAF Automated Review — Iteration 1
Result: Findings reported
Scope: full PR (1 commit(s)): 241ed4acac9d
Model: gpt-5.6-sol
Overview
The review found 3 verified inline finding(s).
Reviewed the supplied pull-request change set across correctness, security/reliability, architecture, and failure behavior.
3 verified findings remained after source verification (3 medium) across 2 files. Details are attached to the affected lines below.
Affected areas: python/packages/core/agent_framework/_compaction.py, python/packages/core/agent_framework/_middleware.py
Reconcile summaries at the middleware pipeline boundary, support sequence replacement and nested summaries, strengthen logging coverage, refresh threshold documentation, and warn when protected groups exceed the input budget. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 726d66ea-6cff-4cb8-9090-8d919392271d
Motivation & Context
Compaction can both mark existing messages as excluded and insert replacement summary messages. Those two mutations must remain together across every model call in a function-invocation loop. When chat middleware is present,
ChatMiddlewareLayeroperates on a copied message list; exclusions persist through sharedMessageobjects, but inserted summaries previously remained only in the copy. Later tool-loop iterations therefore lost both the original content and its replacement summary.The default context-window strategy also used
TokenBudgetComposedStrategyfor its 50% tool-eviction phase. That composer's strict fallback can exclude ordinary conversation groups when tool-result compaction cannot meet the budget, which made destructive truncation happen below the separately documented 80% truncation threshold.Finally, compaction had no positive operational signal when it changed context, and truncation had no opt-in way to retain the user's opening request.
Description & Review Guide
finallyso streaming, non-streaming, termination, and failure paths behave consistently.ContextWindowCompactionStrategywith explicit phase gates. Tool-result compaction may run abovetool_eviction_threshold; destructive truncation can run only when the post-eviction context still exceedstruncation_threshold.LogRecordreceivescompaction_phase,compaction_strategy, and before/after included message and token counts throughextra; message content is never logged. OpenTelemetry events and callbacks remain out of scope.preserve_first_user_group=FalsetoTruncationStrategyand surface the same opt-in onContextWindowCompactionStrategy. Existing behavior remains the default. If protected groups cannot fit within the actual input budget, the strategy preserves them and emits a structured warning with the remaining token count and input budget.ChatMiddlewareLayer: only summaries transitively linked to durable source messages should cross the middleware copy boundary, and middleware rewrites must remain call-local.preserve_first_user_group.Related Issue
Fixes #7744
Fixes #7224
Fixes #7216
There are no other open pull requests linked to these issues.
Contribution Checklist
breaking changelabel (or add "[BREAKING]" to the title prefix, before or after any language prefix) — a workflow keeps the label and title prefix in sync automatically.