feat(ai): add guarded Claude fallback route
This commit is contained in:
@@ -21,6 +21,10 @@ def _explicitly_enable_gemini_environment(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
monkeypatch.setenv("ENABLE_GEMINI", "true")
|
||||
monkeypatch.setenv("ENABLE_CLAUDE", "false")
|
||||
monkeypatch.setattr(openclaw_module.settings, "CLAUDE_API_KEY", "")
|
||||
monkeypatch.setattr(openclaw_module.settings, "CLAUDE_EXECUTION_MODE", "shadow")
|
||||
monkeypatch.setattr(openclaw_module.settings, "CLAUDE_CANARY_PERCENT", 0)
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -105,6 +109,23 @@ class _FakeExecutor:
|
||||
)
|
||||
|
||||
|
||||
def _prepared_paid_alert_context(
|
||||
service: OpenClawService,
|
||||
**overrides: Any,
|
||||
) -> dict[str, Any]:
|
||||
context = service._prepare_paid_cloud_route_context(
|
||||
{
|
||||
"incident_id": "INC-1",
|
||||
"alertname": "HostHighCpuLoad",
|
||||
"source": "test-alert-producer",
|
||||
"target_resource": "node-110",
|
||||
**overrides,
|
||||
}
|
||||
)
|
||||
assert context is not None
|
||||
return context
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_alert_context_uses_exact_ollama_lane_then_gemini(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
@@ -290,7 +311,7 @@ async def test_alert_context_sorts_ollama_lane_and_drops_cloud_providers(
|
||||
service = object.__new__(OpenClawService)
|
||||
provider_order = await service._resolve_alert_provider_order(
|
||||
task_type="diagnose",
|
||||
alert_context={"incident_id": "INC-1", "alertname": "HostHighCpuLoad"},
|
||||
alert_context=_prepared_paid_alert_context(service),
|
||||
)
|
||||
|
||||
assert provider_order == ["ollama_gcp_a", "ollama_gcp_b", "ollama_local"]
|
||||
@@ -309,13 +330,46 @@ async def test_alert_context_drops_cloud_insertions_before_gemini_backup(
|
||||
service = object.__new__(OpenClawService)
|
||||
provider_order = await service._resolve_alert_provider_order(
|
||||
task_type="diagnose",
|
||||
alert_context={"incident_id": "INC-1", "alertname": "HostHighCpuLoad"},
|
||||
alert_context=_prepared_paid_alert_context(service),
|
||||
cloud_provider_order=["claude", "openclaw_nemo", "gemini", "ollama"],
|
||||
)
|
||||
|
||||
assert provider_order == ["ollama_gcp_a", "ollama_gcp_b", "ollama_local", "gemini"]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_alert_context_appends_enabled_claude_before_gemini(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
monkeypatch.setattr(openclaw_module.settings, "ALERT_AI_ALLOW_CLOUD_FALLBACK", True)
|
||||
monkeypatch.setattr(openclaw_module.settings, "ALERT_AI_ENFORCE_OLLAMA_FIRST", True)
|
||||
monkeypatch.setattr(openclaw_module.settings, "CLAUDE_API_KEY", "configured-test-value")
|
||||
monkeypatch.setattr(openclaw_module.settings, "CLAUDE_EXECUTION_MODE", "production")
|
||||
monkeypatch.setattr(openclaw_module.settings, "CLAUDE_CANARY_PERCENT", 0)
|
||||
monkeypatch.setattr(openclaw_module.settings, "GEMINI_API_KEY", "configured-test-value")
|
||||
monkeypatch.setenv("ENABLE_CLAUDE", "true")
|
||||
monkeypatch.setattr(ai_control_module, "is_provider_disabled", AsyncMock(return_value=False))
|
||||
monkeypatch.setattr(
|
||||
openclaw_module,
|
||||
"get_ollama_failover_manager",
|
||||
lambda: _UnorderedFailoverManager(),
|
||||
)
|
||||
|
||||
service = object.__new__(OpenClawService)
|
||||
provider_order = await service._resolve_alert_provider_order(
|
||||
task_type="diagnose",
|
||||
alert_context=_prepared_paid_alert_context(service),
|
||||
)
|
||||
|
||||
assert provider_order == [
|
||||
"ollama_gcp_a",
|
||||
"ollama_gcp_b",
|
||||
"ollama_local",
|
||||
"claude",
|
||||
"gemini",
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_disabled_gemini_is_not_readded_to_alert_route(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
|
||||
Reference in New Issue
Block a user