初始化提交
This commit is contained in:
commit
887c1f449e
963 files changed
+166869
No files matched your search
@@ -0,0 +1,100 @@
|
||||
"""小周天每轮记忆候选 + 反思抽取测试。
|
||||
|
||||
高置信度(≥0.7)低敏感度记忆候选直接落地到 memories 表而非 MemoryCandidate。
|
||||
"""
|
||||
|
||||
import pytest
|
||||
from sqlalchemy import select
|
||||
|
||||
from app.application.reflection import (
|
||||
drain_pending_reflections,
|
||||
start_reflection_after_turn,
|
||||
)
|
||||
from app.db.session import AsyncSessionLocal
|
||||
from app.models.memory import Memory
|
||||
from app.repositories import candidates as candidates_repo
|
||||
from app.services.characters import get_active_character_model
|
||||
|
||||
_REFLECTION_RESPONSE = (
|
||||
'{"memories":[{"type":"preference","title":"喜欢简洁","content":"用户偏好简洁",'
|
||||
'"importance":0.8,"sensitivity":"low","confidence":0.7}],'
|
||||
'"reflection":"本轮应更主动确认用户意图。"}'
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_reflection_chat(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
async def fake_chat(*_args, **_kwargs):
|
||||
return _REFLECTION_RESPONSE
|
||||
|
||||
monkeypatch.setattr("app.application.reflection._call_model", fake_chat)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_reflection_extracts_memory_and_writes_reflection(
|
||||
mock_reflection_chat, # noqa: ARG001
|
||||
) -> None:
|
||||
async with AsyncSessionLocal() as session:
|
||||
character = await get_active_character_model(session)
|
||||
|
||||
start_reflection_after_turn(character.id, "session_test", "你好", "你好,我是魂镜。")
|
||||
await drain_pending_reflections()
|
||||
|
||||
async with AsyncSessionLocal() as session:
|
||||
# 高置信度记忆直接落地到 memories 表(非 MemoryCandidate)
|
||||
auto_mem = (
|
||||
await session.execute(
|
||||
select(Memory).where(
|
||||
Memory.character_id == character.id,
|
||||
Memory.type == "preference",
|
||||
Memory.source == "reflection",
|
||||
)
|
||||
)
|
||||
).scalar_one_or_none()
|
||||
# 反思文本也落地为 memories 表
|
||||
ref_mem = (
|
||||
await session.execute(
|
||||
select(Memory).where(
|
||||
Memory.character_id == character.id,
|
||||
Memory.type == "reflection",
|
||||
)
|
||||
)
|
||||
).scalar_one_or_none()
|
||||
|
||||
assert auto_mem is not None
|
||||
assert auto_mem.title == "喜欢简洁"
|
||||
assert ref_mem is not None
|
||||
assert ref_mem.source == "reflection"
|
||||
assert ref_mem.status == "active" # Memory 无 status 字段,用 default
|
||||
assert "确认用户意图" in ref_mem.content
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_reflection_without_memories_only_writes_reflection(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
async def fake_chat(*_args, **_kwargs):
|
||||
return '{"memories":[],"reflection":"只反思不抽记忆。"}'
|
||||
|
||||
monkeypatch.setattr("app.application.reflection._call_model", fake_chat)
|
||||
|
||||
async with AsyncSessionLocal() as session:
|
||||
character = await get_active_character_model(session)
|
||||
|
||||
start_reflection_after_turn(character.id, "session_test", "hi", "你好。")
|
||||
await drain_pending_reflections()
|
||||
|
||||
async with AsyncSessionLocal() as session:
|
||||
cands = await candidates_repo.list_memory_candidates(session, character.id, source="cycle")
|
||||
ref_mem = (
|
||||
await session.execute(
|
||||
select(Memory).where(
|
||||
Memory.character_id == character.id,
|
||||
Memory.type == "reflection",
|
||||
)
|
||||
)
|
||||
).scalar_one_or_none()
|
||||
# 无记忆候选(空 memories 数组),只有反思
|
||||
assert len(cands) == 0
|
||||
assert ref_mem is not None
|
||||
assert "只反思" in ref_mem.content
|
||||
Reference in new issue
Block a user