feat(memory-gateway): merge memory mode with main

This commit is contained in:
2026-06-16 18:04:44 +08:00
30 changed files with 3170 additions and 18 deletions

View File

@ -1,6 +1,7 @@
import json
import asyncio
import pytest
from fastapi.testclient import TestClient
from beaver.engine import AgentLoop, EngineLoader
@ -11,6 +12,39 @@ from beaver.interfaces.web.app import create_app, _reload_agent_config
from beaver.services.agent_service import AgentService
def test_load_config_reads_shared_memory_config(tmp_path, monkeypatch: pytest.MonkeyPatch) -> None:
config_path = tmp_path / "config.json"
config_path.write_text(json.dumps({}), encoding="utf-8")
memory_config_path = tmp_path / "memory-config.json"
memory_config_path.write_text(
json.dumps(
{
"memory": {
"mode": "hybrid",
"gateway": {
"baseUrl": "http://172.19.207.37:8010",
"appId": "default",
"projectId": "default",
"scope": ["current_chat", "resources", "all_user_memory"],
"topK": 8,
"timeoutSeconds": 10,
},
}
}
),
encoding="utf-8",
)
monkeypatch.setenv("BEAVER_MEMORY_CONFIG_PATH", str(memory_config_path))
config = load_config(config_path=config_path)
assert config.memory.mode == "hybrid"
assert config.memory.gateway.base_url == "http://172.19.207.37:8010"
assert config.memory.gateway.scope == ["current_chat", "resources", "all_user_memory"]
assert config.memory.gateway.top_k == 8
assert config.memory.gateway.timeout_seconds == 10
def test_load_config_reads_current_instance_shape(tmp_path) -> None:
config_path = tmp_path / "config.json"
config_path.write_text(
@ -514,3 +548,159 @@ def test_load_config_adds_managed_local_mcp_servers(tmp_path) -> None:
assert local.managed is True
assert local.display_name == "个人智能体文件系统工具"
assert "beaver.interfaces.mcp.tools_server" in local.args
def test_missing_memory_config_defaults_to_implicit_hybrid(
tmp_path, monkeypatch: pytest.MonkeyPatch
) -> None:
monkeypatch.setenv("BEAVER_MEMORY_CONFIG_PATH", str(tmp_path / "missing-memory.json"))
config = load_config(config_path=tmp_path / "missing.json")
assert config.memory.mode == "hybrid"
assert config.memory.explicit is False
assert config.memory.gateway.scope == ["current_chat", "resources", "all_user_memory"]
def test_load_config_reads_explicit_curated_memory_mode(
tmp_path, monkeypatch: pytest.MonkeyPatch
) -> None:
config_path = tmp_path / "config.json"
config_path.write_text(json.dumps({}), encoding="utf-8")
memory_config_path = tmp_path / "memory-config.json"
memory_config_path.write_text(json.dumps({"memory": {"mode": "curated"}}), encoding="utf-8")
monkeypatch.setenv("BEAVER_MEMORY_CONFIG_PATH", str(memory_config_path))
config = load_config(config_path=config_path)
assert config.memory.mode == "curated"
assert config.memory.explicit is True
def test_load_config_reads_explicit_hybrid_gateway_settings(
tmp_path, monkeypatch: pytest.MonkeyPatch
) -> None:
config_path = tmp_path / "config.json"
config_path.write_text(json.dumps({}), encoding="utf-8")
memory_config_path = tmp_path / "memory-config.json"
memory_config_path.write_text(
json.dumps(
{
"memory": {
"mode": "hybrid",
"gateway": {
"baseUrl": "http://127.0.0.1:8010",
"appId": "beaver",
"projectId": "sandbox",
"scope": ["current_chat", "resources"],
"topK": 5,
"timeoutSeconds": 12.5,
},
}
}
),
encoding="utf-8",
)
monkeypatch.setenv("BEAVER_MEMORY_CONFIG_PATH", str(memory_config_path))
config = load_config(config_path=config_path)
assert config.memory.mode == "hybrid"
assert config.memory.explicit is True
assert config.memory.gateway.base_url == "http://127.0.0.1:8010"
assert config.memory.gateway.app_id == "beaver"
assert config.memory.gateway.project_id == "sandbox"
assert config.memory.gateway.scope == ["current_chat", "resources"]
assert config.memory.gateway.top_k == 5
assert config.memory.gateway.timeout_seconds == 12.5
def test_explicit_hybrid_requires_gateway_base_url(tmp_path, monkeypatch: pytest.MonkeyPatch) -> None:
config_path = tmp_path / "config.json"
config_path.write_text(json.dumps({}), encoding="utf-8")
memory_config_path = tmp_path / "memory-config.json"
memory_config_path.write_text(
json.dumps({"memory": {"mode": "hybrid", "gateway": {"appId": "beaver"}}}),
encoding="utf-8",
)
monkeypatch.setenv("BEAVER_MEMORY_CONFIG_PATH", str(memory_config_path))
with pytest.raises(ValueError) as exc_info:
load_config(config_path=config_path)
assert "baseUrl" in str(exc_info.value)
def test_hybrid_memory_rejects_unknown_scope(tmp_path, monkeypatch: pytest.MonkeyPatch) -> None:
config_path = tmp_path / "config.json"
config_path.write_text(json.dumps({}), encoding="utf-8")
memory_config_path = tmp_path / "memory-config.json"
memory_config_path.write_text(
json.dumps(
{
"memory": {
"mode": "hybrid",
"gateway": {
"baseUrl": "http://127.0.0.1:8010",
"scope": ["current_chat", "unknown"],
},
}
}
),
encoding="utf-8",
)
monkeypatch.setenv("BEAVER_MEMORY_CONFIG_PATH", str(memory_config_path))
with pytest.raises(ValueError, match="scope"):
load_config(config_path=config_path)
def test_hybrid_memory_rejects_empty_scope(tmp_path, monkeypatch: pytest.MonkeyPatch) -> None:
config_path = tmp_path / "config.json"
config_path.write_text(json.dumps({}), encoding="utf-8")
memory_config_path = tmp_path / "memory-config.json"
memory_config_path.write_text(
json.dumps(
{
"memory": {
"mode": "hybrid",
"gateway": {
"baseUrl": "http://127.0.0.1:8010",
"scope": [],
},
}
}
),
encoding="utf-8",
)
monkeypatch.setenv("BEAVER_MEMORY_CONFIG_PATH", str(memory_config_path))
with pytest.raises(ValueError, match="scope"):
load_config(config_path=config_path)
@pytest.mark.parametrize(
("gateway_override", "expected_error"),
[
({"topK": 0}, "topK"),
({"topK": 101}, "topK"),
({"timeoutSeconds": 0}, "timeoutSeconds"),
],
)
def test_hybrid_memory_rejects_invalid_limits(
tmp_path, gateway_override, expected_error, monkeypatch: pytest.MonkeyPatch
) -> None:
config_path = tmp_path / "config.json"
config_path.write_text(json.dumps({}), encoding="utf-8")
gateway = {
"baseUrl": "http://127.0.0.1:8010",
**gateway_override,
}
memory_config_path = tmp_path / "memory-config.json"
memory_config_path.write_text(
json.dumps({"memory": {"mode": "hybrid", "gateway": gateway}}),
encoding="utf-8",
)
monkeypatch.setenv("BEAVER_MEMORY_CONFIG_PATH", str(memory_config_path))
with pytest.raises(ValueError, match=expected_error):
load_config(config_path=config_path)