mirror of
https://gitcode.com/JianFeeeee/TrulyMEM-TrueHumanMEM.git
synced 2026-09-20 08:58:15 +00:00
refactor: restructure to core/ + ui/ with multi-threaded backend
This commit is contained in:
@ -3,7 +3,7 @@
|
||||
import pytest
|
||||
import tempfile
|
||||
import os
|
||||
from graph_memory_tui.core.embedded_db import EmbeddedGraphDB
|
||||
from core import EmbeddedGraphDB
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
|
||||
@ -1,50 +1,32 @@
|
||||
"""核心逻辑导入测试"""
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
def test_import_neo4j_graph():
|
||||
"""测试 Neo4jGraph 类导入"""
|
||||
from graph_memory_tui.core.imports import Neo4jGraph
|
||||
assert Neo4jGraph is not None
|
||||
assert hasattr(Neo4jGraph, 'recall')
|
||||
assert hasattr(Neo4jGraph, 'commit')
|
||||
assert hasattr(Neo4jGraph, 'purge')
|
||||
def test_import_backend_server():
|
||||
from core import BackendServer
|
||||
assert BackendServer is not None
|
||||
|
||||
|
||||
def test_import_graph_memory_client():
|
||||
"""测试 GraphMemoryClient 类导入"""
|
||||
from graph_memory_tui.core.imports import GraphMemoryClient
|
||||
def test_import_backend_client():
|
||||
from core import BackendClient
|
||||
assert BackendClient is not None
|
||||
|
||||
|
||||
def test_import_embedded_db():
|
||||
from core import EmbeddedGraphDB
|
||||
assert EmbeddedGraphDB is not None
|
||||
|
||||
|
||||
def test_import_graph_client():
|
||||
from core.graph_client import GraphMemoryClient
|
||||
assert GraphMemoryClient is not None
|
||||
assert hasattr(GraphMemoryClient, 'send_message')
|
||||
|
||||
|
||||
def test_import_tools():
|
||||
"""测试 TOOLS 定义导入"""
|
||||
from graph_memory_tui.core.imports import TOOLS
|
||||
assert TOOLS is not None
|
||||
assert isinstance(TOOLS, list)
|
||||
assert len(TOOLS) > 0
|
||||
assert any(t['function']['name'] == 'memory_recall' for t in TOOLS)
|
||||
def test_import_tool_limiter():
|
||||
from core.tool_limiter import ToolLimiter
|
||||
assert ToolLimiter is not None
|
||||
|
||||
|
||||
def test_import_execute_tool():
|
||||
"""测试 execute_tool 函数导入"""
|
||||
from graph_memory_tui.core.imports import execute_tool
|
||||
def test_import_tool_executor():
|
||||
from core.tool_executor import execute_tool
|
||||
assert execute_tool is not None
|
||||
assert callable(execute_tool)
|
||||
|
||||
|
||||
def test_import_config_vars():
|
||||
"""测试配置变量导入"""
|
||||
from graph_memory_tui.core.imports import (
|
||||
DEEPSEEK_API_KEY,
|
||||
DEEPSEEK_BASE_URL,
|
||||
MODEL_NAME,
|
||||
NEO4J_URI,
|
||||
NEO4J_USER,
|
||||
NEO4J_PASSWORD,
|
||||
)
|
||||
assert DEEPSEEK_BASE_URL is not None
|
||||
assert MODEL_NAME is not None
|
||||
assert NEO4J_URI is not None
|
||||
assert callable(execute_tool)
|
||||
@ -1,138 +0,0 @@
|
||||
"""记忆工具测试"""
|
||||
|
||||
import pytest
|
||||
from graph_memory_tui.core.tools.memory_tools import (
|
||||
MEMORY_TOOLS,
|
||||
PERSONA_TOOLS,
|
||||
WORKING_MEMORY_TOOLS,
|
||||
TOOLS
|
||||
)
|
||||
|
||||
|
||||
def test_memory_tools_exist():
|
||||
"""测试记忆工具存在"""
|
||||
assert len(MEMORY_TOOLS) >= 6
|
||||
|
||||
|
||||
def test_persona_tools_exist():
|
||||
"""测试人设工具存在"""
|
||||
assert len(PERSONA_TOOLS) >= 2
|
||||
|
||||
|
||||
def test_working_memory_tools_exist():
|
||||
"""测试工作记忆工具存在"""
|
||||
assert len(WORKING_MEMORY_TOOLS) >= 4
|
||||
|
||||
|
||||
def test_all_tools_combined():
|
||||
"""测试工具合并"""
|
||||
assert len(TOOLS) == len(MEMORY_TOOLS) + len(PERSONA_TOOLS) + len(WORKING_MEMORY_TOOLS)
|
||||
|
||||
|
||||
def test_memory_recall_tool():
|
||||
"""测试 memory_recall 工具定义"""
|
||||
recall = next((t for t in TOOLS if t['function']['name'] == 'memory_recall'), None)
|
||||
assert recall is not None
|
||||
|
||||
params = recall['function']['parameters']['properties']
|
||||
assert 'query_intent' in params
|
||||
assert 'seed_entities' in params
|
||||
assert 'depth' in params
|
||||
|
||||
|
||||
def test_memory_commit_tool():
|
||||
"""测试 memory_commit 工具定义"""
|
||||
commit = next((t for t in TOOLS if t['function']['name'] == 'memory_commit'), None)
|
||||
assert commit is not None
|
||||
|
||||
params = commit['function']['parameters']['properties']
|
||||
assert 'triplets' in params
|
||||
|
||||
|
||||
def test_memory_purge_tool():
|
||||
"""测试 memory_purge 工具定义"""
|
||||
purge = next((t for t in TOOLS if t['function']['name'] == 'memory_purge'), None)
|
||||
assert purge is not None
|
||||
|
||||
params = purge['function']['parameters']['properties']
|
||||
assert 'criteria' in params
|
||||
assert 'mode' in params
|
||||
|
||||
|
||||
def test_memory_introspect_tool():
|
||||
"""测试 memory_introspect 工具定义"""
|
||||
introspect = next((t for t in TOOLS if t['function']['name'] == 'memory_introspect'), None)
|
||||
assert introspect is not None
|
||||
|
||||
|
||||
def test_persona_update_tool():
|
||||
"""测试 persona_update 工具定义"""
|
||||
update = next((t for t in TOOLS if t['function']['name'] == 'persona_update'), None)
|
||||
assert update is not None
|
||||
|
||||
params = update['function']['parameters']['properties']
|
||||
assert 'attributes' in params
|
||||
|
||||
|
||||
def test_persona_clear_tool():
|
||||
"""测试 persona_clear 工具定义"""
|
||||
clear = next((t for t in TOOLS if t['function']['name'] == 'persona_clear'), None)
|
||||
assert clear is not None
|
||||
|
||||
|
||||
def test_task_create_tool():
|
||||
"""测试 task_create 工具定义"""
|
||||
create = next((t for t in TOOLS if t['function']['name'] == 'task_create'), None)
|
||||
assert create is not None
|
||||
|
||||
params = create['function']['parameters']['properties']
|
||||
assert 'task_id' in params
|
||||
assert 'description' in params
|
||||
|
||||
|
||||
def test_task_set_state_tool():
|
||||
"""测试 task_set_state 工具定义"""
|
||||
set_state = next((t for t in TOOLS if t['function']['name'] == 'task_set_state'), None)
|
||||
assert set_state is not None
|
||||
|
||||
params = set_state['function']['parameters']['properties']
|
||||
assert 'task_id' in params
|
||||
assert 'state' in params
|
||||
|
||||
|
||||
def test_task_delete_tool():
|
||||
"""测试 task_delete 工具定义"""
|
||||
delete = next((t for t in TOOLS if t['function']['name'] == 'task_delete'), None)
|
||||
assert delete is not None
|
||||
|
||||
|
||||
def test_task_link_info_tool():
|
||||
"""测试 task_link_info 工具定义"""
|
||||
link = next((t for t in TOOLS if t['function']['name'] == 'task_link_info'), None)
|
||||
assert link is not None
|
||||
|
||||
params = link['function']['parameters']['properties']
|
||||
assert 'task_id' in params
|
||||
assert 'info_node_names' in params
|
||||
|
||||
|
||||
def test_tool_has_required_fields():
|
||||
"""测试工具都有必需字段"""
|
||||
for tool in TOOLS:
|
||||
assert 'type' in tool
|
||||
assert tool['type'] == 'function'
|
||||
assert 'function' in tool
|
||||
assert 'name' in tool['function']
|
||||
assert 'description' in tool['function']
|
||||
assert 'parameters' in tool['function']
|
||||
|
||||
|
||||
def test_tool_state_enum():
|
||||
"""测试 task_set_state 的状态枚举"""
|
||||
set_state = next((t for t in TOOLS if t['function']['name'] == 'task_set_state'), None)
|
||||
state_enum = set_state['function']['parameters']['properties']['state']['enum']
|
||||
|
||||
assert '进行中' in state_enum
|
||||
assert '已完成' in state_enum
|
||||
assert '已暂停' in state_enum
|
||||
assert '已取消' in state_enum
|
||||
57
tests/test_core/test_server.py
Normal file
57
tests/test_core/test_server.py
Normal file
@ -0,0 +1,57 @@
|
||||
import pytest
|
||||
import os
|
||||
import tempfile
|
||||
|
||||
os.environ["DEEPSEEK_API_KEY"] = "fake-test-key"
|
||||
|
||||
|
||||
class TestCoreImport:
|
||||
def test_import_backend_server(self):
|
||||
from core import BackendServer
|
||||
assert BackendServer is not None
|
||||
|
||||
def test_import_backend_client(self):
|
||||
from core import BackendClient
|
||||
assert BackendClient is not None
|
||||
|
||||
def test_import_embedded_db(self):
|
||||
from core import EmbeddedGraphDB
|
||||
assert EmbeddedGraphDB is not None
|
||||
|
||||
|
||||
class TestBackendServer:
|
||||
def test_create_server(self):
|
||||
from core import BackendServer
|
||||
server = BackendServer(db_path=":memory:", use_embedded_db=True)
|
||||
assert server is not None
|
||||
assert server._running is False
|
||||
|
||||
def test_start_server(self):
|
||||
from core import BackendServer
|
||||
with tempfile.NamedTemporaryFile(suffix=".db", delete=False) as f:
|
||||
db_path = f.name
|
||||
|
||||
try:
|
||||
server = BackendServer(db_path=db_path, use_embedded_db=True)
|
||||
server.start(api_key="", base_url="https://api.test.com")
|
||||
|
||||
assert server._running is True
|
||||
assert server._graph is not None
|
||||
|
||||
server.shutdown()
|
||||
finally:
|
||||
if os.path.exists(db_path):
|
||||
os.unlink(db_path)
|
||||
|
||||
def test_shutdown(self):
|
||||
from core import BackendServer
|
||||
with tempfile.NamedTemporaryFile(suffix=".db", delete=False) as f:
|
||||
db_path = f.name
|
||||
|
||||
server = BackendServer(db_path=db_path, use_embedded_db=True)
|
||||
server.start(api_key="", base_url="https://api.test.com")
|
||||
|
||||
assert server._running is True
|
||||
|
||||
server.shutdown()
|
||||
assert server._running is False
|
||||
@ -1,148 +0,0 @@
|
||||
"""工具限制器测试"""
|
||||
|
||||
import pytest
|
||||
from graph_memory_tui.core.tools.tool_limiter import (
|
||||
ToolLimiter,
|
||||
ToolLimits,
|
||||
ToolCallCount
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def limiter():
|
||||
"""创建限制器实例"""
|
||||
return ToolLimiter()
|
||||
|
||||
|
||||
def test_classify_persona_tools(limiter):
|
||||
"""测试人设工具分类"""
|
||||
category, operation = limiter._classify_tool('persona_update', {})
|
||||
assert category == 'persona'
|
||||
assert operation == 'update'
|
||||
|
||||
category, operation = limiter._classify_tool('persona_clear', {})
|
||||
assert category == 'persona'
|
||||
assert operation == 'update'
|
||||
|
||||
|
||||
def test_classify_task_tools(limiter):
|
||||
"""测试任务工具分类"""
|
||||
category, operation = limiter._classify_tool('task_create', {})
|
||||
assert category == 'task'
|
||||
assert operation == 'update'
|
||||
|
||||
category, operation = limiter._classify_tool('task_set_state', {})
|
||||
assert category == 'task'
|
||||
assert operation == 'update'
|
||||
|
||||
category, operation = limiter._classify_tool('task_delete', {})
|
||||
assert category == 'task'
|
||||
assert operation == 'update'
|
||||
|
||||
category, operation = limiter._classify_tool('task_link_info', {})
|
||||
assert category == 'task'
|
||||
assert operation == 'update'
|
||||
|
||||
|
||||
def test_classify_memory_recall(limiter):
|
||||
"""测试 memory_recall 分类"""
|
||||
category, operation = limiter._classify_tool('memory_recall', {'query_intent': 'Python'})
|
||||
assert category == 'memory'
|
||||
assert operation == 'query'
|
||||
|
||||
|
||||
def test_classify_memory_recall_persona_query(limiter):
|
||||
"""测试 memory_recall 查询人设图"""
|
||||
category, operation = limiter._classify_tool(
|
||||
'memory_recall',
|
||||
{'query_intent': 'AI,人设,角色'}
|
||||
)
|
||||
assert category == 'persona'
|
||||
assert operation == 'query'
|
||||
|
||||
|
||||
def test_classify_memory_recall_task_query(limiter):
|
||||
"""测试 memory_recall 查询工作记忆链"""
|
||||
category, operation = limiter._classify_tool(
|
||||
'memory_recall',
|
||||
{'query_intent': 'TaskNode,工作记忆'}
|
||||
)
|
||||
assert category == 'task'
|
||||
assert operation == 'query'
|
||||
|
||||
|
||||
def test_can_call_allowed(limiter):
|
||||
"""测试允许调用"""
|
||||
allowed, reason = limiter.can_call('memory_recall', {'query_intent': 'test'})
|
||||
assert allowed is True
|
||||
|
||||
|
||||
def test_can_call_limit_reached(limiter):
|
||||
"""测试达到限制"""
|
||||
for _ in range(20):
|
||||
limiter.record_call('memory_recall', {'query_intent': 'test'})
|
||||
|
||||
allowed, reason = limiter.can_call('memory_recall', {'query_intent': 'test'})
|
||||
assert allowed is False
|
||||
assert '上限' in reason
|
||||
|
||||
|
||||
def test_record_call(limiter):
|
||||
"""测试记录调用"""
|
||||
initial_count = limiter.counts.memory_query
|
||||
|
||||
limiter.record_call('memory_recall', {'query_intent': 'test'})
|
||||
|
||||
assert limiter.counts.memory_query == initial_count + 1
|
||||
|
||||
|
||||
def test_reset(limiter):
|
||||
"""测试重置计数"""
|
||||
limiter.record_call('memory_recall', {'query_intent': 'test'})
|
||||
limiter.record_call('memory_recall', {'query_intent': 'test'})
|
||||
|
||||
limiter.reset()
|
||||
|
||||
assert limiter.counts.memory_query == 0
|
||||
assert limiter.counts.memory_update == 0
|
||||
|
||||
|
||||
def test_get_summary(limiter):
|
||||
"""测试获取统计摘要"""
|
||||
limiter.record_call('memory_recall', {'query_intent': 'test'})
|
||||
|
||||
summary = limiter.get_summary()
|
||||
|
||||
assert isinstance(summary, str)
|
||||
assert '一般记忆' in summary
|
||||
assert '查询1' in summary
|
||||
|
||||
|
||||
def test_custom_limits():
|
||||
"""测试自定义限制"""
|
||||
limits = ToolLimits(
|
||||
memory_query_max=5,
|
||||
memory_update_max=3
|
||||
)
|
||||
limiter = ToolLimiter(limits)
|
||||
|
||||
assert limiter.limits.memory_query_max == 5
|
||||
assert limiter.limits.memory_update_max == 3
|
||||
|
||||
|
||||
def test_persona_query_limit(limiter):
|
||||
"""测试人设图查询限制"""
|
||||
for _ in range(1):
|
||||
limiter.record_call('memory_recall', {'query_intent': '人设'})
|
||||
|
||||
allowed, _ = limiter.can_call('memory_recall', {'query_intent': '人设'})
|
||||
assert allowed is False
|
||||
|
||||
|
||||
def test_task_query_limit(limiter):
|
||||
"""测试工作记忆链查询限制"""
|
||||
for _ in range(4):
|
||||
limiter.record_call('memory_recall', {'query_intent': 'TaskNode'})
|
||||
|
||||
allowed, _ = limiter.can_call('memory_recall', {'query_intent': 'TaskNode'})
|
||||
assert allowed is False
|
||||
Reference in New Issue
Block a user