rmi-backend/app/ai_router.py
opencode c762564d40 style(rmi-backend): complete lint cleanup — 1175→0 ruff errors
- Fix 71 invalid-syntax files (class-body newline-broken assignments)
- Add from/None chain to 307 B904 raise-without-from sites
- Add B008 ignore to ruff.toml (already in pyproject.toml)
- Noqa F401 on __init__.py re-exports (137 sites)
- Noqa E402 on deferred imports (63 sites)
- Bulk-add stdlib/FastAPI/project imports for F821 (127 sites)
- Replace ×→x, –→-, …→... in docstrings (4093 chars)
- Manual refactor of 5 SIM103/SIM116 patterns

Tests: 791 passed (66 deselected due to pre-existing Redis issues in test_rag.py)
Co-authored-by: opencode <opencode@rugmunch.io>
2026-07-06 15:43:20 +02:00

72 lines
2.3 KiB
Python

#!/usr/bin/env python3
"""
Stub AI Router - Intelligent Model-First Provider Swapping
===========================================================
Routes requests to optimal AI provider based on quota, latency, and cost.
For now, a minimal stub that delegates to OpenRouter.
"""
import base64
import os
from typing import Any
from fastapi import APIRouter
router = APIRouter(tags=["AI Router"])
# Decode base64 LLM key if present, otherwise use plain LLM_API_KEY
# (safety net: ensures key is decoded even when imported without main.py)
if os.getenv("LLM_API_KEY_B64"):
os.environ["LLM_API_KEY"] = base64.b64decode(os.getenv("LLM_API_KEY_B64")).decode()
# Model tiers (for reference, full config in ai_router.py)
MODEL_TIERS = {
"T0": {"name": "Ultra", "models": ["gpt-4o", "claude-3.5-sonnet"], "max_cost_per_1k": 0.05},
"T1": {"name": "Premium", "models": ["gpt-4-turbo", "claude-3-opus"], "max_cost_per_1k": 0.02},
"T2": {
"name": "Standard",
"models": ["gpt-3.5-turbo", "claude-3-haiku"],
"max_cost_per_1k": 0.005,
},
"T3": {"name": "Fast", "models": ["llama-3-8b", "mistral-tiny"], "max_cost_per_1k": 0.001},
"T4": {"name": "Free", "models": ["tiny-llama", "phi-2"], "max_cost_per_1k": 0.0},
}
# Providers (for reference)
PROVIDERS = {
"deepseek": {
"url": os.getenv("LLM_BASE_URL", "https://api.deepseek.com/v1/chat/completions"),
"key_env": "LLM_API_KEY",
"model": os.getenv("LLM_MODEL", "deepseek-v4-flash"),
"rpm": 100,
},
"openrouter": {
"url": "https://openrouter.ai/api/v1/chat/completions",
"key_env": "OPENROUTER_API_KEY",
"rpm": 100,
},
}
@router.post("/ai/completions")
async def ai_completions(request: dict[str, Any]):
"""AI completion via optimal provider routing."""
return {"error": "AI Router not fully configured", "provider": "openrouter"}
@router.post("/ai/chat")
async def ai_chat(request: dict[str, Any]):
"""AI chat endpoint with provider fallback."""
return {"error": "AI Router not fully configured", "provider": "openrouter"}
@router.get("/ai/providers")
async def list_providers():
"""List available AI providers."""
return {"providers": list(PROVIDERS.keys())}
@router.get("/ai/models")
async def list_models():
"""List available models by tier."""
return {"tiers": MODEL_TIERS}