from __future__ import annotations from typing import Any import pytest from src.models.drift import DriftIntent from src.services import openclaw as openclaw_module from src.services.drift_interpreter import NemotronDriftInterpreter class _FakeOpenClaw: def __init__(self) -> None: self.alert_context: dict[str, Any] | None = None async def call( self, prompt: str, alert_context: dict[str, Any] | None = None, ) -> tuple[str, str, bool]: self.alert_context = alert_context return ( '{"intent":"automated_change","explanation":"HPA 自動調整","risk":"LOW","confidence":0.8}', "ollama_gcp_a", True, ) @pytest.mark.asyncio async def test_drift_interpreter_declares_ollama_first_governance_lane( monkeypatch: pytest.MonkeyPatch, ) -> None: fake_openclaw = _FakeOpenClaw() monkeypatch.setattr(openclaw_module, "get_openclaw", lambda: fake_openclaw) result = await NemotronDriftInterpreter()._call_nemotron("請分析漂移") assert result.intent == DriftIntent.AUTOMATED_CHANGE assert fake_openclaw.alert_context is not None assert fake_openclaw.alert_context["enforce_ollama_first"] is True assert fake_openclaw.alert_context["task_type"] == "diagnose" assert fake_openclaw.alert_context["allow_gcp_heavy_model"] is True def test_drift_interpreter_strips_think_blocks_before_json_parse() -> None: result = NemotronDriftInterpreter()._parse_response( """ 先判斷 replicas 變化是否為 HPA。 { "intent": "automated_change", "explanation": "replicas 變化通常是 HPA 自動調整", "risk": "LOW", "confidence": 0.72 } """ ) assert result.intent == DriftIntent.AUTOMATED_CHANGE assert result.risk == "LOW" assert result.confidence == 0.72 def test_drift_interpreter_extracts_json_from_markdown() -> None: result = NemotronDriftInterpreter()._parse_response( """ 以下為判斷: ```json {"intent":"human_error","explanation":"欄位異常變更","risk":"MEDIUM","confidence":0.61} ``` """ ) assert result.intent == DriftIntent.HUMAN_ERROR assert result.risk == "MEDIUM" assert result.confidence == 0.61