feat: add LiteLLM gateway scaffold and dashboard health probe
Deploy Dashboard (Dev) / deploy-dev (push) Successful in 2m11s

Introduce a localhost-only LiteLLM service template and expose a protected dashboard health endpoint for operational visibility, while adding cc-connect mobile bridge templates with conservative defaults.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Gan, Jimmy
2026-03-02 01:08:12 +08:00
parent bd2a166253
commit ed4090a910
9 changed files with 193 additions and 1 deletions
+3
View File
@@ -44,6 +44,9 @@ CORS_ORIGINS = os.environ.get("CORS_ORIGINS", "https://nas.jimmygan.com,https://
# Chat Summary
CHAT_SUMMARY_DB = os.environ.get("CHAT_SUMMARY_DB", "/app/data/chat-summarizer/chat_summary.db")
# LiteLLM
LITELLM_URL = os.environ.get("LITELLM_URL", "http://127.0.0.1:4005")
# OpenClaw
OPENCLAW_GATEWAY_TOKEN = os.environ.get("OPENCLAW_GATEWAY_TOKEN", "")
+3 -1
View File
@@ -6,7 +6,7 @@ from fastapi.responses import JSONResponse
from slowapi import Limiter
from slowapi.util import get_remote_address
from slowapi.errors import RateLimitExceeded
from routers import docker_router, gitea, files, terminal, system, auth, chat_summary, security, passkey, totp
from routers import docker_router, gitea, files, terminal, system, auth, chat_summary, security, passkey, totp, litellm
import auth as auth_module
from rbac import require_page, require_write
@@ -179,6 +179,8 @@ app.include_router(files.router, prefix="/api/files",
dependencies=[Depends(_inject_user), Depends(require_page("files")), Depends(require_write())])
app.include_router(system.router, prefix="/api/system",
dependencies=[Depends(_inject_user), Depends(require_page("dashboard"))])
app.include_router(litellm.router, prefix="/api/litellm",
dependencies=[Depends(_inject_user), Depends(require_page("dashboard"))])
app.include_router(chat_summary.router, prefix="/api/chat-summary",
dependencies=[Depends(_inject_user), Depends(require_page("chat-digest"))])
app.include_router(security.router, prefix="/api/security",
+40
View File
@@ -0,0 +1,40 @@
import time
import httpx
from fastapi import APIRouter
from config import LITELLM_URL
router = APIRouter()
@router.get("/health")
async def litellm_health():
timeout = httpx.Timeout(2.0)
checks = ("/health", "/v1/models")
last_error = None
async with httpx.AsyncClient(timeout=timeout) as client:
for path in checks:
url = f"{LITELLM_URL.rstrip('/')}{path}"
started = time.perf_counter()
try:
response = await client.get(url)
latency_ms = round((time.perf_counter() - started) * 1000, 1)
if response.is_success:
return {
"ok": True,
"status": "up",
"latency_ms": latency_ms,
"endpoint": path,
"http_status": response.status_code,
}
last_error = f"{path} returned {response.status_code}"
except Exception as exc:
last_error = str(exc)
return {
"ok": False,
"status": "down",
"latency_ms": None,
"endpoint": None,
"error": last_error or "health check failed",
}