AgentWorkshop.Backend behaviour (AgentWorkshop v0.3.0)

Copy Markdown View Source

Behaviour for LLM CLI backends.

Workshop uses this behaviour to communicate with agents. Each backend wraps a specific CLI tool (Claude, Codex, etc.) and provides a uniform interface for session management and message passing.

Implementing a backend

defmodule MyApp.ClaudeBackend do
  @behaviour AgentWorkshop.Backend

  @impl true
  def start_session(config, opts) do
    # Start a session process, return {:ok, pid}
  end

  @impl true
  def send_message(server, prompt, opts) do
    # Send a message, return {:ok, result} or {:error, reason}
  end

  # ... other callbacks
end

Result map

The result type is a map with these keys:

  • :result - response text (string)
  • :session_id - session identifier for continuation (string or nil)
  • :cost_usd - cost in USD (float or nil)
  • :is_error - whether this is an error result (boolean)
  • :duration_ms - execution time (integer or nil)
  • :num_turns - number of turns (integer or nil)

Summary

Callbacks

Get the full conversation history.

Get the last result, if any.

Send a message to a session. Blocks until the response is ready.

Get the session ID (if established).

Start a new session process.

Stop the session process.

Get the total cost across all turns.

Get the number of completed turns.

Types

config()

@type config() :: term()

result()

@type result() :: %{
  result: String.t(),
  session_id: String.t() | nil,
  cost_usd: float() | nil,
  is_error: boolean(),
  duration_ms: non_neg_integer() | nil,
  num_turns: non_neg_integer() | nil
}

server()

@type server() :: GenServer.server()

Callbacks

history(server)

@callback history(server()) :: [result()]

Get the full conversation history.

last_result(server)

@callback last_result(server()) :: result() | nil

Get the last result, if any.

send_message(server, t, keyword)

@callback send_message(server(), String.t(), keyword()) ::
  {:ok, result()} | {:error, term()}

Send a message to a session. Blocks until the response is ready.

session_id(server)

@callback session_id(server()) :: String.t() | nil

Get the session ID (if established).

start_session(config, keyword)

@callback start_session(
  config(),
  keyword()
) :: {:ok, pid()} | {:error, term()}

Start a new session process.

Returns {:ok, pid} where pid is a process that can receive send_message/3 calls. The process should be linkable for supervision.

stop_session(server)

@callback stop_session(server()) :: :ok

Stop the session process.

total_cost(server)

@callback total_cost(server()) :: float()

Get the total cost across all turns.

turn_count(server)

@callback turn_count(server()) :: non_neg_integer()

Get the number of completed turns.