From c3a5106adc982a1f34a8eb91c201eef4119c3918 Mon Sep 17 00:00:00 2001 From: PKC278 <52959804+PKC278@users.noreply.github.com> Date: Mon, 22 Dec 2025 21:04:13 +0800 Subject: [PATCH] =?UTF-8?q?feat(manager):=20=E6=B7=BB=E5=8A=A0=E5=B7=A5?= =?UTF-8?q?=E5=85=B7=E8=B0=83=E7=94=A8=E5=8F=82=E6=95=B0=E6=A0=BC=E5=BC=8F?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E8=BD=AC=E6=8D=A2=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/agent/tools/manager.py | 71 +++++++++++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/app/agent/tools/manager.py b/app/agent/tools/manager.py index 770c527a..894d6c71 100644 --- a/app/agent/tools/manager.py +++ b/app/agent/tools/manager.py @@ -100,6 +100,72 @@ class MoviePilotToolsManager: return tool return None + def _normalize_arguments(self, tool_instance: Any, arguments: Dict[str, Any]) -> Dict[str, Any]: + """ + 根据工具的参数schema规范化参数类型 + + Args: + tool_instance: 工具实例 + arguments: 原始参数 + + Returns: + 规范化后的参数 + """ + # 获取工具的参数schema + args_schema = getattr(tool_instance, 'args_schema', None) + if not args_schema: + return arguments + + # 获取schema中的字段定义 + try: + schema = args_schema.model_json_schema() + properties = schema.get("properties", {}) + except Exception as e: + logger.warning(f"获取工具schema失败: {e}") + return arguments + + # 规范化参数 + normalized = {} + for key, value in arguments.items(): + if key not in properties: + # 参数不在schema中,保持原样 + normalized[key] = value + continue + + field_info = properties[key] + field_type = field_info.get("type") + + # 处理 anyOf 类型(例如 Optional[int] 会生成 anyOf) + any_of = field_info.get("anyOf") + if any_of and not field_type: + # 从 anyOf 中提取实际类型 + for type_option in any_of: + if "type" in type_option and type_option["type"] != "null": + field_type = type_option["type"] + break + + # 根据类型进行转换 + if field_type == "integer" and isinstance(value, str): + try: + normalized[key] = int(value) + except (ValueError, TypeError): + logger.warning(f"无法将参数 {key}='{value}' 转换为整数,保持原值") + normalized[key] = value + elif field_type == "number" and isinstance(value, str): + try: + normalized[key] = float(value) + except (ValueError, TypeError): + logger.warning(f"无法将参数 {key}='{value}' 转换为浮点数,保持原值") + normalized[key] = value + elif field_type == "boolean" and isinstance(value, str): + # 转换字符串为布尔值 + normalized[key] = value.lower() in ("true", "1", "yes", "on") + else: + # 其他类型保持原样 + normalized[key] = value + + return normalized + async def call_tool(self, tool_name: str, arguments: Dict[str, Any]) -> str: """ 调用工具 @@ -120,8 +186,11 @@ class MoviePilotToolsManager: return error_msg try: + # 规范化参数类型 + normalized_arguments = self._normalize_arguments(tool_instance, arguments) + # 调用工具的run方法 - result = await tool_instance.run(**arguments) + result = await tool_instance.run(**normalized_arguments) # 确保返回字符串 if isinstance(result, str):