# `AgentSessionManager.Core.Run`
[🔗](https://github.com/nshkrdotcom/agent_session_manager/blob/v0.8.0/lib/agent_session_manager/core/run.ex#L1)

Represents a single execution run within a session.

A run represents one complete interaction with the AI agent,
including input, output, and any intermediate steps (turns).

## Run Lifecycle

Runs follow this state machine:

    pending -> running -> completed
                      -> failed
                      -> cancelled
                      -> timeout

## Fields

- `id` - Unique run identifier
- `session_id` - Parent session identifier
- `status` - Current run status
- `input` - Input data for the run
- `output` - Output data from the run
- `error` - Error information if the run failed
- `metadata` - Arbitrary metadata
- `turn_count` - Number of turns in this run
- `token_usage` - Token usage statistics
- `started_at` - Run start timestamp
- `ended_at` - Run end timestamp

## Usage

    # Create a new run
    {:ok, run} = Run.new(%{session_id: "session-123"})

    # Start the run
    {:ok, running} = Run.update_status(run, :running)

    # Set output and complete
    {:ok, completed} = Run.set_output(running, %{response: "Hello!"})

# `status`

```elixir
@type status() :: :pending | :running | :completed | :failed | :cancelled | :timeout
```

# `t`

```elixir
@type t() :: %AgentSessionManager.Core.Run{
  cost_usd: float() | nil,
  ended_at: DateTime.t() | nil,
  error: map() | nil,
  id: String.t() | nil,
  input: map() | nil,
  metadata: map(),
  output: map() | nil,
  provider: String.t() | nil,
  provider_metadata: map(),
  session_id: String.t() | nil,
  started_at: DateTime.t() | nil,
  status: status(),
  token_usage: map(),
  turn_count: non_neg_integer()
}
```

# `from_map`

```elixir
@spec from_map(map()) :: {:ok, t()} | {:error, AgentSessionManager.Core.Error.t()}
```

Reconstructs a run from a map.

# `increment_turn`

```elixir
@spec increment_turn(t()) :: {:ok, t()}
```

Increments the turn count by 1.

# `new`

```elixir
@spec new(map()) :: {:ok, t()} | {:error, AgentSessionManager.Core.Error.t()}
```

Creates a new run with the given attributes.

## Required

- `:session_id` - The parent session identifier

## Optional

- `:id` - Custom ID (auto-generated if not provided)
- `:input` - Input data for the run
- `:metadata` - Arbitrary metadata map

## Examples

    iex> Run.new(%{session_id: "session-123"})
    {:ok, %Run{session_id: "session-123", status: :pending, ...}}

    iex> Run.new(%{})
    {:error, %Error{code: :validation_error, ...}}

# `set_error`

```elixir
@spec set_error(t(), map()) :: {:ok, t()}
```

Sets the error and marks the run as failed.

# `set_output`

```elixir
@spec set_output(t(), map()) :: {:ok, t()}
```

Sets the output and marks the run as completed.

# `to_map`

```elixir
@spec to_map(t()) :: map()
```

Converts a run to a map suitable for JSON serialization.

# `update_status`

```elixir
@spec update_status(t(), status()) ::
  {:ok, t()} | {:error, AgentSessionManager.Core.Error.t()}
```

Updates the run status.

## Valid statuses

- `:pending` - Run created but not started
- `:running` - Run is currently executing
- `:completed` - Run completed successfully
- `:failed` - Run failed
- `:cancelled` - Run was cancelled
- `:timeout` - Run timed out

Terminal statuses (:completed, :failed, :cancelled, :timeout) will
automatically set the `ended_at` timestamp.

## Examples

    iex> {:ok, run} = Run.new(%{session_id: "session"})
    iex> Run.update_status(run, :running)
    {:ok, %Run{status: :running, ended_at: nil, ...}}

    iex> Run.update_status(run, :completed)
    {:ok, %Run{status: :completed, ended_at: %DateTime{}, ...}}

# `update_token_usage`

```elixir
@spec update_token_usage(t(), map()) :: {:ok, t()}
```

Updates token usage statistics.

Token usage is accumulated across multiple updates.

---

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