71 lines
2.2 KiB
Python
71 lines
2.2 KiB
Python
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
from datetime import datetime, timezone
|
||
|
|
|
||
|
|
import pytest
|
||
|
|
|
||
|
|
from app.agents.chat.agent_turn import AgentChatTurn
|
||
|
|
from app.features.conversation.chat_turn import (
|
||
|
|
ChatTurnContext,
|
||
|
|
ChatTurnInput,
|
||
|
|
ChatTurnService,
|
||
|
|
)
|
||
|
|
|
||
|
|
|
||
|
|
class _FakeOrchestrator:
|
||
|
|
def __init__(self) -> None:
|
||
|
|
self.calls: list[dict] = []
|
||
|
|
|
||
|
|
async def process_user_message(self, **kwargs):
|
||
|
|
self.calls.append(kwargs)
|
||
|
|
return AgentChatTurn(
|
||
|
|
messages=["第一泡", "第二泡"],
|
||
|
|
skip_tts=False,
|
||
|
|
memory_retrieval_trace={"chunks": 1},
|
||
|
|
interview_state_meta={"recent_questions": ["你当时在哪里?"]},
|
||
|
|
)
|
||
|
|
|
||
|
|
|
||
|
|
@pytest.mark.asyncio
|
||
|
|
async def test_chat_turn_service_exposes_one_turn_contract() -> None:
|
||
|
|
orchestrator = _FakeOrchestrator()
|
||
|
|
service = ChatTurnService(orchestrator=orchestrator)
|
||
|
|
ts = datetime(2026, 4, 29, tzinfo=timezone.utc)
|
||
|
|
|
||
|
|
result = await service.process_turn(
|
||
|
|
ChatTurnInput(
|
||
|
|
conversation_id="conv-1",
|
||
|
|
user_message="我小时候住在河边。",
|
||
|
|
is_from_voice=True,
|
||
|
|
voice_session_id="voice-1",
|
||
|
|
user_message_timestamp=ts,
|
||
|
|
audio_duration_seconds=12,
|
||
|
|
force_skip_tts=True,
|
||
|
|
),
|
||
|
|
ChatTurnContext(
|
||
|
|
db=object(),
|
||
|
|
user=object(),
|
||
|
|
conversation=object(),
|
||
|
|
apply_extracted_profile_fn=lambda *args, **kwargs: None,
|
||
|
|
get_missing_profile_fields_fn=lambda user: [],
|
||
|
|
get_filled_profile_fields_fn=lambda user: {},
|
||
|
|
),
|
||
|
|
)
|
||
|
|
|
||
|
|
assert result.messages == ["第一泡", "第二泡"]
|
||
|
|
assert result.skip_tts is True
|
||
|
|
assert result.memory_retrieval_trace == {"chunks": 1}
|
||
|
|
assert result.interview_state_meta == {
|
||
|
|
"recent_questions": ["你当时在哪里?"]
|
||
|
|
}
|
||
|
|
assert result.decision.force_skip_tts is True
|
||
|
|
|
||
|
|
assert len(orchestrator.calls) == 1
|
||
|
|
call = orchestrator.calls[0]
|
||
|
|
assert call["conversation_id"] == "conv-1"
|
||
|
|
assert call["user_message"] == "我小时候住在河边。"
|
||
|
|
assert call["is_from_voice"] is True
|
||
|
|
assert call["voice_session_id"] == "voice-1"
|
||
|
|
assert call["user_message_timestamp"] is ts
|
||
|
|
assert call["audio_duration_seconds"] == 12
|