Source code for ractogateway._tool_runtime

"""Internal helpers for local tool execution loops in chat kits."""

from __future__ import annotations

import inspect

from ractogateway.adapters.base import ToolCallResult
from ractogateway.tools.registry import ToolRegistry


[docs] def execute_tool_calls_sync( tool_calls: list[ToolCallResult], registry: ToolRegistry, ) -> list[str]: """Execute tool calls synchronously and return stringified results.""" results: list[str] = [] for tc in tool_calls: fn = registry.get_callable(tc.name) if fn is None: results.append(f"[Error: no callable registered for tool {tc.name!r}]") continue try: raw = fn(**tc.arguments) if inspect.isawaitable(raw): close = getattr(raw, "close", None) if callable(close): close() results.append( f"[Error executing {tc.name!r}: returned awaitable in sync mode. " "Use achat() or register a sync callable.]" ) else: results.append(str(raw)) except Exception as exc: # pragma: no cover results.append(f"[Error executing {tc.name!r}: {exc}]") return results
[docs] async def execute_tool_calls_async( tool_calls: list[ToolCallResult], registry: ToolRegistry, ) -> list[str]: """Execute tool calls asynchronously and return stringified results.""" results: list[str] = [] for tc in tool_calls: fn = registry.get_callable(tc.name) if fn is None: results.append(f"[Error: no callable registered for tool {tc.name!r}]") continue try: raw = fn(**tc.arguments) if inspect.isawaitable(raw): raw = await raw results.append(str(raw)) except Exception as exc: # pragma: no cover results.append(f"[Error executing {tc.name!r}: {exc}]") return results
[docs] def build_tool_followup_user_message( *, original_user_message: str, tool_calls: list[ToolCallResult], results: list[str], ) -> str: """Build a provider-agnostic follow-up user message from tool outputs.""" lines: list[str] = [ "You requested tools in the previous step. The tools have now been executed.", f"Original user request: {original_user_message}", "Tool execution results:", ] for tc, result in zip(tool_calls, results, strict=True): args_repr = ", ".join(f"{k}={v!r}" for k, v in tc.arguments.items()) lines.append(f"- {tc.name}({args_repr}) -> {result}") lines.append( "Now provide the best final answer to the original user request using these results." ) return "\n".join(lines)