GenAgent.Backends.Claude (GenAgentClaude v0.2.0)

Copy Markdown View Source

GenAgent.Backend implementation backed by ClaudeWrapper.

Each session wraps a set of ClaudeWrapper options (config + query-level) and threads the Claude CLI's session_id across turns so that a persistent conversation is maintained without any ClaudeWrapper.Session or ClaudeWrapper.SessionServer involvement.

Options

start_session/1 accepts ClaudeWrapper.stream/2 options except :no_session_persistence, which cannot be enabled because this backend resumes the CLI session on later turns:

  • Config: :binary, :working_dir (aliased as :cwd), :env, :timeout, :verbose, :debug
  • Query: :model, :system_prompt, :append_system_prompt, :max_turns, :max_budget_usd, :permission_mode, :dangerously_skip_permissions, :effort, :json_schema, :agent, :brief, :include_partial_messages (on by default)

Plus a backend-only option:

  • :stream_fn -- a 2-arity function (prompt, opts) -> Enumerable.t() that replaces the default &ClaudeWrapper.stream/2. Intended for tests; production code should leave this alone.

Session continuation

On the first turn, no :resume flag is passed. When the terminal :result event arrives, update_session/2 captures session_id from the event data and stores it on the session struct. Under GenAgent, prompt/3 also checkpoints a raw system or terminal ID as soon as it arrives, so failed and interrupted turns can resume. Subsequent turns pass that id through Claude's --resume flag, without forwarding the first turn's :session_id or :continue_session options.

terminate_session/1 has no native process to close. GenAgent cancels its prompt task on interrupt, watchdog, stop, or agent death, but the default Port runner closes pipes without guaranteeing that the CLI and its subprocesses have exited. Choose a runner with process-group termination when OS-level settlement is required.

Summary

Types

t()

@type t() :: %GenAgent.Backends.Claude{
  opts: keyword(),
  session_id: String.t() | nil,
  stream_fn: (String.t(), keyword() -> Enumerable.t())
}