# ToolCall

[![CI](https://github.com/gilbertwong96/tool_call/actions/workflows/ci.yml/badge.svg)](https://github.com/gilbertwong96/tool_call/actions/workflows/ci.yml)
[![codecov](https://codecov.io/gh/gilbertwong96/tool_call/graph/badge.svg)](https://codecov.io/gh/gilbertwong96/tool_call)
[![Elixir](https://img.shields.io/badge/elixir-1.18+-purple.svg)](https://elixir-lang.org)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)

Derive LLM tool-call schemas from Elixir `@spec` and `@doc`, then dispatch the
call back to the function.

No DSL, no second schema, no runtime reflection.

```elixir
defmodule MyApp.Tools.Weather do
  use ToolCall

  @doc """
  Get the forecast for a city.

  ## Parameters
    * `city` - city name
    * `days` - how many days ahead
  """
  @spec get_weather(city :: String.t(), days :: pos_integer() | nil) ::
          {:ok, map()} | {:error, String.t()}
  def get_weather(city, days \\ 3) do
    {:ok, %{city: city, days: days, temp: 21.5}}
  end
end
```

```elixir
ToolCall.emit(MyApp.Tools.Weather, :openai)

ToolCall.run(MyApp.Tools.Weather, :get_weather, %{"city" => "Oslo"})
#=> {:ok, %{city: "Oslo", days: 3, temp: 21.5}}
```

## Installation

```elixir
def deps do
  [tool_call: "~> 0.1"]
end
```

Requires Elixir `~> 1.18` and Erlang/OTP 27.1+. The OTP floor is enforced at
compile time; there are no runtime dependencies.

## What you get

- `ToolCall.emit/3` — OpenAI and Anthropic schemas, precompiled per module.
- `ToolCall.run/3` — required/unknown argument checks, coercion, exception
  wrapping, and dispatch to the real function.
- `ToolCall.tools/1` and `ToolCall.describe/2` — the IR and provider-neutral
  schema descriptions.
- `use ToolCall, types: [...]` — custom `ToolCall.TypeProvider` integrations.
- `mix tool_call.export` — JSON for OpenAI, Anthropic or MCP.
- `mix tool_call.clean` — removes orphaned typedoc companion beams.

## Documentation

The full documentation is generated by `mix docs`:

- [`CHANGELOG.md`](CHANGELOG.md) — release history.
- [`docs/usage.md`](docs/usage.md) — defining, emitting, dispatching, exporting,
  conventions, and error terms.
- [`docs/design.md`](docs/design.md) — architecture, type mapping, typedoc
  companions, provider subsets, and design boundaries.
- [`docs/pitfalls.md`](docs/pitfalls.md) — compile-time traps and their
  trade-offs.
- [`docs/number-handling.md`](docs/number-handling.md) — large integers and JSON
  precision.
- [`docs/roadmap.md`](docs/roadmap.md) — current status and planned stages.

## Development

```sh
mix deps.get
mix ci
mix coveralls.html
```

`mix ci` runs compile/format checks, tests, `spec_lint`, Credo, Dialyzer,
ExDNA and Reach. `mix coveralls.html` writes the HTML coverage report to
`cover/` and fails below 100%. CI uploads the report to Codecov when
`CODECOV_TOKEN` is configured.

## License

MIT
