From 6835003d15da36898bf51d2b3890307b21a52554 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E6=BD=AE?= Date: Tue, 23 Jun 2026 10:11:19 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20BotSettingsResponse.skills=20=E6=94=B9?= =?UTF-8?q?=E4=B8=BA=20list=20=E7=B1=BB=E5=9E=8B=EF=BC=8C=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=20settings=20=E6=8E=A5=E5=8F=A3=20500?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The /api/v1/general-agent/settings endpoint returned HTTP 500 because config/general_agent.json stores skills as a list while the response model expected Optional[str]. Add _normalize_skills_list and apply it in both get_general_agent_settings_api and get_bot_settings so list and legacy comma-separated string inputs both yield a list output. Co-Authored-By: Claude Opus 4.7 --- routes/bot_manager.py | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/routes/bot_manager.py b/routes/bot_manager.py index 0dc1a58..61b9ea8 100644 --- a/routes/bot_manager.py +++ b/routes/bot_manager.py @@ -27,6 +27,15 @@ router = APIRouter() # ============== 辅助函数 ============== +def _normalize_skills_list(value) -> List[str]: + """Normalize skills value (list or comma-separated str) to a list of strings.""" + if not value: + return [] + if isinstance(value, str): + return [s.strip() for s in value.split(',') if s.strip()] + return list(value) + + def copy_skills_folder(source_bot_id: str, target_bot_id: str) -> bool: """ 复制智能体的 skills 文件夹 @@ -547,7 +556,7 @@ class BotSettingsUpdate(BaseModel): enable_memori: Optional[bool] = None enable_thinking: Optional[bool] = None tool_response: Optional[bool] = None - skills: Optional[str] = None + skills: Optional[List[str]] = None is_published: Optional[bool] = None # 是否发布到广场 shell_env: Optional[dict] = None # 自定义 shell 环境变量 voice_speaker: Optional[str] = None # 语音音色 @@ -591,7 +600,7 @@ class BotSettingsResponse(BaseModel): enable_memori: bool enable_thinking: bool tool_response: bool - skills: Optional[str] + skills: Optional[List[str]] shell_env: Optional[dict] = None # 自定义 shell 环境变量 is_published: bool = False # 是否发布到广场 is_owner: bool = True # 是否是所有者 @@ -1699,7 +1708,7 @@ async def get_general_agent_settings_api(authorization: Optional[str] = Header(N enable_memori=settings.get("enable_memori", False), enable_thinking=settings.get("enable_thinking", False), tool_response=settings.get("tool_response", False), - skills=settings.get("skills"), + skills=_normalize_skills_list(settings.get("skills")), shell_env=settings.get("shell_env") or {}, is_published=False, is_owner=False, @@ -1869,14 +1878,10 @@ async def get_bot_settings(bot_uuid: str, authorization: Optional[str] = Header( # 扫描 skills 需要的环境变量并合并到 shell_env shell_env = settings.get('shell_env') or {} - skills_list = settings.get('skills') + skills_list = _normalize_skills_list(settings.get('skills')) if skills_list: from utils.multi_project_manager import scan_skill_env_keys - # skills 可能是逗号分隔的字符串,需要拆分成列表 - if isinstance(skills_list, str): - skills_names = [s.strip() for s in skills_list.split(',') if s.strip()] - else: - skills_names = skills_list + skills_names = skills_list required_keys = scan_skill_env_keys(bot_uuid, skills_names, Path("projects")) for key in required_keys: if key not in shell_env: