添加内存管理工具和用户密钥支持,更新文档和测试用例
This commit is contained in:
@ -23,10 +23,23 @@ class FakeClient:
|
||||
def __init__(self, commit_status="success"):
|
||||
self.posts = []
|
||||
self.gets = []
|
||||
self.deletes = []
|
||||
self.commit_status = commit_status
|
||||
|
||||
def post(self, path, payload=None):
|
||||
self.posts.append((path, payload or {}))
|
||||
if path == "/memory-system/users":
|
||||
return {
|
||||
"status": "success",
|
||||
"account": {
|
||||
"status": "ok",
|
||||
"result": {
|
||||
"account_id": f"{payload['user_id']}_account",
|
||||
"admin_user_id": payload["user_id"],
|
||||
"user_key": f"{payload['user_id']}-key",
|
||||
},
|
||||
},
|
||||
}
|
||||
if path == "/memory-system/search":
|
||||
return {
|
||||
"status": "success",
|
||||
@ -52,12 +65,22 @@ class FakeClient:
|
||||
}
|
||||
if path.endswith("/commit"):
|
||||
return {"status": self.commit_status}
|
||||
if path == "/memory-system/memories":
|
||||
return {"status": "success", "memory": {"status": "ok", "result": {"uri": payload.get("uri")}}}
|
||||
return {"status": "success"}
|
||||
|
||||
def get(self, path):
|
||||
self.gets.append(path)
|
||||
if path.startswith("/memory-system/memories/content"):
|
||||
return {"status": "success", "memory": {"status": "ok", "result": {"content": "# Python"}}}
|
||||
if path.startswith("/memory-system/memories"):
|
||||
return {"status": "success", "memory": {"status": "ok", "result": {"children": []}}}
|
||||
return {"status": "success", "profile": {"coffee": "latte"}}
|
||||
|
||||
def delete(self, path):
|
||||
self.deletes.append(path)
|
||||
return {"status": "success", "memory": {"status": "ok", "result": {"estimated_deleted_count": 1}}}
|
||||
|
||||
|
||||
def make_provider():
|
||||
module = load_plugin_module()
|
||||
@ -65,6 +88,7 @@ def make_provider():
|
||||
provider._client = FakeClient()
|
||||
provider._endpoint = "http://127.0.0.1:1934"
|
||||
provider._user_id = "user-1"
|
||||
provider._user_key = "user-1-key"
|
||||
provider._session_id = "session-1"
|
||||
provider._commit_every_turns = 0
|
||||
provider._commit_interval_seconds = 0
|
||||
@ -87,6 +111,7 @@ def test_initialize_loads_config_from_hermes_env_file(tmp_path, monkeypatch):
|
||||
[
|
||||
"MEMORY_SYSTEM_ENDPOINT=http://127.0.0.1:1934",
|
||||
"MEMORY_SYSTEM_USER_ID=file-user",
|
||||
"MEMORY_SYSTEM_USER_KEY=file-user-key",
|
||||
"MEMORY_SYSTEM_COMMIT_EVERY_TURNS=3",
|
||||
"MEMORY_SYSTEM_COMMIT_INTERVAL_SECONDS=60",
|
||||
"MEMORY_SYSTEM_TIMEOUT_SECONDS=123",
|
||||
@ -116,6 +141,7 @@ def test_initialize_loads_config_from_hermes_env_file(tmp_path, monkeypatch):
|
||||
|
||||
assert provider._endpoint == "http://127.0.0.1:1934"
|
||||
assert provider._user_id == "file-user"
|
||||
assert provider._user_key == "file-user-key"
|
||||
assert provider._commit_every_turns == 3
|
||||
assert provider._commit_interval_seconds == 60
|
||||
assert provider._timeout == 123
|
||||
@ -134,6 +160,7 @@ def test_sync_turn_posts_user_and_assistant_messages():
|
||||
"/memory-system/messages",
|
||||
{
|
||||
"user_id": "user-1",
|
||||
"user_key": "user-1-key",
|
||||
"session_id": "session-1",
|
||||
"user_message": "hello",
|
||||
"assistant_message": "hi there",
|
||||
@ -151,7 +178,7 @@ def test_on_session_end_commits_after_turn_sync():
|
||||
|
||||
assert provider._client.posts[-1] == (
|
||||
"/memory-system/sessions/session-1/commit",
|
||||
{"user_id": "user-1"},
|
||||
{"user_id": "user-1", "user_key": "user-1-key"},
|
||||
)
|
||||
|
||||
|
||||
@ -167,7 +194,7 @@ def test_sync_turn_commits_every_configured_turns():
|
||||
|
||||
assert provider._client.posts[-1] == (
|
||||
"/memory-system/sessions/session-1/commit",
|
||||
{"user_id": "user-1"},
|
||||
{"user_id": "user-1", "user_key": "user-1-key"},
|
||||
)
|
||||
assert provider._last_commit_turn == 2
|
||||
|
||||
@ -221,12 +248,13 @@ def test_search_tool_uses_memory_system_api():
|
||||
assert "vector" not in json.dumps(result)
|
||||
assert "original_data" not in json.dumps(result)
|
||||
assert provider._client.posts[-1] == (
|
||||
"/memory-system/search",
|
||||
{
|
||||
"user_id": "user-1",
|
||||
"session_id": "session-1",
|
||||
"query": "coffee",
|
||||
"use_llm": False,
|
||||
"/memory-system/search",
|
||||
{
|
||||
"user_id": "user-1",
|
||||
"user_key": "user-1-key",
|
||||
"session_id": "session-1",
|
||||
"query": "coffee",
|
||||
"use_llm": False,
|
||||
"limit": 3,
|
||||
},
|
||||
)
|
||||
@ -238,7 +266,7 @@ def test_profile_tool_reads_user_profile():
|
||||
result = json.loads(provider.handle_tool_call("memory_system_profile", {}))
|
||||
|
||||
assert result["profile"] == {"coffee": "latte"}
|
||||
assert provider._client.gets == ["/memory-system/users/user-1/profile"]
|
||||
assert provider._client.gets == ["/memory-system/users/user-1/profile?user_key=user-1-key"]
|
||||
|
||||
|
||||
def test_remember_tool_writes_and_commits():
|
||||
@ -252,6 +280,7 @@ def test_remember_tool_writes_and_commits():
|
||||
"/memory-system/messages",
|
||||
{
|
||||
"user_id": "user-1",
|
||||
"user_key": "user-1-key",
|
||||
"session_id": "session-1",
|
||||
"user_message": "likes latte",
|
||||
"metadata": {"source": "hermes", "provider": "memory_system"},
|
||||
@ -259,11 +288,118 @@ def test_remember_tool_writes_and_commits():
|
||||
),
|
||||
(
|
||||
"/memory-system/sessions/session-1/commit",
|
||||
{"user_id": "user-1"},
|
||||
{"user_id": "user-1", "user_key": "user-1-key"},
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
def test_initialize_creates_user_when_user_key_is_not_configured(tmp_path, monkeypatch):
|
||||
module = load_plugin_module()
|
||||
for key in list(os.environ):
|
||||
if key.startswith("MEMORY_SYSTEM_"):
|
||||
monkeypatch.delenv(key, raising=False)
|
||||
monkeypatch.setenv("MEMORY_SYSTEM_ENDPOINT", "http://127.0.0.1:1934")
|
||||
monkeypatch.setenv("MEMORY_SYSTEM_USER_ID", "new-user")
|
||||
monkeypatch.chdir(tmp_path)
|
||||
|
||||
class InitClient(FakeClient):
|
||||
def __init__(self, endpoint, api_key="", timeout=0):
|
||||
super().__init__()
|
||||
self.endpoint = endpoint
|
||||
|
||||
def health(self):
|
||||
return True
|
||||
|
||||
monkeypatch.setattr(module, "_MemorySystemClient", InitClient)
|
||||
provider = module.MemorySystemMemoryProvider()
|
||||
|
||||
provider.initialize("session-1")
|
||||
|
||||
assert provider._user_key == "new-user-key"
|
||||
assert provider._client.posts == [("/memory-system/users", {"user_id": "new-user"})]
|
||||
|
||||
|
||||
def test_memory_tool_schemas_include_memory_management_tools():
|
||||
provider = make_provider()
|
||||
|
||||
tool_names = {schema["name"] for schema in provider.get_tool_schemas()}
|
||||
|
||||
assert {
|
||||
"memory_system_memory_list",
|
||||
"memory_system_memory_read",
|
||||
"memory_system_memory_write",
|
||||
"memory_system_memory_delete",
|
||||
} <= tool_names
|
||||
|
||||
|
||||
def test_memory_list_tool_calls_memories_endpoint():
|
||||
provider = make_provider()
|
||||
|
||||
result = json.loads(provider.handle_tool_call("memory_system_memory_list", {"recursive": True}))
|
||||
|
||||
assert result["status"] == "success"
|
||||
assert provider._client.gets == [
|
||||
"/memory-system/memories?user_id=user-1&user_key=user-1-key&uri=viking%3A%2F%2Fuser%2Fmemories&recursive=true"
|
||||
]
|
||||
|
||||
|
||||
def test_memory_read_tool_calls_memory_content_endpoint():
|
||||
provider = make_provider()
|
||||
|
||||
result = json.loads(provider.handle_tool_call(
|
||||
"memory_system_memory_read",
|
||||
{"uri": "viking://user/memories/preferences/python.md"},
|
||||
))
|
||||
|
||||
assert result["status"] == "success"
|
||||
assert provider._client.gets == [
|
||||
"/memory-system/memories/content?user_id=user-1&user_key=user-1-key&uri=viking%3A%2F%2Fuser%2Fmemories%2Fpreferences%2Fpython.md"
|
||||
]
|
||||
|
||||
|
||||
def test_memory_write_tool_posts_memory_payload():
|
||||
provider = make_provider()
|
||||
|
||||
result = json.loads(provider.handle_tool_call(
|
||||
"memory_system_memory_write",
|
||||
{
|
||||
"uri": "viking://user/memories/preferences/python.md",
|
||||
"content": "# Python",
|
||||
"mode": "replace",
|
||||
"wait": True,
|
||||
},
|
||||
))
|
||||
|
||||
assert result["status"] == "success"
|
||||
assert provider._client.posts == [
|
||||
(
|
||||
"/memory-system/memories",
|
||||
{
|
||||
"user_id": "user-1",
|
||||
"user_key": "user-1-key",
|
||||
"uri": "viking://user/memories/preferences/python.md",
|
||||
"content": "# Python",
|
||||
"mode": "replace",
|
||||
"wait": True,
|
||||
},
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
def test_memory_delete_tool_deletes_memory_uri_non_recursive_by_default():
|
||||
provider = make_provider()
|
||||
|
||||
result = json.loads(provider.handle_tool_call(
|
||||
"memory_system_memory_delete",
|
||||
{"uri": "viking://user/memories/preferences/python.md"},
|
||||
))
|
||||
|
||||
assert result["status"] == "success"
|
||||
assert provider._client.deletes == [
|
||||
"/memory-system/memories?user_id=user-1&user_key=user-1-key&uri=viking%3A%2F%2Fuser%2Fmemories%2Fpreferences%2Fpython.md&recursive=false"
|
||||
]
|
||||
|
||||
|
||||
def test_register_adds_provider():
|
||||
module = load_plugin_module()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user