# `PtcRunner.SubAgent.ToolSchema`
[🔗](https://github.com/andreasronge/ptc_runner/blob/main/lib/ptc_runner/sub_agent/tool_schema.ex#L1)

Converts Tool structs to OpenAI-format JSON Schema tool definitions.

Used by `:tool_calling` mode to provide tool schemas to the LLM API.

# `sanitize_name`

```elixir
@spec sanitize_name(String.t()) :: String.t()
```

Sanitize a tool name for LLM provider APIs.

Replaces hyphens with underscores since most LLM providers require
tool names to match `[a-zA-Z0-9_]+`. PTC-Lisp mode uses hyphens
(e.g., `grep-n`, `llm-query`) but these are invalid in native tool calling APIs.

## Examples

    iex> PtcRunner.SubAgent.ToolSchema.sanitize_name("grep-n")
    "grep_n"

    iex> PtcRunner.SubAgent.ToolSchema.sanitize_name("search")
    "search"

# `to_tool_definition`

```elixir
@spec to_tool_definition(PtcRunner.Tool.t()) :: map()
```

Convert a single Tool struct to an OpenAI-format tool definition.

## Examples

    iex> {:ok, tool} = PtcRunner.Tool.new("greet", {fn _ -> "hi" end, signature: "(name :string) -> :string", description: "Greet someone"})
    iex> defn = PtcRunner.SubAgent.ToolSchema.to_tool_definition(tool)
    iex> defn["function"]["name"]
    "greet"
    iex> defn["function"]["parameters"]["properties"]["name"]
    %{"type" => "string"}

# `to_tool_definitions`

```elixir
@spec to_tool_definitions(map()) :: [map()]
```

Convert a tools map to a list of OpenAI-format tool definitions.

Each tool is converted to a map with `"type" => "function"` and
a `"function"` key containing name, description, and parameters schema.

## Examples

    iex> tools = %{"search" => fn _ -> [] end}
    iex> defs = PtcRunner.SubAgent.ToolSchema.to_tool_definitions(tools)
    iex> length(defs)
    1
    iex> hd(defs)["function"]["name"]
    "search"

---

*Consult [api-reference.md](api-reference.md) for complete listing*
