GenAgent.Backends.Anthropic (GenAgentAnthropic v0.2.3)

Copy Markdown View Source

GenAgent.Backend implementation backed by the Anthropic Messages API.

Unlike the CLI-backed backends (GenAgent.Backends.Claude, GenAgent.Backends.Codex), this backend talks directly to an HTTP API. The conversation history lives in the session struct, because the API is stateless -- every request carries the full messages array.

This backend exists primarily as a validation spike for the GenAgent.Backend contract. The CLI backends share a lot of DNA with each other (subprocess + NDJSON + server-side session ids); an HTTP backend inverts most of that. Getting both to fit the same contract without changes is the real test of whether the abstraction is right.

How the two halves of a turn land in the session

  1. prompt/2 appends the user's message to session.messages before making the API call, and returns the updated session along with the event list. The state machine stores that updated session.
  2. When the state machine delivers the terminal :result event, it calls update_session/2 with the event's data, and this backend appends the assistant's message to session.messages.
  3. The next prompt/2 sees both messages in the session and sends the full history to the API.

This uses both sides of the GenAgent.Backend contract in a way the CLI backends don't: CLI backends leave prompt/2's returned session unchanged and do all updates in update_session/2.

Options

  • :api_key -- Anthropic API key. Defaults to System.get_env("ANTHROPIC_API_KEY").
  • :model -- model name. Defaults to "claude-sonnet-4-5".
  • :max_tokens -- max tokens per turn. Defaults to 1024.
  • :system -- system prompt (string).
  • :receive_timeout -- HTTP receive timeout in milliseconds. Defaults to 60_000. Long-context turns (big messages array, slow models) can blow through Req's 15s default, so the backend picks a safer default. Set higher for large debates or longer generations.
  • :connect_timeout -- HTTP connect timeout in milliseconds. Defaults to Req's default when unset.
  • :http_fn -- a 1-arity function (request_map) -> {:ok, response_map} | {:error, term} that replaces the default Req-backed HTTP call. Intended for tests.

Summary

Types

message()

@type message() :: %{role: String.t(), content: String.t()}

t()

@type t() :: %GenAgent.Backends.Anthropic{
  api_key: String.t() | nil,
  client_session_id: String.t(),
  connect_timeout: timeout() | nil,
  http_fn: (map() -> {:ok, map()} | {:error, term()}),
  max_tokens: pos_integer(),
  messages: [message()],
  model: String.t(),
  receive_timeout: timeout(),
  system: String.t() | nil
}