dashboard-nanobot/backend/api/system_router.py

121 lines
4.2 KiB
Python

from typing import Any, Dict
from fastapi import APIRouter, HTTPException
from sqlmodel import Session, select
from core.database import engine, get_session
from core.settings import DATABASE_ENGINE, PANEL_ACCESS_PASSWORD, REDIS_ENABLED, REDIS_PREFIX, REDIS_URL
from core.utils import _get_default_system_timezone
from models.bot import BotInstance
from schemas.system import PanelLoginRequest, SystemTemplatesUpdateRequest
from core.cache import cache
from services.platform_service import get_platform_settings_snapshot, get_speech_runtime_settings
from services.template_service import (
get_agent_md_templates,
get_topic_presets,
update_agent_md_templates,
update_topic_presets,
)
router = APIRouter()
@router.get("/api/panel/auth/status")
def get_panel_auth_status():
configured = str(PANEL_ACCESS_PASSWORD or "").strip()
return {"enabled": bool(configured)}
@router.post("/api/panel/auth/login")
def panel_login(payload: PanelLoginRequest):
configured = str(PANEL_ACCESS_PASSWORD or "").strip()
if not configured:
return {"success": True, "enabled": False}
supplied = str(payload.password or "").strip()
if supplied != configured:
raise HTTPException(status_code=401, detail="Invalid panel access password")
return {"success": True, "enabled": True}
@router.get("/api/system/defaults")
def get_system_defaults():
md_templates = get_agent_md_templates()
platform_settings = get_platform_settings_snapshot()
speech_settings = get_speech_runtime_settings()
return {
"templates": md_templates,
"limits": {
"upload_max_mb": platform_settings.upload_max_mb,
},
"workspace": {
"download_extensions": list(platform_settings.workspace_download_extensions),
"allowed_attachment_extensions": list(platform_settings.allowed_attachment_extensions),
},
"bot": {
"system_timezone": _get_default_system_timezone(),
},
"chat": {
"pull_page_size": platform_settings.chat_pull_page_size,
"page_size": platform_settings.page_size,
"command_auto_unlock_seconds": platform_settings.command_auto_unlock_seconds,
},
"topic_presets": get_topic_presets().get("presets", []),
"speech": {
"enabled": speech_settings["enabled"],
"model": speech_settings["model"],
"device": speech_settings["device"],
"max_audio_seconds": speech_settings["max_audio_seconds"],
"default_language": speech_settings["default_language"],
},
}
@router.get("/api/system/templates")
def get_system_templates():
return {
"agent_md_templates": get_agent_md_templates(),
"topic_presets": get_topic_presets(),
}
@router.put("/api/system/templates")
def update_system_templates(payload: SystemTemplatesUpdateRequest):
if payload.agent_md_templates is not None:
update_agent_md_templates(payload.agent_md_templates.model_dump())
if payload.topic_presets is not None:
try:
update_topic_presets(payload.topic_presets)
except ValueError as exc:
raise HTTPException(status_code=400, detail=str(exc)) from exc
return {
"status": "ok",
"agent_md_templates": get_agent_md_templates(),
"topic_presets": get_topic_presets(),
}
@router.get("/api/health")
def get_health():
try:
with Session(engine) as session:
session.exec(select(BotInstance).limit(1)).first()
return {"status": "ok", "database": DATABASE_ENGINE}
except Exception as e:
raise HTTPException(status_code=503, detail=f"database check failed: {e}")
@router.get("/api/health/cache")
def get_cache_health():
redis_url = str(REDIS_URL or "").strip()
configured = bool(REDIS_ENABLED and redis_url)
client_enabled = bool(getattr(cache, "enabled", False))
reachable = bool(cache.ping()) if client_enabled else False
status = "ok"
if configured and not reachable:
status = "degraded"
return {
"status": status,
"cache": {
"configured": configured,
"enabled": client_enabled,
"reachable": reachable,
"prefix": REDIS_PREFIX,
},
}