fix(memory): add write origin metadata
This commit is contained in:
@@ -77,6 +77,13 @@ class FakeMemoryProvider(MemoryProvider):
|
||||
self.memory_writes.append((action, target, content))
|
||||
|
||||
|
||||
class MetadataMemoryProvider(FakeMemoryProvider):
|
||||
"""Provider that opts into write metadata."""
|
||||
|
||||
def on_memory_write(self, action, target, content, metadata=None):
|
||||
self.memory_writes.append((action, target, content, metadata or {}))
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# MemoryProvider ABC tests
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -862,6 +869,51 @@ class TestOnMemoryWriteBridge:
|
||||
mgr.on_memory_write("add", "memory", "new fact")
|
||||
assert p.memory_writes == [("add", "memory", "new fact")]
|
||||
|
||||
def test_on_memory_write_metadata_passed_to_opt_in_provider(self):
|
||||
"""Providers that accept metadata receive structured write provenance."""
|
||||
mgr = MemoryManager()
|
||||
p = MetadataMemoryProvider("ext")
|
||||
mgr.add_provider(p)
|
||||
|
||||
mgr.on_memory_write(
|
||||
"add",
|
||||
"memory",
|
||||
"new fact",
|
||||
metadata={
|
||||
"write_origin": "assistant_tool",
|
||||
"execution_context": "foreground",
|
||||
"session_id": "sess-1",
|
||||
},
|
||||
)
|
||||
|
||||
assert p.memory_writes == [
|
||||
(
|
||||
"add",
|
||||
"memory",
|
||||
"new fact",
|
||||
{
|
||||
"write_origin": "assistant_tool",
|
||||
"execution_context": "foreground",
|
||||
"session_id": "sess-1",
|
||||
},
|
||||
)
|
||||
]
|
||||
|
||||
def test_on_memory_write_metadata_keeps_legacy_provider_compatible(self):
|
||||
"""Old 3-arg providers keep working when the manager receives metadata."""
|
||||
mgr = MemoryManager()
|
||||
p = FakeMemoryProvider("ext")
|
||||
mgr.add_provider(p)
|
||||
|
||||
mgr.on_memory_write(
|
||||
"add",
|
||||
"user",
|
||||
"legacy provider fact",
|
||||
metadata={"write_origin": "assistant_tool"},
|
||||
)
|
||||
|
||||
assert p.memory_writes == [("add", "user", "legacy provider fact")]
|
||||
|
||||
def test_on_memory_write_replace(self):
|
||||
"""on_memory_write fires for 'replace' actions."""
|
||||
mgr = MemoryManager()
|
||||
|
||||
@@ -233,6 +233,31 @@ class TestFlushMemoriesUsesAuxiliaryClient:
|
||||
assert call_kwargs.kwargs["target"] == "notes"
|
||||
assert "dark mode" in call_kwargs.kwargs["content"]
|
||||
|
||||
def test_flush_bridges_memory_write_metadata(self, monkeypatch):
|
||||
"""Flush memory writes notify external providers with flush provenance."""
|
||||
agent = _make_agent(monkeypatch, api_mode="chat_completions", provider="openrouter")
|
||||
agent._memory_manager = MagicMock()
|
||||
agent.session_id = "sess-flush"
|
||||
agent.platform = "cli"
|
||||
|
||||
mock_response = _chat_response_with_memory_call()
|
||||
|
||||
with patch("agent.auxiliary_client.call_llm", return_value=mock_response):
|
||||
messages = [
|
||||
{"role": "user", "content": "Hello"},
|
||||
{"role": "assistant", "content": "Hi"},
|
||||
{"role": "user", "content": "Note this"},
|
||||
]
|
||||
with patch("tools.memory_tool.memory_tool", return_value="Saved."):
|
||||
agent.flush_memories(messages)
|
||||
|
||||
agent._memory_manager.on_memory_write.assert_called_once()
|
||||
call_kwargs = agent._memory_manager.on_memory_write.call_args
|
||||
assert call_kwargs.args[:3] == ("add", "notes", "User prefers dark mode.")
|
||||
assert call_kwargs.kwargs["metadata"]["write_origin"] == "memory_flush"
|
||||
assert call_kwargs.kwargs["metadata"]["execution_context"] == "flush_memories"
|
||||
assert call_kwargs.kwargs["metadata"]["session_id"] == "sess-flush"
|
||||
|
||||
def test_flush_strips_artifacts_from_messages(self, monkeypatch):
|
||||
"""After flush, the flush prompt and any response should be removed from messages."""
|
||||
agent = _make_agent(monkeypatch, api_mode="chat_completions", provider="openrouter")
|
||||
|
||||
Reference in New Issue
Block a user