diff --git a/backend/app.py b/backend/app.py index 60d0d4f..299dc47 100644 --- a/backend/app.py +++ b/backend/app.py @@ -16,7 +16,7 @@ from contextlib import asynccontextmanager import settings import uvicorn -from db.session import sync_interface_definitions +from db.session import sync_default_tools, sync_interface_definitions from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware @@ -36,6 +36,7 @@ from routes import ( @asynccontextmanager async def lifespan(_app: FastAPI): await sync_interface_definitions() + await sync_default_tools() yield diff --git a/backend/db/session.py b/backend/db/session.py index 8367c59..000916c 100644 --- a/backend/db/session.py +++ b/backend/db/session.py @@ -45,3 +45,39 @@ async def sync_interface_definitions() -> None: "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", + }, + )