""" 统一工具返回格式 - ToolResult 所有插件和工具管理器使用统一的返回格式, 替代原来混乱的字符串/Dict 返回。 """ from dataclasses import dataclass, field from typing import Any, Optional # 错误码常量 class ErrorCode: """工具错误码""" SUCCESS = 0 # 参数错误 (1xx) MISSING_ARGS = 100 INVALID_ARGS = 101 UNSUPPORTED_OP = 102 # 资源错误 (2xx) NOT_FOUND = 200 FILE_NOT_FOUND = 201 PERMISSION_DENIED = 202 # 执行错误 (3xx) EXEC_FAILED = 300 TIMEOUT = 301 DECODE_ERROR = 302 # 系统错误 (4xx) INTERNAL_ERROR = 400 NOT_IMPLEMENTED = 401 _NAMES = { 0: "成功", 100: "缺少参数", 101: "参数无效", 102: "不支持的操作", 200: "未找到", 201: "文件不存在", 202: "权限不足", 300: "执行失败", 301: "超时", 302: "解码错误", 400: "内部错误", 401: "未实现", } @classmethod def name(cls, code: int) -> str: return cls._NAMES.get(code, f"未知({code})") @dataclass class ToolResult: """统一工具返回格式""" success: bool data: Any = None error_code: int = ErrorCode.SUCCESS error_message: str = "" # 可选元数据 tool_name: str = "" execution_time: float = 0.0 metadata: dict = field(default_factory=dict) def __str__(self) -> str: if self.success: return str(self.data) if self.data is not None else "执行完成" return f"[{ErrorCode.name(self.error_code)}] {self.error_message}" # ── 便捷构造方法 ── @classmethod def ok(cls, data: Any = None, **kwargs) -> "ToolResult": """成功""" return cls(success=True, data=data, **kwargs) @classmethod def fail(cls, message: str, code: int = ErrorCode.EXEC_FAILED, **kwargs) -> "ToolResult": """失败""" return cls(success=False, error_code=code, error_message=message, **kwargs) @classmethod def missing(cls, what: str = "参数", **kwargs) -> "ToolResult": """缺少参数""" return cls.fail(f"缺少{what}", ErrorCode.MISSING_ARGS, **kwargs) @classmethod def not_found(cls, what: str = "资源", **kwargs) -> "ToolResult": """未找到""" return cls.fail(f"{what}不存在", ErrorCode.NOT_FOUND, **kwargs) @classmethod def timeout(cls, seconds: int = 0, **kwargs) -> "ToolResult": """超时""" msg = f"执行超时" if seconds: msg += f" ({seconds}秒)" return cls.fail(msg, ErrorCode.TIMEOUT, **kwargs) # ── 格式转换 ── def to_dict(self) -> dict: """转为普通 dict(兼容旧接口)""" if self.success: return {"result": self.data if self.data is not None else "执行完成"} return {"result": str(self)} def to_mcp(self) -> dict: """转为 MCP 协议格式""" text = str(self) return { "content": [{"type": "text", "text": text}], "isError": not self.success, } def to_string(self) -> str: """转为字符串(兼容旧插件 handle() 返回值)""" return str(self)