ReqAI (req_ai v0.0.1-rc.3)

Copy Markdown View Source

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.

Summary

Functions

Generates a response.

Streams a response into an accumulator.

Functions

generate(module, request)

@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 ReqAI.Translator.response/2; for non-successful responses, it is produced by 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(module, request, acc, fun)

@spec stream(
  provider :: ReqAI.Provider.t() | module(),
  request :: term(),
  acc,
  fun :: (term(), Req.Response.t(), acc -> {: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 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 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 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.