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:
@@ -3,6 +3,6 @@ import src.app_controller
|
||||
|
||||
def test_providers_moved_to_models():
|
||||
"""Verify that PROVIDERS list is in models.py and removed from AppController."""
|
||||
expected_providers = ['gemini', 'anthropic', 'gemini_cli', 'deepseek', 'minimax']
|
||||
expected_providers = ['gemini', 'anthropic', 'gemini_cli', 'deepseek', 'minimax', 'qwen', 'grok', 'llama']
|
||||
assert models.PROVIDERS == expected_providers
|
||||
assert not hasattr(src.app_controller.AppController, 'PROVIDERS')
|
||||
@@ -0,0 +1,23 @@
|
||||
"""Verify PROVIDERS is defined in src.ai_client (the source of truth)
|
||||
and re-exported from src.models (backward compat shim).
|
||||
|
||||
Per the follow-up track's Naming Convention (HARD RULE), PROVIDERS
|
||||
lives in src/ai_client.py. src/models.py keeps a re-export
|
||||
shim so existing import sites don't break.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
import src.models as models
|
||||
import src.ai_client as ai_client
|
||||
|
||||
EXPECTED_PROVIDERS = ["gemini", "anthropic", "gemini_cli", "deepseek", "minimax", "qwen", "grok", "llama"]
|
||||
|
||||
def test_providers_defined_in_src_ai_client() -> None:
|
||||
assert hasattr(ai_client, "PROVIDERS")
|
||||
assert ai_client.PROVIDERS == EXPECTED_PROVIDERS
|
||||
|
||||
def test_providers_reexported_from_src_models() -> None:
|
||||
assert hasattr(models, "PROVIDERS")
|
||||
assert models.PROVIDERS == EXPECTED_PROVIDERS
|
||||
|
||||
def test_providers_same_object_in_both_modules() -> None:
|
||||
assert models.PROVIDERS is ai_client.PROVIDERS
|
||||
Reference in New Issue
Block a user