# `AgentSessionManager.Runtime.SessionServer`
[🔗](https://github.com/nshkrdotcom/agent_session_manager/blob/v0.8.0/lib/agent_session_manager/runtime/session_server.ex#L1)

Per-session runtime server (GenServer) providing:

- FIFO run queueing with configurable concurrency slots
- submit/await/cancel run semantics
- event subscriptions backed by the durable event store
- optional `ConcurrencyLimiter` integration
- optional `ControlOperations` integration
- operational APIs: status, drain

## Multi-Slot Concurrency (Phase 2)

The server supports `max_concurrent_runs` greater than 1, allowing
multiple runs to execute in parallel within a single session.
Bounded queue behaviour is preserved and runs never exceed the
configured slot count.

## Durable Subscriptions

Subscribers receive `{:session_event, session_id, event}` messages.
On subscribe, the server backfills events from the store starting at
`:from_sequence`, then delivers live events as they are appended.

The server delegates run lifecycle work to `SessionManager` APIs.

# `submit_opts`

```elixir
@type submit_opts() :: keyword()
```

# `subscribe_opts`

```elixir
@type subscribe_opts() :: [
  from_sequence: non_neg_integer(),
  run_id: String.t(),
  type: AgentSessionManager.Core.Event.event_type()
]
```

# `await_run`

```elixir
@spec await_run(GenServer.server(), String.t(), timeout()) ::
  {:ok, map()} | {:error, AgentSessionManager.Core.Error.t()}
```

# `cancel_run`

```elixir
@spec cancel_run(GenServer.server(), String.t()) ::
  :ok | {:error, AgentSessionManager.Core.Error.t()}
```

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `drain`

```elixir
@spec drain(GenServer.server(), timeout()) :: :ok | {:error, :timeout}
```

Waits for the queue and all in-flight runs to complete.

Returns `:ok` when drained, or `{:error, :timeout}` if the timeout
elapses before all work finishes.

# `execute_run`

```elixir
@spec execute_run(GenServer.server(), map(), keyword()) ::
  {:ok, map()} | {:error, AgentSessionManager.Core.Error.t()}
```

# `interrupt_run`

```elixir
@spec interrupt_run(GenServer.server(), String.t()) ::
  {:ok, String.t()} | :ok | {:error, AgentSessionManager.Core.Error.t()}
```

Interrupts an in-flight run via `ControlOperations` (if configured)
or falls back to cancel via `SessionManager`.

# `start_link`

```elixir
@spec start_link(keyword()) :: GenServer.on_start()
```

# `status`

```elixir
@spec status(GenServer.server()) :: map()
```

# `submit_run`

```elixir
@spec submit_run(GenServer.server(), map(), submit_opts()) ::
  {:ok, String.t()} | {:error, AgentSessionManager.Core.Error.t()}
```

# `subscribe`

```elixir
@spec subscribe(GenServer.server(), subscribe_opts()) ::
  {:ok, reference()} | {:error, AgentSessionManager.Core.Error.t()}
```

# `unsubscribe`

```elixir
@spec unsubscribe(GenServer.server(), reference()) :: :ok
```

---

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