"""Routing-Endpoints: Lane-Summary (chat/coding) + UI-editierbare Policy (hot-reload).""" from fastapi import APIRouter, HTTPException from pydantic import BaseModel from services import gateway from services.routing_policy import policy_meta, save_policy router = APIRouter(prefix="/api") @router.get("/routing") def routing() -> dict: return {**gateway.routing_summary(), "gateway_reachable": gateway.gateway_reachable()} @router.get("/routing/policy") def get_policy() -> dict: """Aktuelle Policy + Defaults (für „Zurücksetzen“) + Feld-Spezifikation für den Editor.""" return policy_meta() class PolicyPatch(BaseModel): fast: str | None = None heavy: str | None = None coder: str | None = None coder_lite: str | None = None heavy_chars: int | None = None coding_escalate_chars: int | None = None fast_no_think: bool | None = None @router.put("/routing/policy") def put_policy(patch: PolicyPatch) -> dict: """Teil-Update der Routing-Policy. Validiert, persistiert atomar, sofort wirksam (hot-reload).""" fields = {k: v for k, v in patch.model_dump().items() if v is not None} if not fields: raise HTTPException(status_code=400, detail="Keine Felder zum Aktualisieren.") try: new_policy = save_policy(fields) except (ValueError, TypeError) as e: raise HTTPException(status_code=400, detail=f"Ungültige Policy: {e}") return {"policy": new_policy}