""" Tool definition converter for Function Calling. Converts ToolRegistry definitions to LLM ToolDefinition format. """ import logging from typing import Any from app.services.llm.base import ToolDefinition from app.services.mid.tool_registry import ToolDefinition as RegistryToolDefinition logger = logging.getLogger(__name__) def convert_tool_to_llm_format(tool: RegistryToolDefinition) -> ToolDefinition: """ Convert ToolRegistry tool definition to LLM ToolDefinition format. Args: tool: Tool definition from ToolRegistry Returns: ToolDefinition for Function Calling """ meta = tool.metadata or {} parameters = meta.get("parameters", { "type": "object", "properties": {}, "required": [], }) if not isinstance(parameters, dict): parameters = { "type": "object", "properties": {}, "required": [], } if "type" not in parameters: parameters["type"] = "object" if "properties" not in parameters: parameters["properties"] = {} if "required" not in parameters: parameters["required"] = [] properties = parameters.get("properties", {}) if "tenant_id" in properties: properties = {k: v for k, v in properties.items() if k != "tenant_id"} if "user_id" in properties: properties = {k: v for k, v in properties.items() if k != "user_id"} if "session_id" in properties: properties = {k: v for k, v in properties.items() if k != "session_id"} parameters["properties"] = properties required = parameters.get("required", []) required = [r for r in required if r not in ("tenant_id", "user_id", "session_id")] parameters["required"] = required return ToolDefinition( name=tool.name, description=tool.description, parameters=parameters, ) def convert_tools_to_llm_format(tools: list[RegistryToolDefinition]) -> list[ToolDefinition]: """ Convert multiple tool definitions to LLM format. Args: tools: List of tool definitions from ToolRegistry Returns: List of ToolDefinition for Function Calling """ return [convert_tool_to_llm_format(tool) for tool in tools] def build_tool_result_message( tool_call_id: str, tool_name: str, result: dict[str, Any], tool_guide: str | None = None, ) -> dict[str, str]: """ Build a tool result message for the conversation. Args: tool_call_id: ID of the tool call tool_name: Name of the tool result: Tool execution result tool_guide: Optional tool usage guide to append Returns: Message dict with role='tool' """ if isinstance(result, dict): result_copy = {k: v for k, v in result.items() if k != "_tool_guide"} content = str(result_copy) else: content = str(result) if tool_guide: content = f"{content}\n\n---\n{tool_guide}" return { "role": "tool", "tool_call_id": tool_call_id, "content": content, }