@samitouri / QOSami_Agents_Zero / commits / 4b906561
Fork 0

Agent Zero AI framework

Remove obsolete preset API key warning

Stop scanning every global model preset for missing credentials when building Welcome banners. Keep readiness scoped to the effective model configuration so first-send setup remains in the deferred chat gate. Add regression coverage for unused OpenRouter presets and document the boundary.

Alessandro committed Jul 28, 2026 at 21:28 UTC 4b906561cd19ab6b625c69d814ad550b49afe6f3
3 files changed +9 -52
plugins/_model_config/AGENTS.md
+1
@@ -19,6 +19,7 @@
19 - Preserve scoped plugin resolution order and fall back invalid or missing scope/chat references to `Default`.
20 - Project Settings `llm` payloads are owned here through the generic `helpers.projects` project extension-data hooks; keep project helper code agnostic to `_model_config` paths, presets, and inheritance rules.
21 - Keep provider metadata and API-key checks safe around secrets.
22 +- Check API-key readiness only for the effective model configuration; unused global presets must not produce Welcome-screen warnings.
23 - Coordinate OAuth-backed providers with `_oauth` instead of hardcoding provider-specific auth here.
24 - `model_config_get` exposes `model_configured` as a derived chat-model readiness flag from provider, model name, and API-key availability.
25 - Non-default presets may inherit omitted slots or durable tuning from `Default`, but must replace or clear per-slot `kwargs` so provider-specific extra params never leak across model providers.
plugins/_model_config/extensions/python/banners/_20_missing_api_key.py
-48
@@ -5,7 +5,6 @@ from plugins._model_config.helpers import model_config
5 class MissingApiKeyCheck(Extension):
6 """Check if API keys are configured for selected model providers."""
7
8 - LOCAL_PROVIDERS = {"ollama", "lm_studio", "llama_cpp", "omlx", "vllm"}
8 ONBOARDING_MODAL_PATH = "/plugins/_onboarding/webui/onboarding.html"
9 ONBOARDING_CTA_TEXT = "Start Onboarding"
10
@@ -27,50 +26,3 @@ class MissingApiKeyCheck(Extension):
26 # For programmatic clients (e.g. chat composer) reusing this banner pipeline
27 "missing_providers": missing_providers,
28 })
30 -
31 - # Check preset providers for missing API keys (warning level)
32 - preset_missing = []
33 - seen = set()
34 - for preset in model_config.get_presets():
35 - preset_name = preset.get("name", "Unnamed")
36 - for slot_key, slot_label, model_type in [
37 - ("chat", "Main", "chat"),
38 - ("utility", "Utility", "chat"),
39 - ("embedding", "Embedding", "embedding"),
40 - ]:
41 - slot = preset.get(slot_key, {})
42 - provider = slot.get("provider", "")
43 - if not provider:
44 - continue
45 - provider_lower = provider.lower()
46 - identity = (provider_lower, model_type)
47 - if (
48 - provider_lower in self.LOCAL_PROVIDERS
49 - or model_type == "embedding"
50 - and provider_lower in model_config.LOCAL_EMBEDDING
51 - or identity in seen
52 - ):
53 - continue
54 - if slot.get("api_key", "").strip():
55 - continue
56 - if not model_config.has_provider_api_key(
57 - provider_lower,
58 - model_type=model_type,
59 - ):
60 - seen.add(identity)
61 - preset_missing.append(f"{preset_name}/{slot_label} ({provider})")
62 -
63 - if preset_missing:
64 - preset_list = ", ".join(preset_missing)
65 - banners.append({
66 - "id": "missing-preset-api-key",
67 - "type": "warning",
68 - "priority": 90,
69 - "title": "Missing API Key for model presets",
70 - "html": f"""No API key configured for preset models: {preset_list}.<br>
71 - These presets will not work until you provide the required API keys.""",
72 - "cta_text": self.ONBOARDING_CTA_TEXT,
73 - "cta_action": f"open-modal:{self.ONBOARDING_MODAL_PATH}",
74 - "dismissible": True,
75 - "source": "backend"
76 - })
tests/test_model_config_api_keys.py
+8 -4
@@ -90,16 +90,23 @@ def test_chat_model_configured_requires_identity_and_key(monkeypatch):
90
91
92 @pytest.mark.asyncio
93 -async def test_missing_api_key_banner_exposes_missing_providers(monkeypatch):
93 +async def test_missing_api_key_banner_exposes_only_effective_missing_providers(monkeypatch):
94 from plugins._model_config.helpers import model_config
95
96 fake = [{"model_type": "Chat Model", "provider": "openai"}]
97 monkeypatch.setattr(model_config, "get_missing_api_key_providers", lambda: fake)
98 + monkeypatch.setattr(
99 + model_config,
100 + "get_presets",
101 + lambda: [{"name": "Efficiency", "chat": {"provider": "openrouter"}}],
102 + )
103 + monkeypatch.setattr(model_config, "has_provider_api_key", lambda *args, **kwargs: False)
104
105 banners = []
106 await missing_key_banner.MissingApiKeyCheck(agent=None).execute(
107 banners=banners, frontend_context={}
108 )
109 + assert [banner["id"] for banner in banners] == ["missing-api-key"]
110 row = next(b for b in banners if b.get("id") == "missing-api-key")
111 assert row.get("missing_providers") == fake
112 assert row["cta_text"] == "Start Onboarding"
@@ -515,9 +522,6 @@ def test_provider_key_modes_for_local_and_ollama_cloud():
522 assert model_config.provider_requires_api_key("vllm") is False
523 assert model_config.provider_requires_api_key("other") is False
524 assert model_config.provider_requires_api_key("ollama_cloud") is True
518 - assert "llama_cpp" in missing_key_banner.MissingApiKeyCheck.LOCAL_PROVIDERS
519 - assert "omlx" in missing_key_banner.MissingApiKeyCheck.LOCAL_PROVIDERS
520 - assert "vllm" in missing_key_banner.MissingApiKeyCheck.LOCAL_PROVIDERS
525
526
527 def test_local_provider_defaults_are_docker_friendly():