Skip to main content

lib/llm/http_client.ex

defmodule LLM.HTTPClient do
  @moduledoc """
  HTTP client behaviour for LLM API calls.

  The default implementation is `LLM.HTTPClient.Req`, which wraps the
  [Req](https://hex.pm/packages/req) library. You can swap it out for testing
  or to add custom behavior (retries, logging, etc.).

  ## Custom implementation

      defmodule MyApp.HTTPClient do
        @behaviour LLM.HTTPClient

        @impl true
        def request(req) do
          Req.request(req)
        end
      end

  ## Configuration

      # config/config.exs
      config :llm, :http_client, MyApp.HTTPClient

  ## Testing with Mox

      Mox.defmock(LLM.HTTPClient.Mock, for: LLM.HTTPClient)

      # config/test.exs
      config :llm, :http_client, LLM.HTTPClient.Mock
  """

  @callback request(Req.Request.t()) ::
              {:ok, Req.Response.t()} | {:error, term()}

  @doc """
  Make an HTTP request using the configured adapter.

  Defaults to `LLM.HTTPClient.Req`. Override by setting `:http_client` in
  the `:llm` application config.
  """
  def request(req) do
    adapter().request(req)
  end

  defp adapter do
    Application.get_env(:llm, :http_client, __MODULE__.Req)
  end
end