# API

This document describes the public surface area re-exported from:
- `../src/openai_resptools/__init__.py`

## Exports

### ToolRegistry

Source: `../src/openai_resptools/registry.py`

Purpose:
- Store tool definitions (`ToolDef`) by name
- Build the `tools=[...]` payload for `client.responses.create(...)`

Key methods:
- `ToolRegistry.tool(...)`: decorator to register a callable as a tool
  - `name`: override tool name (defaults to function name)
  - `description`: override description (defaults to docstring)
  - `parameters`: override JSON schema parameters; still validates args from signature/type hints
  - `strict`: if true, schema uses strict mode (see schema doc)
  - `overwrite`: allow overwriting an existing tool name
- `ToolRegistry.add(tool_def, overwrite=False)`: register an existing `ToolDef`
- `ToolRegistry.get(name)`: get tool or raise `ToolNotFoundError`
- `ToolRegistry.maybe_get(name)`: get tool or return `None`
- `ToolRegistry.names()`: list tool names
- `ToolRegistry.as_openai_tools()`: list of OpenAI function tool payloads
- `ToolRegistry.allowed_tools_choice(names=None, mode="auto", validate=True)`: build `tool_choice` payload

Notes:
- When you instantiate `ToolRegistry`, it auto-scans itself for public methods if used as a subclass pattern.

### ToolDef

Source: `../src/openai_resptools/tool.py`

Purpose:
- Bind a callable to (a) an OpenAI tool schema and (b) a Pydantic args validator.

Key methods:
- `ToolDef.from_callable(func, name=None, description=None, parameters=None, strict=True)`
- `ToolDef.validate_args(raw_args: dict) -> dict`
- `ToolDef.call(raw_args: dict) -> Any`
- `ToolDef.call_and_serialize(raw_args: dict) -> str`

Behavior notes:
- Argument validation uses Pydantic (`model_validate`).
- Output serialization uses `json_dumps(...)` from `../src/openai_resptools/serialize.py`.

### ToolRunner

Source: `../src/openai_resptools/runner.py`

Purpose:
- Run the loop: call model → execute tools → feed tool outputs back → stop on final text.

Constructor:
- `ToolRunner(client, model, registry, max_iters=8, max_retry=0, parallel_tool_calls=None, on_event=None)`

`run(...)`:
- `run(prompt_or_input, tool_choice=None, instructions=None, extra=None) -> RunnerResult`
  - `prompt_or_input` can be a string prompt or a list of input items
  - `tool_choice` is passed through to the Responses API
  - `instructions` is passed through to the Responses API
  - `extra` is merged into request kwargs (advanced usage)

Events (if `on_event` provided):
- `llm.request`
- `llm.response`
- `tool.call`
- `tool.output`

### run(...)

Source: `../src/openai_resptools/runner.py`

Convenience function:
- `run(client, model, registry, prompt, tool_choice=None, instructions=None, max_iters=8, max_retry=0) -> RunnerResult`

### RunnerResult

Source: `../src/openai_resptools/types.py`

Fields:
- `text: str` (final output text when the model stops calling tools)
- `input_items: Sequence[dict]` (the full accumulated input items)
- `last_response: Any` (SDK response object)

### Errors

Source: `../src/openai_resptools/errors.py`

- `ToolNotFoundError`
- `ToolArgumentsError`
- `ToolExecutionError`
- `RunnerError`
- `RunnerMaxIterationsError`

