From 3c702d8525eb6c9839aed613e6d0b67d87d4571a Mon Sep 17 00:00:00 2001 From: Diego Colombo Date: Thu, 12 Feb 2026 22:15:09 +0000 Subject: [PATCH 1/2] docs: add metadata field to context compaction event payloads MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Include the optional `metadata: dict | null` property bag in context manager event emissions: - Added metadata to context:pre_compact and context:post_compact examples - Added context:compaction to the standard events list - Documented the metadata property bag pattern for extensibility - Updated the validation checklist to reference metadata This ensures module authors know to include metadata in their event payloads, enabling implementation-specific data (strategy variant, trigger reason, etc.) without breaking the contract. 🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier) Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com> --- docs/contracts/CONTEXT_CONTRACT.md | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/docs/contracts/CONTEXT_CONTRACT.md b/docs/contracts/CONTEXT_CONTRACT.md index b3fe704..23638fd 100644 --- a/docs/contracts/CONTEXT_CONTRACT.md +++ b/docs/contracts/CONTEXT_CONTRACT.md @@ -373,7 +373,8 @@ async def _compact_internal(self) -> None: # Emit pre-compaction event await self._hooks.emit("context:pre_compact", { "message_count": len(self._messages), - "token_count": self._token_count + "token_count": self._token_count, + "metadata": None, # Optional dict for implementation-specific data }) # Build tool_call_id -> tool_use index map @@ -415,7 +416,8 @@ async def _compact_internal(self) -> None: # Emit post-compaction event await self._hooks.emit("context:post_compact", { "message_count": len(self._messages), - "token_count": self._token_count + "token_count": self._token_count, + "metadata": None, # Optional dict for implementation-specific data }) ``` @@ -496,8 +498,14 @@ coordinator.register_contributor( ``` Standard events to emit: -- `context:pre_compact` - Before compaction (include message_count, token_count) -- `context:post_compact` - After compaction (include new counts) +- `context:pre_compact` - Before compaction (include message_count, token_count, metadata) +- `context:post_compact` - After compaction (include new counts, metadata) +- `context:compaction` - After compaction with strategy details (include before/after stats, metadata) + +All context events should include an optional `metadata: dict | null` field as an +extensible property bag for implementation-specific data (e.g., compaction strategy +variant, trigger reason, context manager configuration). Consumers that don't need +metadata ignore it. Set to `null` when no implementation-specific data is available. See [CONTRIBUTION_CHANNELS.md](../specs/CONTRIBUTION_CHANNELS.md) for the pattern. @@ -530,7 +538,7 @@ Additional examples: ### Recommended - [ ] Token counting for accurate compaction triggers -- [ ] Emits context:pre_compact and context:post_compact events +- [ ] Emits context:pre_compact and context:post_compact events with metadata field - [ ] Preserves system messages during compaction - [ ] Thread-safe for concurrent access - [ ] Configurable thresholds From 7c7d1288faaabf66205062f8812f6a8a92d1a71b Mon Sep 17 00:00:00 2001 From: Diego Colombo Date: Fri, 13 Feb 2026 20:26:19 +0000 Subject: [PATCH 2/2] docs: show populated metadata exemplar in compaction event examples MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier) Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com> --- docs/contracts/CONTEXT_CONTRACT.md | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/docs/contracts/CONTEXT_CONTRACT.md b/docs/contracts/CONTEXT_CONTRACT.md index 23638fd..bb21dbf 100644 --- a/docs/contracts/CONTEXT_CONTRACT.md +++ b/docs/contracts/CONTEXT_CONTRACT.md @@ -374,7 +374,7 @@ async def _compact_internal(self) -> None: await self._hooks.emit("context:pre_compact", { "message_count": len(self._messages), "token_count": self._token_count, - "metadata": None, # Optional dict for implementation-specific data + "metadata": {"strategy": "sliding_window", "trigger": "token_limit", "budget": 195000}, }) # Build tool_call_id -> tool_use index map @@ -409,15 +409,26 @@ async def _compact_internal(self) -> None: break recent_messages = self._messages[recent_start:] - + messages_removed = len(self._messages) - len(recent_messages) self._messages = system_messages + recent_messages self._token_count = sum(self._estimate_tokens(m) for m in self._messages) + # Emit compaction event + await self._hooks.emit("context:compaction", { + "message_count": len(self._messages), + "token_count": self._token_count, + "metadata": { + "compaction_trigger": "token-budget-exceeded", + "strategy": "budget", + "messages_removed": messages_removed, + }, + }) + # Emit post-compaction event await self._hooks.emit("context:post_compact", { "message_count": len(self._messages), "token_count": self._token_count, - "metadata": None, # Optional dict for implementation-specific data + "metadata": {"budget_remaining": 97500, "storage_quota_pct": 0.42}, }) ```