"""Tool-call protocol shared by every tool. Mirrors the qwen3_coder schema so vLLM's built-in tool parser can dispatch directly into our registry. """ from __future__ import annotations import json from dataclasses import dataclass, field from typing import Any, Callable, Dict, List @dataclass class ToolResult: ok: bool output: str error: str = "" extra: Dict[str, Any] = field(default_factory=dict) def to_message(self) -> Dict[str, Any]: body = self.output if self.ok else f"[error] {self.error}" return {"role": "tool", "content": body} @dataclass class ToolSpec: name: str description: str parameters: Dict[str, Any] runner: Callable[..., ToolResult] class ToolRegistry: def __init__(self): self._tools: Dict[str, ToolSpec] = {} def register(self, spec: ToolSpec): self._tools[spec.name] = spec def names(self) -> List[str]: return list(self._tools) def schema(self) -> List[Dict[str, Any]]: """OpenAI / qwen3_coder tool schema (function-calling style).""" return [ { "type": "function", "function": { "name": s.name, "description": s.description, "parameters": s.parameters, }, } for s in self._tools.values() ] def call(self, name: str, args: Dict[str, Any]) -> ToolResult: if name not in self._tools: return ToolResult(ok=False, output="", error=f"unknown tool: {name}") try: return self._tools[name].runner(**args) except TypeError as e: return ToolResult(ok=False, output="", error=f"bad args: {e}") except Exception as e: return ToolResult(ok=False, output="", error=f"{type(e).__name__}: {e}")