mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-08 03:01:47 +00:00
fix(compression): preserve iterative summary continuity
This commit is contained in:
parent
f8a6db68ca
commit
4a3e3e20e5
2 changed files with 105 additions and 5 deletions
67
tests/agent/test_context_compressor_summary_continuity.py
Normal file
67
tests/agent/test_context_compressor_summary_continuity.py
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
"""Regression tests for iterative context-summary continuity."""
|
||||
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from agent.context_compressor import ContextCompressor, SUMMARY_PREFIX
|
||||
|
||||
|
||||
def _compressor() -> ContextCompressor:
|
||||
with patch("agent.context_compressor.get_model_context_length", return_value=100000):
|
||||
return ContextCompressor(
|
||||
model="test/model",
|
||||
threshold_percent=0.85,
|
||||
protect_first_n=1,
|
||||
protect_last_n=1,
|
||||
quiet_mode=True,
|
||||
)
|
||||
|
||||
|
||||
def _response(content: str):
|
||||
mock_response = MagicMock()
|
||||
mock_response.choices = [MagicMock()]
|
||||
mock_response.choices[0].message.content = content
|
||||
return mock_response
|
||||
|
||||
|
||||
def _messages_with_handoff(summary_body: str):
|
||||
return [
|
||||
{"role": "system", "content": "system prompt"},
|
||||
{"role": "user", "content": f"{SUMMARY_PREFIX}\n{summary_body}"},
|
||||
{"role": "user", "content": "new user turn after resume"},
|
||||
{"role": "assistant", "content": "new assistant work after resume"},
|
||||
{"role": "user", "content": "more new work after resume"},
|
||||
{"role": "assistant", "content": "latest tail response"},
|
||||
]
|
||||
|
||||
|
||||
def test_existing_previous_summary_is_not_serialized_again_as_new_turn():
|
||||
"""Same-process iterative compression should not feed the old handoff twice."""
|
||||
compressor = _compressor()
|
||||
old_summary = "OLD-SUMMARY-BODY unique continuity facts"
|
||||
compressor._previous_summary = old_summary
|
||||
|
||||
with patch("agent.context_compressor.call_llm", return_value=_response("updated summary")) as mock_call:
|
||||
compressor.compress(_messages_with_handoff(old_summary))
|
||||
|
||||
prompt = mock_call.call_args.kwargs["messages"][0]["content"]
|
||||
assert "PREVIOUS SUMMARY:" in prompt
|
||||
assert "NEW TURNS TO INCORPORATE:" in prompt
|
||||
assert prompt.count(old_summary) == 1
|
||||
assert f"[USER]: {SUMMARY_PREFIX}" not in prompt
|
||||
|
||||
|
||||
def test_resume_rehydrates_previous_summary_from_handoff_message():
|
||||
"""After restart/resume, the persisted handoff should regain summary identity."""
|
||||
compressor = _compressor()
|
||||
old_summary = "RESUMED-SUMMARY-BODY durable continuity facts"
|
||||
assert compressor._previous_summary is None
|
||||
|
||||
with patch("agent.context_compressor.call_llm", return_value=_response("updated summary")) as mock_call:
|
||||
compressor.compress(_messages_with_handoff(old_summary))
|
||||
|
||||
prompt = mock_call.call_args.kwargs["messages"][0]["content"]
|
||||
assert "PREVIOUS SUMMARY:" in prompt
|
||||
assert "NEW TURNS TO INCORPORATE:" in prompt
|
||||
assert "TURNS TO SUMMARIZE:" not in prompt
|
||||
assert prompt.count(old_summary) == 1
|
||||
assert f"[USER]: {SUMMARY_PREFIX}" not in prompt
|
||||
Loading…
Add table
Add a link
Reference in a new issue