- Replay and memoir-submit responses include started/finished UTC and elapsed_ms; Phase1 poll exposes Redis-backed submit time and elapsed_ms_since_submit. - Phase1 batch LLM splits segments by memoir_phase1_batch_llm_chunk_size with bisect fallback per chunk; Playground shows server timings. Made-with: Cursor
72 lines
2.3 KiB
Python
72 lines
2.3 KiB
Python
"""replay/conversation 响应携带服务端 elapsed 字段。"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from datetime import datetime, timezone
|
|
|
|
import pytest
|
|
from httpx import ASGITransport, AsyncClient
|
|
|
|
from app.features.evaluation.internal_auth import get_internal_eval_principal
|
|
from app.features.evaluation.replay_service import ReplayServerTiming
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_replay_conversation_includes_server_elapsed_ms(
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
) -> None:
|
|
from fastapi import FastAPI
|
|
|
|
monkeypatch.setattr(
|
|
"app.core.config.settings.internal_eval_api_key",
|
|
"secret",
|
|
raising=False,
|
|
)
|
|
from app.features.evaluation.deps import get_replay_conversation_service
|
|
from app.features.evaluation.router import router
|
|
|
|
t0 = datetime(2026, 4, 9, 10, 0, 0, tzinfo=timezone.utc)
|
|
t1 = datetime(2026, 4, 9, 10, 0, 1, tzinfo=timezone.utc)
|
|
|
|
class _FakeReplay:
|
|
async def replay_utterances(self, **kwargs):
|
|
return (
|
|
1,
|
|
["seg-a"],
|
|
ReplayServerTiming(
|
|
started_at_utc=t0,
|
|
finished_at_utc=t1,
|
|
elapsed_ms=150,
|
|
),
|
|
)
|
|
|
|
app = FastAPI()
|
|
app.include_router(router, prefix="/internal/api/evaluation")
|
|
|
|
async def _override_auth():
|
|
from app.features.evaluation.internal_auth import InternalEvalPrincipal
|
|
|
|
return InternalEvalPrincipal()
|
|
|
|
app.dependency_overrides[get_internal_eval_principal] = _override_auth
|
|
app.dependency_overrides[get_replay_conversation_service] = lambda: _FakeReplay()
|
|
|
|
transport = ASGITransport(app=app)
|
|
async with AsyncClient(transport=transport, base_url="http://t") as client:
|
|
r = await client.post(
|
|
"/internal/api/evaluation/replay/conversation",
|
|
headers={"X-Internal-Eval-Key": "secret"},
|
|
json={
|
|
"conversation_id": "00000000-0000-0000-0000-000000000099",
|
|
"user_utterances": ["hi"],
|
|
"flush_memoir_after": False,
|
|
"skip_memoir": True,
|
|
"skip_tts": True,
|
|
},
|
|
)
|
|
assert r.status_code == 200
|
|
body = r.json()
|
|
assert body["elapsed_ms"] == 150
|
|
assert body["started_at_utc"] is not None
|
|
assert body["finished_at_utc"] is not None
|