refactor(memory): unify structured consolidation flow

This commit is contained in:
chengyongru
2026-08-19 18:40:20 +08:00
committed by chengyongru
parent d4de0e4e3d
commit 16be6b0f36
14 changed files with 257 additions and 340 deletions
+16 -12
View File
@@ -258,7 +258,7 @@ class TestCmdNewUnifiedSession:
previous_file_state.record_read(tracked_file)
loop = SimpleNamespace(
sessions=sessions,
consolidator=SimpleNamespace(archive=AsyncMock(return_value=True)),
consolidator=SimpleNamespace(archive_session=AsyncMock(return_value=True)),
_cancel_active_tasks=AsyncMock(return_value=0),
discard_session_file_state=file_state_store.discard,
llm_runtime=MagicMock(return_value=MagicMock()),
@@ -288,10 +288,14 @@ class TestCmdNewUnifiedSession:
reset_file_state = file_state_store.for_session("unified:default")
assert reset_file_state is not previous_file_state
assert reset_file_state.is_unchanged(tracked_file) is False
loop.consolidator.archive.assert_called_once_with(
expected_snapshot,
archived = loop.consolidator.archive_session.call_args.args[0]
assert archived.key == "unified:default"
assert archived.messages == expected_snapshot
assert archived.last_consolidated == 0
loop.consolidator.archive_session.assert_called_once_with(
archived,
archive_end=len(expected_snapshot),
runtime=admitted_runtime,
session_key="unified:default",
)
loop.llm_runtime.assert_not_called()
@@ -310,7 +314,7 @@ class TestCmdNewUnifiedSession:
loop = SimpleNamespace(
sessions=sessions,
consolidator=SimpleNamespace(archive=AsyncMock(return_value=True)),
consolidator=SimpleNamespace(archive_session=AsyncMock(return_value=True)),
_cancel_active_tasks=AsyncMock(return_value=0),
discard_session_file_state=MagicMock(),
runtime_for_session=MagicMock(return_value=MagicMock()),
@@ -356,7 +360,7 @@ class TestConsolidationUnaffectedByUnifiedSession:
build_messages=MagicMock(return_value=[]),
get_tool_definitions=MagicMock(return_value=[]),
)
consolidator.archive = AsyncMock()
consolidator.archive_session = AsyncMock()
session = Session(key="unified:default")
session.messages = []
@@ -364,11 +368,11 @@ class TestConsolidationUnaffectedByUnifiedSession:
await consolidator.maybe_consolidate_by_tokens(session, runtime=runtime)
consolidator.archive.assert_not_called()
consolidator.archive_session.assert_not_called()
@pytest.mark.asyncio
async def test_consolidation_behaviour_identical_for_any_key(self):
"""archive call count is the same for 'telegram:123' and 'unified:default'
"""Archive call count is the same for 'telegram:123' and 'unified:default'
under identical token conditions."""
from nanobot.agent.memory import Consolidator, MemoryStore
@@ -392,12 +396,12 @@ class TestConsolidationUnaffectedByUnifiedSession:
session.messages = [] # empty → exits immediately for both keys
sessions.get_or_create.return_value = session
consolidator.archive = AsyncMock()
consolidator.archive_session = AsyncMock()
await consolidator.maybe_consolidate_by_tokens(
session,
runtime=runtime,
)
archive_calls[key] = consolidator.archive.call_count
archive_calls[key] = consolidator.archive_session.call_count
assert archive_calls["telegram:123"] == archive_calls["unified:default"] == 0
@@ -427,7 +431,7 @@ class TestConsolidationUnaffectedByUnifiedSession:
consolidator.estimate_session_prompt_tokens = MagicMock(return_value=(950, "tiktoken"))
# No valid boundary found → returns gracefully without archiving
consolidator.pick_consolidation_boundary = MagicMock(return_value=None)
consolidator.archive = AsyncMock()
consolidator.archive_session = AsyncMock()
await consolidator.maybe_consolidate_by_tokens(session, runtime=runtime)
@@ -437,7 +441,7 @@ class TestConsolidationUnaffectedByUnifiedSession:
runtime=runtime,
)
# but archive was not called (no valid boundary)
consolidator.archive.assert_not_called()
consolidator.archive_session.assert_not_called()
# ---------------------------------------------------------------------------