# `SuperPi.ACP.Session`
[🔗](https://github.com/oleksandr/super-pi-beam/blob/v0.1.0/lib/super_pi/acp/session.ex#L1)

One ACP session: its id, its conversation, the renderer state and the running prompt.

The `sessionId` is an opaque string (`acp_...`), not the conversation id. Editors such as Zed store
it and send it back on `session/load`, possibly after a restart, so the mapping lives in
`SuperPi.Gateway.Sessions` (a table), per principal.

# `t`

```elixir
@type t() :: %SuperPi.ACP.Session{
  conversation_id: term(),
  cwd: term(),
  id: term(),
  last_end: term(),
  prompt: term(),
  renderer: term()
}
```

# `cancel`

```elixir
@spec cancel(t()) :: :ok
```

Cancels the turn. The order is load-bearing: pending prompts first, then the machine.

# `create`

```elixir
@spec create(String.t(), String.t(), module(), keyword()) :: t()
```

Creates a session and its conversation. `harness` is the harness module.

# `fork`

```elixir
@spec fork(String.t(), t()) :: {:ok, t()} | {:error, term()}
```

Forks the conversation at its latest visible entry into a new session (`_superpi/session/fork`).
`session/load` resumes, so a fork is a separate custom method.

# `load`

```elixir
@spec load(String.t(), String.t(), String.t()) :: {:ok, t()} | :error
```

Finds an existing session. Returns `{:ok, session}` or `:error`.

# `modes`

```elixir
@spec modes(integer()) :: %{required(String.t()) =&gt; term()}
```

The modes a client may pick: up to the remote ceiling and the harness ceiling.

# `pick_harness`

```elixir
@spec pick_harness(map() | nil) :: {:ok, module()} | {:error, String.t()}
```

The harness named in `_meta.harness` of a request, or the default.

# `replay`

```elixir
@spec replay(t()) :: [map()]
```

The history of the session as `session/update` payloads, for `session/load`.

# `set_mode`

```elixir
@spec set_mode(integer(), String.t()) :: :ok | {:error, String.t()}
```

Sets the mode. The mode must be one of `modes/1`.

---

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