feat(awooop): surface ai provider route status
This commit is contained in:
@@ -7,11 +7,16 @@ import pytest
|
||||
from fastapi import HTTPException
|
||||
|
||||
from src.api.v1.platform.operator_runs import (
|
||||
AiRouteStatusResponse,
|
||||
ListApprovalsResponse,
|
||||
ListCallbackRepliesResponse,
|
||||
ListRunsResponse,
|
||||
)
|
||||
from src.services.ollama_failover_manager import OllamaEndpoint, OllamaRoutingResult
|
||||
from src.services.ollama_health_monitor import HealthReport, HealthStatus
|
||||
from src.services.platform_operator_service import (
|
||||
_ai_route_health_map,
|
||||
_ai_route_policy_order,
|
||||
_build_awooop_status_chain,
|
||||
_callback_reply_event_item,
|
||||
_callback_reply_summary_matches_status,
|
||||
@@ -28,6 +33,7 @@ from src.services.platform_operator_service import (
|
||||
_run_callback_reply_summary,
|
||||
_run_remediation_list_summary,
|
||||
_timeline_sort_key,
|
||||
_validate_ai_route_workload,
|
||||
_validate_callback_reply_action_filter,
|
||||
_validate_callback_reply_status_filter,
|
||||
)
|
||||
@@ -725,3 +731,101 @@ def test_timeline_sort_key_normalizes_datetime_and_iso_string() -> None:
|
||||
"2026-05-14T10:00:01",
|
||||
"2026-05-14T10:00:02+00:00",
|
||||
]
|
||||
|
||||
|
||||
def test_ai_route_policy_order_exposes_global_ollama_then_gemini() -> None:
|
||||
policy = _ai_route_policy_order("deep_rca")
|
||||
|
||||
assert [item["provider_name"] for item in policy] == [
|
||||
"ollama_gcp_a",
|
||||
"ollama_gcp_b",
|
||||
"ollama_local",
|
||||
"gemini",
|
||||
]
|
||||
assert policy[-1]["role"] == "final_fallback"
|
||||
assert policy[-1]["runtime"] == "cloud"
|
||||
|
||||
|
||||
def test_ai_route_health_map_marks_standby_as_not_checked() -> None:
|
||||
route = OllamaRoutingResult(
|
||||
primary=OllamaEndpoint(
|
||||
url="http://gcp-a:11434",
|
||||
provider_name="ollama_gcp_a",
|
||||
model="qwen3:14b",
|
||||
),
|
||||
fallback_chain=[
|
||||
OllamaEndpoint(
|
||||
url="http://gcp-b:11434",
|
||||
provider_name="ollama_gcp_b",
|
||||
model="qwen3:14b",
|
||||
),
|
||||
OllamaEndpoint(
|
||||
url="http://local-111:11434",
|
||||
provider_name="ollama_local",
|
||||
model="qwen3:14b",
|
||||
),
|
||||
],
|
||||
routing_reason="primary healthy",
|
||||
health_gcp_a=HealthReport(
|
||||
status=HealthStatus.HEALTHY,
|
||||
host="http://gcp-a:11434",
|
||||
latency_ms=123.4,
|
||||
reason="ok",
|
||||
),
|
||||
health_gcp_b=None,
|
||||
health_local=None,
|
||||
)
|
||||
|
||||
health = _ai_route_health_map(route)
|
||||
|
||||
assert health["ollama_gcp_a"]["status"] == "healthy"
|
||||
assert health["ollama_gcp_a"]["checked"] is True
|
||||
assert health["ollama_gcp_b"]["status"] == "not_checked"
|
||||
assert health["ollama_local"]["reason"] == "standby_not_checked_primary_healthy"
|
||||
|
||||
|
||||
def test_ai_route_status_response_preserves_route_fields() -> None:
|
||||
response = AiRouteStatusResponse.model_validate({
|
||||
"schema_version": "awooop_ai_route_status_v1",
|
||||
"workload_type": "deep_rca",
|
||||
"policy_order": _ai_route_policy_order("deep_rca"),
|
||||
"selected_provider": "ollama_gcp_a",
|
||||
"selected_url": "http://gcp-a:11434",
|
||||
"selected_model": "qwen3:14b",
|
||||
"fallback_chain": [
|
||||
{
|
||||
"priority": 2,
|
||||
"provider_name": "ollama_gcp_b",
|
||||
"url": "http://gcp-b:11434",
|
||||
"model": "qwen3:14b",
|
||||
"runtime": "ollama",
|
||||
}
|
||||
],
|
||||
"route_reason": "primary healthy",
|
||||
"route_source": "ollama_failover_manager",
|
||||
"route_error": None,
|
||||
"health": {
|
||||
"ollama_gcp_a": {
|
||||
"status": "healthy",
|
||||
"host": "http://gcp-a:11434",
|
||||
"latency_ms": 123.4,
|
||||
"reason": "ok",
|
||||
"checked_at": 0,
|
||||
"from_cache": False,
|
||||
"checked": True,
|
||||
},
|
||||
},
|
||||
"checked_at": datetime(2026, 5, 19, 12, 0, 0),
|
||||
})
|
||||
|
||||
dumped = response.model_dump(mode="json")
|
||||
assert dumped["policy_order"][-1]["provider_name"] == "gemini"
|
||||
assert dumped["selected_provider"] == "ollama_gcp_a"
|
||||
|
||||
|
||||
def test_ai_route_workload_validation_rejects_unknown_value() -> None:
|
||||
assert _validate_ai_route_workload(" hermes ") == "hermes"
|
||||
with pytest.raises(HTTPException) as exc_info:
|
||||
_validate_ai_route_workload("charge_money")
|
||||
|
||||
assert "Unsupported workload_type" in str(exc_info.value.detail)
|
||||
|
||||
Reference in New Issue
Block a user