feat: flush memory before summarization (#2176)
* feat: flush memory before summarization * fix: keep agent-scoped memory on summarization flush * fix: harden summarization hook plumbing * fix: address summarization review feedback * style: format memory middleware
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
import threading
|
||||
import time
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from deerflow.agents.memory.queue import ConversationContext, MemoryUpdateQueue
|
||||
@@ -89,3 +91,74 @@ def test_process_queue_forwards_reinforcement_flag_to_updater() -> None:
|
||||
correction_detected=False,
|
||||
reinforcement_detected=True,
|
||||
)
|
||||
|
||||
|
||||
def test_flush_nowait_cancels_existing_timer_and_starts_immediate_timer() -> None:
|
||||
queue = MemoryUpdateQueue()
|
||||
existing_timer = MagicMock()
|
||||
queue._timer = existing_timer
|
||||
created_timer = MagicMock()
|
||||
|
||||
with patch("deerflow.agents.memory.queue.threading.Timer", return_value=created_timer) as timer_cls:
|
||||
queue.flush_nowait()
|
||||
|
||||
existing_timer.cancel.assert_called_once_with()
|
||||
timer_cls.assert_called_once_with(0, queue._process_queue)
|
||||
assert created_timer.daemon is True
|
||||
created_timer.start.assert_called_once_with()
|
||||
assert queue._timer is created_timer
|
||||
|
||||
|
||||
def test_add_nowait_cancels_existing_timer_and_starts_immediate_timer() -> None:
|
||||
queue = MemoryUpdateQueue()
|
||||
existing_timer = MagicMock()
|
||||
queue._timer = existing_timer
|
||||
created_timer = MagicMock()
|
||||
|
||||
with (
|
||||
patch("deerflow.agents.memory.queue.get_memory_config", return_value=_memory_config(enabled=True)),
|
||||
patch("deerflow.agents.memory.queue.threading.Timer", return_value=created_timer) as timer_cls,
|
||||
):
|
||||
queue.add_nowait(thread_id="thread-1", messages=["conversation"], agent_name="lead-agent")
|
||||
|
||||
existing_timer.cancel.assert_called_once_with()
|
||||
timer_cls.assert_called_once_with(0, queue._process_queue)
|
||||
assert queue.pending_count == 1
|
||||
assert queue._queue[0].agent_name == "lead-agent"
|
||||
assert created_timer.daemon is True
|
||||
created_timer.start.assert_called_once_with()
|
||||
|
||||
|
||||
def test_process_queue_reschedules_immediately_when_already_processing() -> None:
|
||||
queue = MemoryUpdateQueue()
|
||||
queue._processing = True
|
||||
created_timer = MagicMock()
|
||||
|
||||
with patch("deerflow.agents.memory.queue.threading.Timer", return_value=created_timer) as timer_cls:
|
||||
queue._process_queue()
|
||||
|
||||
timer_cls.assert_called_once_with(0, queue._process_queue)
|
||||
assert created_timer.daemon is True
|
||||
created_timer.start.assert_called_once_with()
|
||||
|
||||
|
||||
def test_flush_nowait_is_non_blocking() -> None:
|
||||
queue = MemoryUpdateQueue()
|
||||
started = threading.Event()
|
||||
finished = threading.Event()
|
||||
|
||||
def _slow_process_queue() -> None:
|
||||
started.set()
|
||||
time.sleep(0.2)
|
||||
finished.set()
|
||||
|
||||
queue._process_queue = _slow_process_queue
|
||||
|
||||
start = time.perf_counter()
|
||||
queue.flush_nowait()
|
||||
elapsed = time.perf_counter() - start
|
||||
|
||||
assert started.wait(0.1) is True
|
||||
assert elapsed < 0.1
|
||||
assert finished.is_set() is False
|
||||
assert finished.wait(1.0) is True
|
||||
|
||||
Reference in New Issue
Block a user