Add FastAPI backend with agent system
This commit is contained in:
140
backend/app/services/settings_service.py
Normal file
140
backend/app/services/settings_service.py
Normal file
@@ -0,0 +1,140 @@
|
||||
import logging
|
||||
from typing import Optional
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy import select
|
||||
from app.models.user import User
|
||||
from app.services.auth_service import verify_password, get_password_hash
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def get_user_settings(user_id: str, db: AsyncSession) -> dict:
|
||||
"""获取用户完整设置"""
|
||||
result = await db.execute(select(User).where(User.id == user_id))
|
||||
user = result.scalar_one_or_none()
|
||||
if not user:
|
||||
return None
|
||||
return {
|
||||
"profile": user,
|
||||
"llm_config": user.llm_config or {},
|
||||
"scheduler_config": user.scheduler_config or {}
|
||||
}
|
||||
|
||||
|
||||
async def update_user_profile(
|
||||
user_id: str,
|
||||
db: AsyncSession,
|
||||
full_name: Optional[str] = None,
|
||||
password: Optional[str] = None,
|
||||
current_password: Optional[str] = None
|
||||
) -> User:
|
||||
"""更新用户资料"""
|
||||
result = await db.execute(select(User).where(User.id == user_id))
|
||||
user = result.scalar_one_or_none()
|
||||
if not user:
|
||||
raise ValueError("用户不存在")
|
||||
|
||||
if password:
|
||||
if not current_password or not verify_password(current_password, user.hashed_password):
|
||||
raise ValueError("当前密码错误")
|
||||
user.hashed_password = get_password_hash(password)
|
||||
|
||||
if full_name:
|
||||
user.full_name = full_name
|
||||
|
||||
await db.commit()
|
||||
await db.refresh(user)
|
||||
return user
|
||||
|
||||
|
||||
async def update_llm_config(user_id: str, config: dict, db: AsyncSession) -> dict:
|
||||
"""更新 LLM 配置"""
|
||||
result = await db.execute(select(User).where(User.id == user_id))
|
||||
user = result.scalar_one_or_none()
|
||||
if not user:
|
||||
raise ValueError("用户不存在")
|
||||
|
||||
current = user.llm_config or {}
|
||||
# 合并配置 - 直接替换整个类型配置列表
|
||||
for key, value in config.items():
|
||||
if value is not None:
|
||||
if isinstance(value, list):
|
||||
# 列表直接替换
|
||||
current[key] = value
|
||||
elif isinstance(value, dict):
|
||||
# 字典合并
|
||||
if key in current and isinstance(current[key], dict):
|
||||
current[key] = {**current[key], **value}
|
||||
else:
|
||||
current[key] = value
|
||||
else:
|
||||
current[key] = value
|
||||
user.llm_config = current
|
||||
await db.commit()
|
||||
return current
|
||||
|
||||
|
||||
async def update_scheduler_config(user_id: str, config: dict, db: AsyncSession) -> dict:
|
||||
"""更新定时任务配置"""
|
||||
result = await db.execute(select(User).where(User.id == user_id))
|
||||
user = result.scalar_one_or_none()
|
||||
if not user:
|
||||
raise ValueError("用户不存在")
|
||||
|
||||
current = user.scheduler_config or {}
|
||||
for key, value in config.items():
|
||||
if value is not None:
|
||||
current[key] = value
|
||||
user.scheduler_config = current
|
||||
await db.commit()
|
||||
return current
|
||||
|
||||
|
||||
async def test_llm_connection(
|
||||
provider: str,
|
||||
model: str,
|
||||
base_url: str,
|
||||
api_key: str
|
||||
) -> dict:
|
||||
"""测试 LLM 连接"""
|
||||
try:
|
||||
# 根据不同 provider 创建临时 LLM 实例并测试
|
||||
if provider == "openai":
|
||||
from langchain_openai import ChatOpenAI
|
||||
llm = ChatOpenAI(
|
||||
api_key=api_key,
|
||||
model=model,
|
||||
base_url=base_url or None,
|
||||
timeout=30
|
||||
)
|
||||
elif provider == "claude":
|
||||
from langchain_anthropic import ChatAnthropic
|
||||
llm = ChatAnthropic(
|
||||
api_key=api_key,
|
||||
model=model,
|
||||
timeout=30
|
||||
)
|
||||
elif provider == "ollama":
|
||||
from langchain_ollama import ChatOllama
|
||||
llm = ChatOllama(
|
||||
base_url=base_url or "http://localhost:11434",
|
||||
model=model,
|
||||
timeout=30
|
||||
)
|
||||
elif provider == "deepseek":
|
||||
from langchain_openai import ChatOpenAI
|
||||
llm = ChatOpenAI(
|
||||
api_key=api_key,
|
||||
model=model,
|
||||
base_url=base_url or "https://api.deepseek.com/v1",
|
||||
timeout=30
|
||||
)
|
||||
else:
|
||||
return {"success": False, "error": f"不支持的 provider: {provider}"}
|
||||
|
||||
# 简单测试调用
|
||||
from langchain_core.messages import HumanMessage
|
||||
response = await llm.ainvoke([HumanMessage(content="Hi")])
|
||||
return {"success": True, "message": f"连接成功,模型响应: {response.content[:50]}..."}
|
||||
except Exception as e:
|
||||
return {"success": False, "error": str(e)}
|
||||
Reference in New Issue
Block a user