snipe/app/llm/router.py
pyr0ball cc997c09e3 refactor: rename CF_ORCH_URL → GPU_SERVER_URL (backward-compat alias kept)
GPU_SERVER_URL is the self-explanatory name a self-hoster can understand
without knowing CircuitForge internals. CF_ORCH_URL continues to work as
a drop-in fallback alias (runner.py, main.py both check GPU_SERVER_URL
first, then CF_ORCH_URL).

Updated everywhere the env var is referenced or documented:
- app/tasks/runner.py
- api/main.py
- app/llm/router.py
- .env.example (alias note added)
- compose.override.yml
- compose.cloud.yml
- config/llm.cloud.yaml
- tests/test_tasks/test_runner.py (primary key updated; 13/13 still pass)

Follows the GPU_SERVER_URL convention established in kiwi (see kiwi
app/core/config.py).

Closes: #55
2026-05-21 15:05:27 -07:00

36 lines
1.2 KiB
Python

# app/llm/router.py
# BSL 1.1 License
"""
Snipe LLMRouter shim — tri-level config path priority.
Config lookup order:
1. <repo>/config/llm.yaml — per-install local override
2. ~/.config/circuitforge/llm.yaml — user-level config (circuitforge-core default)
3. env-var auto-config (ANTHROPIC_API_KEY, OPENAI_API_KEY, OLLAMA_HOST, GPU_SERVER_URL)
"""
from pathlib import Path
from circuitforge_core.llm import LLMRouter as _CoreLLMRouter
_REPO_CONFIG = Path(__file__).parent.parent.parent / "config" / "llm.yaml"
_USER_CONFIG = Path.home() / ".config" / "circuitforge" / "llm.yaml"
class LLMRouter(_CoreLLMRouter):
"""Snipe-specific LLMRouter with tri-level config resolution.
Explicit ``config_path`` bypasses the lookup (useful in tests).
"""
def __init__(self, config_path: Path | None = None) -> None:
if config_path is not None:
super().__init__(config_path)
return
if _REPO_CONFIG.exists():
super().__init__(_REPO_CONFIG)
elif _USER_CONFIG.exists():
super().__init__(_USER_CONFIG)
else:
# No yaml — let circuitforge-core env-var auto-config handle it.
super().__init__()