ForcePilot/backend/server/utils/lifespan.py

133 lines
5.0 KiB
Python
Raw Normal View History

import os
from contextlib import asynccontextmanager
from fastapi import FastAPI
from langgraph.checkpoint.postgres.aio import AsyncPostgresSaver
from yuxi import get_version
from yuxi.agents.backends.sandbox import init_sandbox_provider, shutdown_sandbox_provider
from yuxi.knowledge import knowledge_base
from yuxi.services.mcp_service import ensure_builtin_mcp_servers_in_db
from yuxi.services.model_provider_service import ensure_builtin_model_providers_in_db
from yuxi.services.run_queue_service import close_queue_clients, get_redis_client
from yuxi.services.subagent_service import init_builtin_subagents
from yuxi.services.task_service import tasker
from yuxi.storage.postgres.manager import pg_manager
from yuxi.utils import logger
@asynccontextmanager
async def lifespan(app: FastAPI):
"""FastAPI lifespan事件管理器"""
# 初始化数据库连接
try:
pg_manager.initialize()
await pg_manager.create_business_tables()
await pg_manager.ensure_business_schema()
await pg_manager.ensure_knowledge_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:
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.services.model_cache import model_cache
from yuxi.services.model_provider_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}")
# 初始化内置 SubAgent
try:
await init_builtin_subagents()
except Exception as e:
logger.error(f"Failed to initialize builtin subagents during startup: {e}")
raise
# 初始化知识库管理器
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()
try:
from yuxi.channel.infrastructure.agent.agent_adapter import AgentAdapter
from yuxi.channel.startup import init_channel, register_channel_middleware
redis_url = os.getenv("REDIS_URL", "redis://redis:6379/0")
config_path = os.getenv("CHANNEL_CONFIG_PATH", "channel_config.yaml")
await init_channel(
redis_url=redis_url,
agent_port=AgentAdapter(pg_manager.get_async_session_context),
config_yaml_path=config_path,
)
register_channel_middleware(app)
logger.info("Channel gateway initialized")
except Exception as e:
logger.error(f"Channel gateway initialization failed: {e}")
raise
2026-03-21 00:33:20 +08:00
logger.info(f"""
v{get_version()}
""")
logger.info("Yuxi backend startup complete")
yield
try:
from yuxi.channel.startup import get_container, shutdown_channel
container = get_container()
if container:
await shutdown_channel(container)
except Exception as e:
logger.error(f"Channel gateway shutdown error: {e}")
await tasker.shutdown()
shutdown_sandbox_provider()
await close_queue_clients()
await pg_manager.close()