ForcePilot/backend/server/utils/lifespan.py
Kris 825a5e9769 feat: 新增外部系统工具加载能力,补充数据库初始化和异常处理
1. 在agent资源解析中新增从数据库加载外部工具的逻辑
2. 新增全局外部适配器注册和数据库外部schema初始化
3. 添加外部系统异常统一处理中间件
4. 在运行时工具解析中追加外部系统工具加载
2026-06-20 22:17:20 +08:00

130 lines
4.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import os
from contextlib import asynccontextmanager
from fastapi import FastAPI
from langgraph.checkpoint.postgres.aio import AsyncPostgresSaver
from yuxi.services.task_service import tasker
from yuxi.agents.mcp.service import ensure_builtin_mcp_servers_in_db
from yuxi.models.providers.service import ensure_builtin_model_providers_in_db
from yuxi.services.run_queue_service import close_queue_clients, get_redis_client
from yuxi.storage.postgres.manager import pg_manager
from yuxi.external import register_adapters
from yuxi.knowledge import knowledge_base
from yuxi.utils import logger
from yuxi.agents.backends.sandbox import init_sandbox_provider, shutdown_sandbox_provider
from yuxi import get_version
@asynccontextmanager
async def lifespan(app: FastAPI):
# 注册外部系统适配器(避免模块导入副作用)
try:
register_adapters()
except Exception as e:
logger.error(f"Failed to register external system adapters during startup: {e}")
"""FastAPI lifespan事件管理器"""
# 初始化数据库连接
try:
pg_manager.initialize()
await pg_manager.create_tables()
await pg_manager.ensure_business_schema()
await pg_manager.ensure_knowledge_schema()
await pg_manager.ensure_external_schema()
except Exception as e:
logger.error(f"Failed to initialize database during startup: {e}")
# 确保内置 MCP 服务器定义存在于数据库
try:
await ensure_builtin_mcp_servers_in_db()
except Exception as e:
logger.error(f"Failed to ensure builtin MCP servers during startup: {e}")
try:
from yuxi.agents.skills.service import init_builtin_skills
async with pg_manager.get_async_session_context() as session:
await init_builtin_skills(session)
except Exception as e:
logger.error(f"Failed to initialize builtin skills during startup: {e}")
try:
from yuxi.repositories.agent_repository import AgentRepository
async with pg_manager.get_async_session_context() as session:
repository = AgentRepository(session)
await repository.ensure_default_agent()
await repository.ensure_general_purpose_subagent()
await repository.ensure_web_search_subagent()
await repository.ensure_deep_research_agents()
except Exception as e:
logger.error(f"Failed to ensure default agent during startup: {e}")
# 初始化内置模型供应商配置
try:
async with pg_manager.get_async_session_context() as session:
await ensure_builtin_model_providers_in_db(session)
except Exception as e:
logger.error(f"Failed to ensure builtin model providers during startup: {e}")
# 初始化模型缓存v2 模型选择使用)
try:
from yuxi.models.providers.cache import model_cache
from yuxi.models.providers.service import get_all_model_providers
async with pg_manager.get_async_session_context() as session:
providers = await get_all_model_providers(session)
model_cache.rebuild(providers)
except Exception as e:
logger.error(f"Failed to initialize model cache during startup: {e}")
# 初始化知识库管理器
if os.environ.get("LITE_MODE", "").lower() in ("true", "1"):
logger.info("LITE_MODE enabled, skipping knowledge base initialization")
else:
try:
await knowledge_base.initialize()
except Exception as e:
logger.error(f"Failed to initialize knowledge base manager: {e}")
# 预热 Redisrun 队列)
try:
redis = await get_redis_client()
await redis.ping()
except Exception as e:
logger.warning(f"Run queue redis unavailable on startup: {e}")
try:
init_sandbox_provider()
except Exception as e:
logger.error(f"Failed to initialize sandbox provider during startup: {e}")
# =========================================================
# 2. 核心修复:在这里执行一次 setup(),建完表就拉倒
# =========================================================
checkpointer = AsyncPostgresSaver(pg_manager.langgraph_pool)
await checkpointer.setup()
print("LangGraph Checkpoint tables verified/created!")
await tasker.start()
logger.info(f"""
░██ ░██ ░██
░██ ░██
░██ ░██ ░██ ░██ ░██ ░██ ░██
░████ ░██ ░██ ░██ ░██ ░██
░██ ░██ ░██ ░█████ ░██
░██ ░██ ░███ ░██ ░██ ░██
░██ ░█████░██ ░██ ░██ ░██ v{get_version()}
""")
logger.info("Yuxi backend startup complete")
yield
await tasker.shutdown()
shutdown_sandbox_provider()
await close_queue_clients()
await pg_manager.close()