feat(integrations): add Hermes provider with shared memory utilities
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
"""Offline contract smoke against a real Hermes checkout.
|
||||
|
||||
HERMES_SOURCE=/path/to/hermes-agent python tests/smoke_hermes.py
|
||||
Host modules are real; only the Mem0 backend is mocked. Uses a temporary profile.
|
||||
"""
|
||||
|
||||
import json
|
||||
import os
|
||||
import pathlib
|
||||
import shutil
|
||||
import sys
|
||||
import tempfile
|
||||
from unittest.mock import Mock
|
||||
|
||||
hermes_source = pathlib.Path(os.environ["HERMES_SOURCE"]).resolve()
|
||||
plugin_source = pathlib.Path(__file__).resolve().parents[1]
|
||||
sys.path.insert(0, str(hermes_source))
|
||||
with tempfile.TemporaryDirectory() as d:
|
||||
os.environ["HERMES_HOME"] = d
|
||||
os.environ["MEM0_API_KEY"] = "test-key"
|
||||
import plugins.memory as pm
|
||||
from agent.memory_manager import MemoryManager
|
||||
|
||||
destination = pathlib.Path(d) / "plugins" / "mem0"
|
||||
shutil.copytree(plugin_source, destination)
|
||||
assert pm.find_provider_dir("mem0") == hermes_source / "plugins" / "memory" / "mem0"
|
||||
pm._MEMORY_PLUGINS_DIR = pathlib.Path(d) / "empty-bundled"
|
||||
pm._MEMORY_PLUGINS_DIR.mkdir()
|
||||
provider = pm.load_memory_provider("mem0", register_skills=False)
|
||||
assert provider is not None
|
||||
assert provider.__class__.__module__.startswith("_hermes_user_memory.")
|
||||
backend = Mock()
|
||||
backend.search.return_value = []
|
||||
backend.add.return_value = {}
|
||||
provider._create_backend = lambda: backend
|
||||
manager = MemoryManager()
|
||||
manager.add_provider(provider)
|
||||
manager.initialize_all("s1", platform="cli", user_id="alice")
|
||||
result = manager.handle_tool_call("mem0_search", {"query": "favorite programming language"})
|
||||
assert json.loads(result)["result"] == "No relevant memories found."
|
||||
manager.sync_all(
|
||||
"I prefer Python for tooling. " * 100 + "UNIQUE_END_MARKER",
|
||||
"I will remember that.",
|
||||
session_id="s2",
|
||||
messages=[{"role": "tool", "content": "NOT_FOR_CAPTURE"}],
|
||||
turn_author={"id": "alice"},
|
||||
)
|
||||
manager.shutdown_all()
|
||||
assert backend.add.call_count >= 1
|
||||
sent = str(backend.add.call_args_list)
|
||||
assert "UNIQUE_END_MARKER" in sent and "NOT_FOR_CAPTURE" not in sent
|
||||
assert backend.add.call_args.kwargs["run_id"] == "s2"
|
||||
print("PASS:", hermes_source, "real external loader + MemoryManager lifecycle/tools/full capture/session ID")
|
||||
Reference in New Issue
Block a user