# `AgentWorkshop.Backend`
[🔗](https://github.com/joshrotenberg/agent_workshop/blob/main/lib/agent_workshop/backend.ex#L1)

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)

# `config`

```elixir
@type config() :: term()
```

# `result`

```elixir
@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`

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

# `history`

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

Get the full conversation history.

# `last_result`

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

Get the last result, if any.

# `send_message`

```elixir
@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`

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

Get the session ID (if established).

# `start_session`

```elixir
@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`

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

Stop the session process.

# `total_cost`

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

Get the total cost across all turns.

# `turn_count`

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

Get the number of completed turns.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
