- Backend: Introduced new endpoints for LLM configuration retrieval and updates in `config.py`, allowing dynamic management of LLM provider settings. - Updated schemas to include `AlphaEngineConfig` for better integration with the new provider. - Frontend: Added state management for AlphaEngine API credentials in the configuration page, ensuring seamless user experience. - Configuration files updated to reflect changes in LLM provider settings and API keys. BREAKING CHANGE: The default LLM provider has been changed from `new_api` to `alpha_engine`, requiring updates to existing configurations.
142 lines
5.2 KiB
Python
142 lines
5.2 KiB
Python
from fastapi import APIRouter, Depends, HTTPException
|
|
from typing import Dict, Any, Optional
|
|
from pydantic import BaseModel
|
|
|
|
from app.core.dependencies import get_config_manager
|
|
from app.schemas.config import ConfigResponse, ConfigUpdateRequest, ConfigTestRequest, ConfigTestResponse
|
|
from app.services.config_manager import ConfigManager
|
|
|
|
router = APIRouter()
|
|
|
|
class LLMConfigUpdate(BaseModel):
|
|
provider: str
|
|
model: Optional[str] = None
|
|
|
|
@router.get("/", response_model=ConfigResponse)
|
|
async def get_config(config_manager: ConfigManager = Depends(get_config_manager)):
|
|
"""Retrieve the current system configuration."""
|
|
return await config_manager.get_config()
|
|
|
|
@router.get("/llm", response_model=Dict[str, Any])
|
|
async def get_llm_config(config_manager: ConfigManager = Depends(get_config_manager)):
|
|
"""Get LLM provider and model configuration."""
|
|
llm_config = await config_manager.get_llm_config()
|
|
return llm_config
|
|
|
|
@router.put("/llm", response_model=Dict[str, Any])
|
|
async def update_llm_config(
|
|
llm_update: LLMConfigUpdate,
|
|
config_manager: ConfigManager = Depends(get_config_manager)
|
|
):
|
|
"""Update LLM provider and model configuration."""
|
|
import json
|
|
import os
|
|
|
|
provider = llm_update.provider
|
|
model = llm_update.model
|
|
|
|
# Load base config
|
|
project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", ".."))
|
|
config_path = os.path.join(project_root, "config", "config.json")
|
|
|
|
base_config = {}
|
|
if os.path.exists(config_path):
|
|
try:
|
|
with open(config_path, "r", encoding="utf-8") as f:
|
|
base_config = json.load(f)
|
|
except Exception:
|
|
pass
|
|
|
|
# Update llm config
|
|
if "llm" not in base_config:
|
|
base_config["llm"] = {}
|
|
|
|
base_config["llm"]["provider"] = provider
|
|
if model:
|
|
# Update model in the provider-specific config
|
|
if provider in base_config["llm"]:
|
|
if not isinstance(base_config["llm"][provider], dict):
|
|
base_config["llm"][provider] = {}
|
|
base_config["llm"][provider]["model"] = model
|
|
|
|
# Save to file
|
|
try:
|
|
with open(config_path, "w", encoding="utf-8") as f:
|
|
json.dump(base_config, f, ensure_ascii=False, indent=2)
|
|
except Exception as e:
|
|
raise HTTPException(status_code=500, detail=f"Failed to save config: {str(e)}")
|
|
|
|
# Also update in database - use same error handling as _load_dynamic_config_from_db
|
|
try:
|
|
from app.models.system_config import SystemConfig
|
|
from sqlalchemy.future import select
|
|
|
|
result = await config_manager.db.execute(
|
|
select(SystemConfig).where(SystemConfig.config_key == "llm")
|
|
)
|
|
existing_llm_config = result.scalar_one_or_none()
|
|
|
|
if existing_llm_config:
|
|
if isinstance(existing_llm_config.config_value, dict):
|
|
existing_llm_config.config_value["provider"] = provider
|
|
if model:
|
|
if provider not in existing_llm_config.config_value:
|
|
existing_llm_config.config_value[provider] = {}
|
|
elif not isinstance(existing_llm_config.config_value[provider], dict):
|
|
existing_llm_config.config_value[provider] = {}
|
|
existing_llm_config.config_value[provider]["model"] = model
|
|
else:
|
|
existing_llm_config.config_value = {"provider": provider}
|
|
if model:
|
|
existing_llm_config.config_value[provider] = {"model": model}
|
|
else:
|
|
new_llm_config = SystemConfig(
|
|
config_key="llm",
|
|
config_value={"provider": provider}
|
|
)
|
|
if model:
|
|
new_llm_config.config_value[provider] = {"model": model}
|
|
config_manager.db.add(new_llm_config)
|
|
|
|
await config_manager.db.commit()
|
|
except Exception as e:
|
|
# Rollback on error
|
|
try:
|
|
await config_manager.db.rollback()
|
|
except Exception:
|
|
pass
|
|
|
|
# Log the error but don't fail the request since file was already saved
|
|
import logging
|
|
logger = logging.getLogger(__name__)
|
|
logger.warning(f"Failed to update LLM config in database (file saved successfully): {e}")
|
|
# Continue anyway since file config was saved successfully
|
|
|
|
return await config_manager.get_llm_config()
|
|
|
|
@router.put("/", response_model=ConfigResponse)
|
|
async def update_config(
|
|
config_update: ConfigUpdateRequest,
|
|
config_manager: ConfigManager = Depends(get_config_manager)
|
|
):
|
|
"""Update system configuration."""
|
|
return await config_manager.update_config(config_update)
|
|
|
|
@router.post("/test", response_model=ConfigTestResponse)
|
|
async def test_config(
|
|
test_request: ConfigTestRequest,
|
|
config_manager: ConfigManager = Depends(get_config_manager)
|
|
):
|
|
"""Test a specific configuration (e.g., database connection)."""
|
|
try:
|
|
test_result = await config_manager.test_config(
|
|
test_request.config_type,
|
|
test_request.config_data
|
|
)
|
|
return test_result
|
|
except Exception as e:
|
|
return ConfigTestResponse(
|
|
success=False,
|
|
message=f"测试失败: {str(e)}"
|
|
)
|