Source code for rath.flow.tool.tool_table
"""Loop tool registry helpers: merge user tools with system defaults, OpenAI schemas."""
from __future__ import annotations
from collections.abc import Mapping
from rath.flow.tool.base import FlowToolCall
from rath.flow.tool.system_tool import global_system_tools
from rath.llm import RathLLMFunctionTool
__all__ = [
"ToolNameConflictError",
"merge_tools_for_loop",
"tools_dict_to_schemas",
]
[docs]
class ToolNameConflictError(ValueError):
"""Raised when a user tool name collides with a built-in system tool."""
[docs]
def merge_tools_for_loop(
user_tools: list[FlowToolCall] | None,
) -> dict[str, FlowToolCall]:
"""Merge user tools with :func:`~rath.flow.tool.global_system_tools`.
Built-in names cannot be shadowed; duplicates raise
:class:`ToolNameConflictError`.
"""
table = dict(global_system_tools())
for t in user_tools or ():
if t.name in table:
raise ToolNameConflictError(
f"user tool {t.name!r} shadows a built-in system tool"
)
table[t.name] = t
return table
[docs]
def tools_dict_to_schemas(
table: Mapping[str, FlowToolCall],
) -> tuple[RathLLMFunctionTool, ...]:
"""Convert a name-to-tool map into sorted OpenAI-style function specs."""
return tuple(
RathLLMFunctionTool(
name=tool.name,
description=tool.description,
parameters=dict(tool.parameters),
)
for _, tool in sorted(table.items(), key=lambda kv: kv[0])
)