From 9e9cb9ba770514b494749ad6fd00f0b14e48c955 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E6=BD=AE?= Date: Mon, 23 Mar 2026 21:31:20 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=99=BE=E5=BA=A6=E6=90=9C?= =?UTF-8?q?=E7=B4=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- routes/bot_manager.py | 45 +++++++++++++++++++ .../baidu-search/.claude-plugin/plugin.json | 13 ++++++ .../baidu-search-skill}/SKILL.md | 0 .../baidu-search-skill}/_meta.json | 0 .../baidu-search-skill}/scripts/search.py | 0 utils/fastapi_utils.py | 3 +- 6 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 skills/baidu-search/.claude-plugin/plugin.json rename {skills/baidu-search => skills_developing/baidu-search-skill}/SKILL.md (100%) rename {skills/baidu-search => skills_developing/baidu-search-skill}/_meta.json (100%) rename {skills/baidu-search => skills_developing/baidu-search-skill}/scripts/search.py (100%) diff --git a/routes/bot_manager.py b/routes/bot_manager.py index 433e119..9dd8b06 100644 --- a/routes/bot_manager.py +++ b/routes/bot_manager.py @@ -659,6 +659,7 @@ class BotSettingsUpdate(BaseModel): voice_speaker: Optional[str] = None # 语音音色 voice_system_role: Optional[str] = None # 语音对话系统角色 voice_speaking_style: Optional[str] = None # 语音说话风格 + mcp_settings: Optional[str] = None # MCP 服务器配置 (JSON 字符串) class ModelInfo(BaseModel): @@ -703,6 +704,7 @@ class BotSettingsResponse(BaseModel): voice_speaker: Optional[str] = None # 语音音色 voice_system_role: Optional[str] = None # 语音对话系统角色 voice_speaking_style: Optional[str] = None # 语音说话风格 + mcp_settings: Optional[str] = None # MCP 服务器配置 (JSON 字符串) updated_at: str @@ -1878,10 +1880,47 @@ async def get_bot_settings(bot_uuid: str, authorization: Optional[str] = Header( voice_speaker=settings.get('voice_speaker'), voice_system_role=settings.get('voice_system_role'), voice_speaking_style=settings.get('voice_speaking_style'), + mcp_settings=settings.get('mcp_settings'), updated_at=datetime_to_str(updated_at) ) +async def _sync_mcp_settings_to_table(cursor, bot_uuid: str, mcp_settings_str: str): + """将 mcp_settings JSON 字符串同步到 agent_mcp_servers 表""" + # 删除该 bot 的旧记录 + await cursor.execute("DELETE FROM agent_mcp_servers WHERE bot_id = %s", (bot_uuid,)) + + if not mcp_settings_str: + return + + try: + mcp_list = json.loads(mcp_settings_str) + except (json.JSONDecodeError, TypeError): + return + + if not isinstance(mcp_list, list): + return + + for item in mcp_list: + config = item.get('config', {}) + server_name = config.get('server_type', f'mcp-server-{id(item)}') + enabled = item.get('enabled', True) + + # 去掉 server_type 后的纯 config + clean_config = {k: v for k, v in config.items() if k != 'server_type'} + + await cursor.execute(""" + INSERT INTO agent_mcp_servers (bot_id, name, type, config, enabled) + VALUES (%s, %s, %s, %s::jsonb, %s) + """, ( + bot_uuid, + server_name, + 'custom', + json.dumps(clean_config), + enabled + )) + + @router.put("/api/v1/bots/{bot_uuid}/settings", response_model=SuccessResponse) async def update_bot_settings( bot_uuid: str, @@ -1958,6 +1997,8 @@ async def update_bot_settings( update_json['voice_system_role'] = request.voice_system_role if request.voice_speaking_style is not None: update_json['voice_speaking_style'] = request.voice_speaking_style + if request.mcp_settings is not None: + update_json['mcp_settings'] = request.mcp_settings # is_published 是表字段,不在 settings JSON 中 need_update_published = request.is_published is not None @@ -1991,6 +2032,10 @@ async def update_bot_settings( WHERE id = %s """, (json.dumps(existing_settings), bot_uuid)) + # 如果 mcp_settings 有更新,同步到 agent_mcp_servers 表 + if request.mcp_settings is not None: + await _sync_mcp_settings_to_table(cursor, bot_uuid, request.mcp_settings) + await conn.commit() # 同步更新所有从此智能体复制的智能体 diff --git a/skills/baidu-search/.claude-plugin/plugin.json b/skills/baidu-search/.claude-plugin/plugin.json new file mode 100644 index 0000000..3638082 --- /dev/null +++ b/skills/baidu-search/.claude-plugin/plugin.json @@ -0,0 +1,13 @@ +{ + "name": "baidu-search", + "description": "百度搜索服务", + "mcpServers": { + "web-search-mcp-server": { + "transport": "http", + "url": "https://qianfan.baidubce.com/v2/tools/web-search/mcp", + "headers": { + "Authorization": "Bearer bce-v3/ALTAK-60JvEdbSLzQEtHmfheEmk/e24d067a609bf099505afdf71dc880cd5ece5dde" + } + } + } +} diff --git a/skills/baidu-search/SKILL.md b/skills_developing/baidu-search-skill/SKILL.md similarity index 100% rename from skills/baidu-search/SKILL.md rename to skills_developing/baidu-search-skill/SKILL.md diff --git a/skills/baidu-search/_meta.json b/skills_developing/baidu-search-skill/_meta.json similarity index 100% rename from skills/baidu-search/_meta.json rename to skills_developing/baidu-search-skill/_meta.json diff --git a/skills/baidu-search/scripts/search.py b/skills_developing/baidu-search-skill/scripts/search.py similarity index 100% rename from skills/baidu-search/scripts/search.py rename to skills_developing/baidu-search-skill/scripts/search.py diff --git a/utils/fastapi_utils.py b/utils/fastapi_utils.py index 2520156..bb5e5b5 100644 --- a/utils/fastapi_utils.py +++ b/utils/fastapi_utils.py @@ -600,7 +600,8 @@ async def fetch_bot_config_from_db(bot_user_id: str, user_identifier: Optional[s mcp_settings_value = [] for server in mcp_servers: server_config = server.get("config", {}) - server_type = server_config.pop("server_type", server["type"]) + # 优先用 config 中的 server_type,fallback 到数据库的 name 字段 + server_type = server_config.pop("server_type", server["name"]) mcp_settings_value.append({ "mcpServers": { server_type: server_config