refactor(ai_client): move PROVIDERS to src/ai_client.py; re-export via models.__getattr__
Phase 2 tasks 2.1 + 2.2 + 2.3a of the follow-up track. PROVIDERS now lives in src/ai_client.py:56 (the canonical home for AI-client-related constants per the HARD RULE on src/ files). The list includes all 8 vendors: gemini, anthropic, gemini_cli, deepseek, minimax, qwen, grok, llama. Backward compat: src/models.py:PROVIDERS is exposed via a module- level __getattr__ (PEP 562) that lazy-imports from src.ai_client. The lazy approach was needed because src.ai_client imports ToolPreset/BiasProfile/Tool from src.models at line 50, so a top-level 'from src.ai_client import PROVIDERS' in models.py would deadlock. Adding a branch to the existing __getattr__ in models.py (which also handles pydantic class factories) is the surgical fix. tests/test_provider_curation.py was stale (expected 5 providers from before Qwen/Grok/Llama were added). Updated to 8. New test: tests/test_providers_source_of_truth.py asserts: - src.ai_client.PROVIDERS exists and matches the 8-provider list - src.models.PROVIDERS still works (re-export) - Both modules reference the SAME object (no drift) Green confirmed: 4 provider tests pass.
This commit is contained in:
+11
-1
@@ -53,7 +53,14 @@ from src.paths import get_config_path
|
||||
|
||||
#region: Constants
|
||||
|
||||
PROVIDERS: List[str] = ["gemini", "anthropic", "gemini_cli", "deepseek", "minimax", "qwen", "grok", "llama"]
|
||||
# PROVIDERS is the source of truth in src/ai_client.py (per the
|
||||
# follow-up track's Naming Convention HARD RULE). Lazy-loaded
|
||||
# via the __getattr__ defined later in this module to break the
|
||||
# circular import (src.ai_client imports ToolPreset/BiasProfile/
|
||||
# Tool from this module at line 50, so a top-level 'from
|
||||
# src.ai_client import PROVIDERS' here would deadlock). The
|
||||
# audit script scripts/audit_providers_source_of_truth.py
|
||||
# verifies PROVIDERS is declared in src/ai_client.py and not here.
|
||||
|
||||
AGENT_TOOL_NAMES: List[str] = [
|
||||
"run_powershell",
|
||||
@@ -251,6 +258,9 @@ _PYDANTIC_CLASS_FACTORIES: dict[str, callable] = {
|
||||
}
|
||||
|
||||
def __getattr__(name: str) -> Any:
|
||||
if name == "PROVIDERS":
|
||||
from src.ai_client import PROVIDERS as _PROVIDERS
|
||||
return _PROVIDERS
|
||||
if name in _PYDANTIC_CLASS_FACTORIES:
|
||||
cls = _PYDANTIC_CLASS_FACTORIES[name]()
|
||||
globals()[name] = cls
|
||||
|
||||
Reference in New Issue
Block a user