v0.26.0
Added
-
CompactionObserver— tell the client when history was compacted.
Compaction is deliberately invisible upstream: it runs inside
before_model_request, mutates the message list, and emits nothing. Right
for the model, wrong for a person watching a long run, who sees earlier turns
quietly stop informing the answers with no explanation. Wrapping the capability
is the seam for saying so:capabilities=[CompactionObserver(SlidingWindow(max_messages=80, keep_messages=40))]
Opt-in by construction — pass the strategy unwrapped and nothing is emitted.
- The compaction itself is untouched.
CompactionObserversubclasses
pydantic-ai'sWrapperCapabilityand overrides one hook, so ordering,
deferral and hook introspection all delegate to the wrapped capability.
A hand-rolled proxy would have silently dropped those. - The wire stays vanilla AG-UI. Each firing emits a standard
ACTIVITY_SNAPSHOTwithactivityType: "compaction"(exported as
COMPACTION_ACTIVITY_TYPE) andcontentcarryingremoved/before/
after— not aCUSTOMevent, so any AG-UI client can render it and ours
is not privileged. Handle it with@ag-ui/client's
onActivitySnapshotEvent. - Placed where a reader wants it: interleaved immediately before the
events of the turn that ran with the shortened history, with a fresh
messageIdper firing — a compaction is a distinct occurrence, not a
mutation of a previous one. - What it does not detect, stated plainly: detection is a message-count
comparison across the wrapped call, because that is all the upstream
contract exposes. A strategy that rewrites history without shortening it
does not register — matching what the indicator claims (turns were dropped)
rather than over-promising a general "history changed" signal. - Per-run, not per-instance. The observer records into a
ContextVar. A
consumer builds the capability once at configuration time and the same
instance serves every request, so instance state would interleave concurrent
runs into each other's transcripts.
- The compaction itself is untouched.
Documentation
- New page: Compaction & skills — adopting the harness
compactionandSkillscapabilities through theCAPABILITIESseam (pure
composition, no code here), then the indicator above. Strategy-by-strategy
guidance lives in django-pydantic-agent's integrations guide, where the seam
itself is documented.