Provider configuration

Copy Markdown View Source

ReqAI.Provider.new/2 accepts a provider module and options. HTTP configuration goes under :req: authentication, headers, timeouts, retries, and other options supported by Req.new/2.

You can set application defaults, supply options when creating a provider, or combine the two.

Application configuration

Set shared HTTP options for each provider in config/config.exs:

import Config

config :req_ai, :providers, [
  {ReqAI.Provider.OpenAI, req: [receive_timeout: 60_000]},
  {ReqAI.Provider.Anthropic, req: [receive_timeout: 60_000]}
]

Read credentials at application startup in config/runtime.exs:

import Config

config :req_ai, :providers, [
  {ReqAI.Provider.OpenAI,
   req: [auth: {:bearer, System.fetch_env!("OPENAI_API_KEY")}]},
  {ReqAI.Provider.Anthropic,
   req: [headers: [{"x-api-key", System.fetch_env!("ANTHROPIC_API_KEY")}]]}
]

Elixir merges these keyword configurations, so the runtime credentials are combined with the timeouts from config/config.exs.

Pass provider modules directly to use those defaults:

ReqAI.generate(ReqAI.Provider.OpenAI, model: "gpt-5.4-mini", input: "Say hello")

Both ReqAI.generate/2 and ReqAI.stream/4 accept modules and call ReqAI.Provider.new/2 with no additional options on every invocation. This reads the current application configuration each time. Only :req options are read from application configuration; translators, custom telemetry, telemetry metadata, and extra provider options require explicit construction.

You can also create and reuse providers to retain the configuration read at construction time:

openai = ReqAI.Provider.new(ReqAI.Provider.OpenAI)
anthropic = ReqAI.Provider.new(ReqAI.Provider.Anthropic)

The built-in adapters supply their API endpoints. The Anthropic adapter also supplies the anthropic-version: 2023-06-01 header unless you override it.

Configure a provider directly

You can instead pass the same HTTP options directly to ReqAI.Provider.new/2, without application configuration:

openai =
  ReqAI.Provider.new(ReqAI.Provider.OpenAI,
    req: [
      auth: {:bearer, System.fetch_env!("OPENAI_API_KEY")},
      receive_timeout: 60_000
    ]
  )

anthropic =
  ReqAI.Provider.new(ReqAI.Provider.Anthropic,
    req: [
      headers: [{"x-api-key", System.fetch_env!("ANTHROPIC_API_KEY")}],
      receive_timeout: 60_000
    ]
  )

ReqAI does not automatically read API key environment variables. These examples explicitly read them and pass their values to Req.

Override request configuration

Options passed when creating a provider take precedence over its application defaults. For example, keep the configured credentials but use a longer receive timeout and disable retries:

openai =
  ReqAI.Provider.new(ReqAI.Provider.OpenAI,
    req: [receive_timeout: 120_000, retry: false]
  )

Options are merged by Req, e.g., explicitly supplied headers replace the configured value for that name.

To use an API-compatible proxy, override :base_url with the full endpoint, including its path:

proxied_openai =
  ReqAI.Provider.new(ReqAI.Provider.OpenAI,
    req: [base_url: "https://llm-proxy.example.com/v1/responses"]
  )

HTTP options and body parameters

Put HTTP options under :req when creating the provider. Put model names and other API body parameters in the request passed to ReqAI.generate/2 or ReqAI.stream/4.

Arbitrary options can be passed to ReqAI.Provider.new/2. These will later be passed to the provider, telemetry, and translator modules when their callbacks are invoked. This enables clients to supply runtime configuration when desired.