# `ReqAI`
[🔗](https://github.com/benjreinhart/req_ai/blob/v0.0.1-rc.3/lib/req_ai.ex#L1)

A lightweight Elixir client for AI APIs, built on Req.

Provides consistent generation, streaming, and telemetry with provider-native
requests and responses. Call `generate/2` or `stream/4` with a provider module
and a provider-native request body. Use `ReqAI.Provider.new/2` to configure
a provider explicitly when additional options are needed.

Optional `ReqAI.Translator` callbacks let applications define their own shared
representations while retaining access to the full `Req.Response`.

# `generate`

```elixir
@spec generate(provider :: ReqAI.Provider.t() | module(), request :: term()) ::
  {:ok, Req.Response.t(), term()}
  | {:error, Req.Response.t(), term()}
  | {:error, Exception.t()}
```

Generates a response.

Accepts a configured provider or a provider module. Passing a module calls
`ReqAI.Provider.new/2` with no additional options on each invocation, reading
the provider's application-configured HTTP options at that time.

The configured provider builds the request with streaming disabled. The
`Req.Response` is always returned unchanged as the second element when the
request completes at the HTTP level. The third element is an
application-owned value produced from that response.

For successful responses, the third element is produced by
`c:ReqAI.Translator.response/2`; for non-successful responses, it is produced
by `c:ReqAI.Translator.error/2`. Both default to `response.body` when their
callback is not implemented. Transport and decoding failures return
`{:error, exception}` because no HTTP response or provider-native body is
available.

# `stream`

```elixir
@spec stream(
  provider :: ReqAI.Provider.t() | module(),
  request :: term(),
  acc,
  fun :: (term(), Req.Response.t(), acc -&gt; {:cont, acc} | {:halt, acc})
) ::
  {:ok, Req.Response.t(), acc}
  | {:error, Req.Response.t(), acc}
  | {:error, Exception.t(), Req.Response.t() | nil, acc}
when acc: term()
```

Streams a response into an accumulator.

Accepts a configured provider or a provider module. Passing a module calls
`ReqAI.Provider.new/2` with no additional options on each invocation, reading
the provider's application-configured HTTP options at that time.

Raises `ArgumentError` if the provider does not implement
`c:ReqAI.Provider.decode_event/3`.

The provider builds the request with streaming enabled. `fun` receives each
provider-native event, the response as it is being received, and the current
accumulator. It must return `{:cont, acc}` to continue or `{:halt, acc}` to
stop consuming the response.

Req handles transport formats such as SSE and NDJSON, then the provider
decodes the resulting values and drops protocol-only events. For the built-in
providers, an SSE event remains a map and its JSON payload is decoded in the
`:data` field. When a translator implements `c:ReqAI.Translator.event/3`, `fun`
receives its return value. The accompanying response remains the in-progress
`Req.Response`.

The completed `Req.Response` remains available. For a successful
stream, the accumulator is the application-owned result of consuming the
translated events. For a non-successful stream, the third element is produced
by `c:ReqAI.Translator.error/2`, defaulting to the buffered response body.

Non-successful HTTP responses are not passed to `fun`. Their streamed data is
instead collected into `response.body`; JSON error bodies are decoded when
possible.

Returns `{:ok, response, acc}` for a successful HTTP response,
`{:error, response, error}` for a non-successful HTTP response, or
`{:error, exception, response, acc}` for a transport or decoding error.

---

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