feat(a2a): durable history compression across A2A turns#66
Merged
Conversation
Implements issue #28. Adds HistoryCompressionHook to src/ant_ai/hooks/builtins/ that compresses older conversation history via LLM summarisation when a configurable threshold (max_messages and/or max_token_ratio) is exceeded, keeping the most recent keep_last messages verbatim. Also restructures the hooks namespace for consistency with the rest of the codebase: hooks/adapters/ is split into hooks/builtins/ (first-party, mirrors tools/builtins/) and hooks/integrations/ (third-party wrappers, mirrors observer/integrations/). Adds name: str = "hook" to AgentHook protocol so all hooks expose an identifier. Closes #28
Persists the compressed baseline as a synthetic checkpoint message in A2A task history so future turns restore it instead of replaying the full BFS chain, keeping LLM message counts bounded long-term. Also fixes ClassVar annotations on AgentHook.name and HistoryCompressionHook.name so Pydantic no longer treats them as fields.
pytest rootdir-based imports don't need __init__.py and having them causes ModuleNotFoundError when parent directories lack them.
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
Consistent with the same fix applied to AgentHook and HistoryCompressionHook — instance variable cannot override a ClassVar.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
compression.pywith checkpoint find/persist helpers that serialise the compressed message baseline into A2A task history as a synthetic metadata messageA2AExecutornow restores the most-recent checkpoint on each turn via_build_history, keeping LLM message counts bounded long-term instead of growing with every turnState._compression_context(private attr) is populated byHistoryCompressionHookafter compression fires so the executor can persist itClassVarannotations onAgentHook.nameandHistoryCompressionHook.nameso Pydantic does not treat them as model fieldsTest plan
tests/unit/hooks/test_history_compression.py— new unit tests verify_compression_contextis set/unset correctlytests/unit/memory/test_react_loop_memory.py— new tests verify memory-triggered compression andmemory.update()still receives correct messagestests/integration/a2a/test_history.py— new integration tests verify message count stays bounded over 4 and 8 turnstests/integration/hooks/test_compression_agent.py— new integration test suite for compression hook behaviour end-to-end