# `LLMProxy.Providers.Behaviour`
[🔗](https://github.com/elixir-vibe/llm_proxy/blob/v0.3.1/lib/llm_proxy/providers/behaviour.ex#L1)

Behaviour for LLM provider implementations.

Providers receive native request bodies and return `LLMProxy.Providers.Result` structs.
Wire JSON stays at protocol/provider boundaries.

# `call_result`

```elixir
@type call_result() ::
  {:ok, LLMProxy.Providers.Result.t()} | {:error, LLMProxy.Providers.Result.t()}
```

# `stream`

```elixir
@type stream() :: Enumerable.t()
```

# `stream_result`

```elixir
@type stream_result() ::
  {:ok, LLMProxy.Providers.Result.t()} | {:error, LLMProxy.Providers.Result.t()}
```

# `usage`

```elixir
@type usage() :: LLMProxy.Usage.t()
```

# `call`

```elixir
@callback call(body :: map(), user_id :: String.t()) :: call_result()
```

Non-streaming call. Body is in the provider's native protocol format.

# `call_native`
*optional* 

```elixir
@callback call_native(body :: map(), user_id :: String.t()) :: call_result()
```

Non-streaming native passthrough. Routes pass the validated native wire body explicitly.

# `extract_usage`

```elixir
@callback extract_usage(response :: map()) :: usage()
```

Extract usage from a non-streaming response body

# `models`

```elixir
@callback models() :: [String.t()]
```

List of model IDs this provider handles

# `name`

```elixir
@callback name() :: String.t()
```

Provider name, e.g. "anthropic", "openrouter"

# `native_protocol`

```elixir
@callback native_protocol() :: :openai | :anthropic
```

The native API protocol this provider speaks (:openai or :anthropic)

# `stream`

```elixir
@callback stream(body :: map(), user_id :: String.t()) :: stream_result()
```

Streaming call. Body is in the provider's native protocol format.

# `stream_error`
*optional* 

```elixir
@callback stream_error(reason :: term(), token :: map() | nil) ::
  LLMProxy.Providers.Result.t()
```

Legacy stream-error projection without model identity

# `stream_error`
*optional* 

```elixir
@callback stream_error(reason :: term(), token :: map() | nil, model :: String.t()) ::
  LLMProxy.Providers.Result.t()
```

Project an exception raised while lazily consuming a provider stream

# `stream_native`
*optional* 

```elixir
@callback stream_native(body :: map(), user_id :: String.t()) :: stream_result()
```

Streaming native passthrough. Routes pass the validated native wire body explicitly.

# `to_openai_response`

```elixir
@callback to_openai_response(response :: map(), model :: String.t()) :: map()
```

Convert native response to OpenAI chat completion format

---

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