初始化提交

This commit is contained in:
chenxin committed 2026-08-21 16:00:13 +08:00
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