feat(agent): add redis short-term user context cache and align tests

This commit is contained in:
qzl
2026-03-06 12:02:10 +08:00
parent fb8f21bcf3
commit c5ccfc4b88
34 changed files with 2073 additions and 263 deletions
@@ -155,6 +155,98 @@ async def test_run_then_resume_persists_messages_and_session_state(
await cleanup_session.commit()
@pytest.mark.asyncio
async def test_run_service_embeds_profile_settings_in_runtime_system_prompt(
monkeypatch: pytest.MonkeyPatch,
) -> None:
captured: dict[str, object] = {}
session_uuid = uuid.uuid4()
agent_type = f"AAA_TEST_{uuid.uuid4().hex[:8]}"
original_profile: Profile | None = None
def _fake_execute(self, *, user_input: str, system_prompt: str | None = None):
captured["user_input"] = user_input
captured["system_prompt"] = system_prompt
return {
"assistant_text": "Mocked answer",
"prompt_tokens": 11,
"completion_tokens": 7,
"total_tokens": 18,
"cost": 0.0025,
"agui_events": [],
}
monkeypatch.setattr(
"core.agent.infrastructure.crewai.runtime.CrewAIRuntime.execute",
_fake_execute,
)
await engine.dispose()
async with AsyncSessionLocal() as lookup_session:
owner_row = await lookup_session.execute(select(Profile.id).limit(1))
owner_id = owner_row.scalar_one_or_none()
if owner_id is None:
pytest.skip("No profile owner available in local database")
original_profile = await lookup_session.get(Profile, owner_id)
llm_row = await lookup_session.execute(
select(Llm.id, LlmFactory.name)
.join(LlmFactory, LlmFactory.id == Llm.factory_id)
.where(LlmFactory.name.in_(("dashscope", "deepseek", "moonshot")))
.limit(1)
)
llm_record = llm_row.one_or_none()
if llm_record is None:
pytest.skip("No supported llm provider available in local database")
llm_id = llm_record[0]
try:
async with AsyncSessionLocal() as seed_session:
seed_session.add(
SystemAgents(agent_type=agent_type, llm_id=llm_id, status="active")
)
profile = await seed_session.get(Profile, owner_id)
assert profile is not None
profile.username = "demo-user"
profile.bio = "hello\nworld"
profile.settings = {
"preferences": {
"interface_language": "zh-CN",
"ai_language": "en-US",
"timezone": "Asia/Shanghai",
"country": "CN",
}
}
seed_session.add(AgentChatSession(id=session_uuid, user_id=owner_id))
await seed_session.commit()
result = await RunService().run(session_id=str(session_uuid), user_input="hello")
assert result["persisted"] is True
assert captured["user_input"] == "hello"
system_prompt = captured["system_prompt"]
assert isinstance(system_prompt, str)
assert "# USER_PROFILE (JSON)" in system_prompt
assert '"ai_language":"en-US"' in system_prompt
assert '"timezone":"Asia/Shanghai"' in system_prompt
assert '"country":"CN"' in system_prompt
finally:
await engine.dispose()
async with AsyncSessionLocal() as cleanup_session:
if original_profile is not None:
profile = await cleanup_session.get(Profile, owner_id)
if profile is not None:
profile.username = original_profile.username
profile.bio = original_profile.bio
profile.settings = original_profile.settings
await cleanup_session.execute(
delete(AgentChatSession).where(AgentChatSession.id == session_uuid)
)
await cleanup_session.execute(
delete(SystemAgents).where(SystemAgents.agent_type == agent_type)
)
await cleanup_session.commit()
@pytest.mark.asyncio
async def test_soft_delete_session_cascades_to_messages() -> None:
session_uuid = uuid.uuid4()