""" Agent 工具管理器:包装已有 ToolRegistry,提供 Agent 需要的工具格式转换和执行。 """ from __future__ import annotations import logging from typing import Any, Dict, List, Optional from app.services.tool_registry import tool_registry logger = logging.getLogger(__name__) class AgentToolManager: """ 为 Agent Runtime 管理工具: - 将 ToolRegistry 的工具 schema 转为 OpenAI Function Calling 格式 - 按 Agent 配置过滤(白名单/黑名单) - 执行工具调用并返回结果字符串 """ def __init__(self, include_tools: Optional[List[str]] = None, exclude_tools: Optional[List[str]] = None): self._include_tools: set = set(include_tools or []) self._exclude_tools: set = set(exclude_tools or []) def get_tool_schemas(self) -> List[Dict[str, Any]]: """获取 Agent 可用的工具定义列表(OpenAI Function Calling 格式)。""" all_schemas = tool_registry.get_all_tool_schemas() if not self._include_tools and not self._exclude_tools: return all_schemas filtered = [] for schema in all_schemas: name = self._extract_tool_name(schema) if not name: continue if self._include_tools and name not in self._include_tools: continue if name in self._exclude_tools: continue filtered.append(schema) return filtered def has_tools(self) -> bool: """是否有可用工具。""" return len(self.get_tool_schemas()) > 0 def tool_names(self) -> List[str]: """可用工具名称列表。""" return [ self._extract_tool_name(s) or "?" for s in self.get_tool_schemas() ] async def execute(self, name: str, args: Dict[str, Any]) -> str: """ 执行工具调用。 优先查找内置工具,其次查找数据库自定义工具(HTTP / Code)。 Args: name: 工具名称 args: 工具参数字典 Returns: 工具执行结果的字符串表示 """ logger.info("Agent 执行工具: %s", name) return await tool_registry.execute_tool(name, args) @staticmethod def _extract_tool_name(schema: Dict[str, Any]) -> Optional[str]: """从工具 schema 中提取工具名称。""" fn = schema.get("function") or schema return fn.get("name") if isinstance(fn, dict) else None