"""管理端下发的 LLM 运行时配置。""" from __future__ import annotations import logging from fastapi import APIRouter from pydantic import BaseModel, Field from app.config import get_settings from app.services.llm_client import get_llm from app.services.llm_runtime import get_runtime_llm, update_runtime_llm logger = logging.getLogger(__name__) router = APIRouter(prefix="/llm", tags=["llm"]) class LlmConfigUpdate(BaseModel): enabled: bool | None = True api_base_url: str | None = Field(default=None, alias="api_base_url") api_key: str | None = None model: str | None = None temperature: float | None = None # 兼容 camelCase(Spring 默认可能发 apiBaseUrl) apiBaseUrl: str | None = None apiKey: str | None = None class Config: populate_by_name = True @router.get("/config") def get_llm_config() -> dict: return get_llm().info() @router.post("/config") def set_llm_config(body: LlmConfigUpdate) -> dict: base = body.api_base_url or body.apiBaseUrl key = body.api_key if body.api_key is not None else body.apiKey # 注意:key 为 None 表示本次不改密钥;空字符串表示清空运行时密钥 rt = update_runtime_llm( enabled=body.enabled, api_base_url=base, api_key=key, model=body.model, temperature=body.temperature, ) info = get_llm().info() logger.info( "已更新运行时 LLM 配置 enabled=%s model=%s base=%s key=%s source=%s", info.get("enabled"), info.get("model"), info.get("api_base_url"), "yes" if info.get("api_key_configured") else "no", rt.source, ) return {"ok": True, **info} @router.get("/status") def llm_status() -> dict: settings = get_settings() info = get_llm().info() rt = get_runtime_llm() return { **info, "env_key_configured": bool(settings.llm_api_key and settings.llm_api_key.strip()), "runtime_enabled_flag": rt.enabled, }