ai-robot-core/ai-service/app/services/mid/tool_converter.py

112 lines
3.1 KiB
Python
Raw Normal View History

"""
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,
}