"""工具系统核心模块""" from dataclasses import dataclass, field from typing import Dict, Any, Callable, List, Optional, TypeVar, Generic @dataclass class ToolDefinition: """工具定义""" name: str description: str parameters: Dict[str, Any] # JSON Schema handler: Callable category: str = "general" def to_openai_format(self) -> Dict[str, Any]: """转换为OpenAI格式""" return { "type": "function", "function": { "name": self.name, "description": self.description, "parameters": self.parameters } } @dataclass class ToolResult: """工具执行结果""" success: bool data: Any = None error: Optional[str] = None def to_dict(self) -> Dict[str, Any]: """转换为字典""" return {"success": self.success, "data": self.data, "error": self.error} @classmethod def ok(cls, data: Any) -> "ToolResult": """创建成功结果""" return cls(success=True, data=data) @classmethod def fail(cls, error: str) -> "ToolResult": """创建失败结果""" return cls(success=False, error=error) class ToolRegistry: """工具注册表(单例模式)""" _instance: Optional["ToolRegistry"] = None _tools: Dict[str, ToolDefinition] = {} def __new__(cls): if cls._instance is None: cls._instance = super().__new__(cls) return cls._instance def register(self, tool: ToolDefinition) -> None: """注册工具""" self._tools[tool.name] = tool def get(self, name: str) -> Optional[ToolDefinition]: """获取工具定义""" return self._tools.get(name) def list_all(self) -> List[Dict[str, Any]]: """列出所有工具""" return [t.to_openai_format() for t in self._tools.values()] def list_by_category(self, category: str) -> List[Dict[str, Any]]: """按分类列出工具""" return [ t.to_openai_format() for t in self._tools.values() if t.category == category ] def execute(self, name: str, arguments: dict) -> Dict[str, Any]: """执行工具""" tool = self.get(name) if not tool: return ToolResult.fail(f"Tool not found: {name}").to_dict() try: result = tool.handler(arguments) if isinstance(result, ToolResult): return result.to_dict() return ToolResult.ok(result).to_dict() except Exception as e: return ToolResult.fail(str(e)).to_dict() def clear(self) -> None: """清空所有工具""" self._tools.clear() def remove(self, name: str) -> bool: """移除工具""" if name in self._tools: del self._tools[name] return True return False @property def tool_count(self) -> int: """工具数量""" return len(self._tools) # 全局注册表实例 registry = ToolRegistry()