PMFlow/backend/tests/test_pmflow_ai_answer_runti...

82 lines
3.2 KiB
Python

import inspect
import time
from types import SimpleNamespace
import pytest
import app.services.pmflow_ai_turn_runtime_service as runtime_module
from app.schemas.rag import RAGAskRequest
from app.services.customer_answer_presentation_service import CustomerAnswerPresentationService
from app.services.pmflow_ai_turn_runtime_service import PMFlowAITurnRuntimeService
def _service() -> PMFlowAITurnRuntimeService:
return PMFlowAITurnRuntimeService(object(), tenant_id=1)
def _open_judgement_state():
return _service().build_initial_turn_state(
request=RAGAskRequest(question="这个方向怎么样"),
route_plan={},
turn_hypothesis={
"normalized_goal": "判断方向",
"desired_outcome": "基于当前状态给出受控判断",
"answer_shape": "strategic_judgement",
"can_answer_with_assumptions": True,
"goal_frames": [
{
"frame_id": "open-direction",
"operation_kind": "judge_direction",
"target_scope": {"scope_type": "current_space", "binding_strength": "surface"},
"target_object_requirement": "none",
"source_policy": "internal",
"answer_shape": "strategic_judgement",
"confidence": 0.72,
}
],
"operation_gaps": [],
},
)
def test_packet_ap_removes_legacy_answer_sanitizer_from_renderer() -> None:
source = inspect.getsource(PMFlowAITurnRuntimeService._execute_answer_renderer_candidate)
assert "_sanitize_state_answer" not in source
assert not hasattr(runtime_module, "_sanitize_state_answer")
@pytest.mark.asyncio
async def test_packet_ap_quality_gate_fail_closed_when_revision_still_fails(monkeypatch) -> None:
service = _service()
state = _open_judgement_state()
async def bad_render(*, request, turn_state):
_ = request, turn_state
return "TurnState evidence_findings 仍然被直接展示。"
def bad_fallback(*, question, turn_state):
_ = question, turn_state
return "PMFlowAITurnState runtime_steps 又泄漏了一次。"
monkeypatch.setattr(service, "_render_answer_from_registry", bad_render)
monkeypatch.setattr(runtime_module, "_render_state_answer_fallback", bad_fallback)
payload = await service._run_state_answer_synthesis(
request=RAGAskRequest(question="这个方向怎么样"),
current_user=SimpleNamespace(id=1, tenant_id=1),
route_plan={},
turn_state=state,
presentation_service=CustomerAnswerPresentationService(object(), tenant_id=1),
started_at=time.perf_counter(),
)
finding_types = {item["finding_type"] for item in payload["answer_runtime_packet"]["quality_findings"]}
assert "internal_runtime_leak" in finding_types
assert "post_revision_quality_failed" in finding_types
assert "TurnState" not in payload["answer"]
assert "evidence_findings" not in payload["answer"]
assert "PMFlowAITurnState" not in payload["answer"]
assert "可直接展示" in payload["answer"]
assert any(step.key == "block_answer_quality" for step in state.runtime_steps)