From 620e9a162b4fa3cbc4826084200ce76a9716b36c Mon Sep 17 00:00:00 2001 From: shriramthebeast Date: Wed, 11 Mar 2026 21:29:06 +0530 Subject: [PATCH 1/2] fix(memory): evict STLTMemory entry after consolidation, not before --- mesa_llm/memory/st_lt_memory.py | 3 +- tests/test_memory/test_STLT_memory.py | 53 +++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/mesa_llm/memory/st_lt_memory.py b/mesa_llm/memory/st_lt_memory.py index a4de6836..5fd82fd9 100644 --- a/mesa_llm/memory/st_lt_memory.py +++ b/mesa_llm/memory/st_lt_memory.py @@ -136,7 +136,6 @@ def _process_step_core(self, pre_step: bool): > self.capacity + (self.consolidation_capacity or 0) and self.consolidation_capacity ): - self.short_term_memory.popleft() should_consolidate = True elif ( @@ -155,6 +154,7 @@ def process_step(self, pre_step: bool = False): if should_consolidate: self._update_long_term_memory() + self.short_term_memory.popleft() if new_entry and self.display: new_entry.display() @@ -167,6 +167,7 @@ async def aprocess_step(self, pre_step: bool = False): if should_consolidate: await self._aupdate_long_term_memory() + self.short_term_memory.popleft() if new_entry and self.display: new_entry.display() diff --git a/tests/test_memory/test_STLT_memory.py b/tests/test_memory/test_STLT_memory.py index c0d90696..7be73765 100644 --- a/tests/test_memory/test_STLT_memory.py +++ b/tests/test_memory/test_STLT_memory.py @@ -200,3 +200,56 @@ def test_get_prompt_ready_returns_str_when_empty(self, mock_agent): ) assert "Short term memory:" in result assert "Long term memory:" in result + + def test_consolidation_includes_evicted_entry( + self, mock_agent, mock_llm, llm_response_factory + ): + """Test that the entry being evicted from short-term memory is included + in the consolidation prompt so its content is preserved in long-term + memory. + + Before the fix, popleft() removed the oldest entry *before* + consolidation ran, so the evicted entry was permanently lost. + """ + mock_llm.generate.return_value = llm_response_factory( + "Consolidated summary" + ) + + memory = STLTMemory( + agent=mock_agent, + short_term_capacity=2, + consolidation_capacity=1, + llm_model="provider/test_model", + ) + memory.llm = mock_llm + + with patch("rich.console.Console"): + # Fill memory to just below consolidation threshold + for i in range(3): + memory.add_to_memory( + "observation", {"content": f"event_{i}"} + ) + memory.process_step(pre_step=True) + memory.process_step(pre_step=False) + + # At this point, capacity(2) + consolidation_capacity(1) = 3 + # We have 3 entries, so no consolidation yet. + assert not mock_llm.generate.called + + # Add one more entry to trigger consolidation + memory.add_to_memory( + "observation", {"content": "event_3"} + ) + memory.process_step(pre_step=True) + memory.process_step(pre_step=False) + + # Consolidation should have been triggered + assert mock_llm.generate.called + + # The consolidation prompt must contain the oldest entry + # (event_0) that is about to be evicted + prompt_sent = mock_llm.generate.call_args[0][0] + assert "event_0" in prompt_sent, ( + "The evicted entry's content must appear in the consolidation " + "prompt so the LLM can preserve it in long-term memory" + ) From 829563e1e7d49f1d8db7d2cfb23245f99f14e1cd Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 11 Mar 2026 16:01:22 +0000 Subject: [PATCH 2/2] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- tests/test_memory/test_STLT_memory.py | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/tests/test_memory/test_STLT_memory.py b/tests/test_memory/test_STLT_memory.py index 7be73765..afd1ce6b 100644 --- a/tests/test_memory/test_STLT_memory.py +++ b/tests/test_memory/test_STLT_memory.py @@ -211,9 +211,7 @@ def test_consolidation_includes_evicted_entry( Before the fix, popleft() removed the oldest entry *before* consolidation ran, so the evicted entry was permanently lost. """ - mock_llm.generate.return_value = llm_response_factory( - "Consolidated summary" - ) + mock_llm.generate.return_value = llm_response_factory("Consolidated summary") memory = STLTMemory( agent=mock_agent, @@ -226,9 +224,7 @@ def test_consolidation_includes_evicted_entry( with patch("rich.console.Console"): # Fill memory to just below consolidation threshold for i in range(3): - memory.add_to_memory( - "observation", {"content": f"event_{i}"} - ) + memory.add_to_memory("observation", {"content": f"event_{i}"}) memory.process_step(pre_step=True) memory.process_step(pre_step=False) @@ -237,9 +233,7 @@ def test_consolidation_includes_evicted_entry( assert not mock_llm.generate.called # Add one more entry to trigger consolidation - memory.add_to_memory( - "observation", {"content": "event_3"} - ) + memory.add_to_memory("observation", {"content": "event_3"}) memory.process_step(pre_step=True) memory.process_step(pre_step=False)