- Introduce a new `sync_default_tools` function in `session.py` to ensure essential reusable tools are created without overwriting existing edits. - Update the `lifespan` context manager in `app.py` to call `sync_default_tools`, enhancing the initialization process for the application. - This change improves the management of default tools within the system, ensuring they are available for use while preserving user modifications.
84 lines
3.1 KiB
Python
84 lines
3.1 KiB
Python
"""异步数据库引擎 + 会话。
|
|
|
|
- engine / SessionLocal:全局单例
|
|
- get_session:FastAPI 依赖,按请求注入一个会话
|
|
- sync_interface_definitions:启动时同步接口定义;表结构由 Alembic 管理
|
|
"""
|
|
|
|
from collections.abc import AsyncGenerator
|
|
import json
|
|
|
|
import settings
|
|
from services.interface_catalog import INTERFACE_DEFINITIONS
|
|
from sqlalchemy import text
|
|
from sqlalchemy.ext.asyncio import (
|
|
AsyncSession,
|
|
async_sessionmaker,
|
|
create_async_engine,
|
|
)
|
|
|
|
engine = create_async_engine(settings.DATABASE_URL, echo=False, pool_pre_ping=True)
|
|
SessionLocal = async_sessionmaker(engine, expire_on_commit=False)
|
|
|
|
|
|
async def get_session() -> AsyncGenerator[AsyncSession, None]:
|
|
async with SessionLocal() as session:
|
|
yield session
|
|
|
|
|
|
async def sync_interface_definitions() -> None:
|
|
async with engine.begin() as conn:
|
|
for definition in INTERFACE_DEFINITIONS:
|
|
await conn.execute(
|
|
text(
|
|
"INSERT INTO interface_definitions "
|
|
"(interface_type, name, capability, field_schema, enabled, version) "
|
|
"VALUES (:interface_type, :name, :capability, CAST(:field_schema AS jsonb), TRUE, 1) "
|
|
"ON CONFLICT (interface_type) DO UPDATE SET "
|
|
"name = EXCLUDED.name, capability = EXCLUDED.capability, "
|
|
"field_schema = EXCLUDED.field_schema, enabled = TRUE, updated_at = now()"
|
|
),
|
|
{
|
|
"interface_type": definition["interface_type"],
|
|
"name": definition["name"],
|
|
"capability": definition["capability"],
|
|
"field_schema": json.dumps({"fields": definition["fields"]}),
|
|
},
|
|
)
|
|
|
|
|
|
async def sync_default_tools() -> None:
|
|
"""Ensure system-provided reusable tools exist without overwriting edits."""
|
|
async with engine.begin() as conn:
|
|
await conn.execute(
|
|
text(
|
|
"INSERT INTO tools "
|
|
"(id, name, function_name, type, description, definition, secrets, status) "
|
|
"VALUES ("
|
|
":id, :name, :function_name, :type, :description, "
|
|
"CAST(:definition AS jsonb), CAST(:secrets AS jsonb), :status"
|
|
") "
|
|
"ON CONFLICT (function_name) DO NOTHING"
|
|
),
|
|
{
|
|
"id": "tool_end_call_default",
|
|
"name": "结束对话",
|
|
"function_name": "end_call",
|
|
"type": "end_call",
|
|
"description": "当用户明确要求结束对话,或任务已完成时调用。",
|
|
"definition": json.dumps(
|
|
{
|
|
"schema_version": 1,
|
|
"type": "end_call",
|
|
"config": {
|
|
"message_type": "none",
|
|
"custom_message": "",
|
|
"capture_reason": True,
|
|
},
|
|
}
|
|
),
|
|
"secrets": "{}",
|
|
"status": "active",
|
|
},
|
|
)
|