# `Nous.Session.Guardrails`
[🔗](https://github.com/nyo16/nous/blob/v0.17.1/lib/nous/session/guardrails.ex#L1)

Session limit checking and guardrail functions.

Works with `Nous.Session.Config` to enforce turn limits,
token budgets, and compaction triggers.

## Example: GenServer integration

    defmodule MySession do
      use GenServer

      def handle_call({:send, message}, _from, state) do
        case Guardrails.check_limits(state.config, state.turns, state.in_tokens, state.out_tokens) do
          :ok ->
            # proceed with agent call
            ...
          {:error, reason} ->
            {:reply, {:error, reason}, state}
        end
      end
    end

# `check_limits`

```elixir
@spec check_limits(
  Nous.Session.Config.t(),
  non_neg_integer(),
  non_neg_integer(),
  non_neg_integer()
) ::
  :ok | {:error, :max_turns_reached | :max_budget_reached}
```

Checks whether a session has exceeded its configured limits.

Returns `:ok` if within limits, or `{:error, reason}` if a limit is hit.

## Examples

    iex> config = %Nous.Session.Config{max_turns: 10, max_budget_tokens: 100_000}
    iex> Nous.Session.Guardrails.check_limits(config, 5, 1000, 2000)
    :ok

    iex> config = %Nous.Session.Config{max_turns: 10, max_budget_tokens: 100_000}
    iex> Nous.Session.Guardrails.check_limits(config, 10, 1000, 2000)
    {:error, :max_turns_reached}

# `remaining`

```elixir
@spec remaining(
  Nous.Session.Config.t(),
  non_neg_integer(),
  non_neg_integer(),
  non_neg_integer()
) ::
  {non_neg_integer(), non_neg_integer()}
```

Returns remaining budget as `{remaining_turns, remaining_tokens}`.

## Examples

    iex> config = %Nous.Session.Config{max_turns: 10, max_budget_tokens: 100_000}
    iex> Nous.Session.Guardrails.remaining(config, 3, 5000, 10000)
    {7, 85000}

# `should_compact?`

```elixir
@spec should_compact?(Nous.Session.Config.t(), non_neg_integer()) :: boolean()
```

Checks if the session should trigger compaction.

## Examples

    iex> config = %Nous.Session.Config{compact_after_turns: 20}
    iex> Nous.Session.Guardrails.should_compact?(config, 25)
    true

    iex> config = %Nous.Session.Config{compact_after_turns: 20}
    iex> Nous.Session.Guardrails.should_compact?(config, 15)
    false

# `summary`

```elixir
@spec summary(
  Nous.Session.Config.t(),
  non_neg_integer(),
  non_neg_integer(),
  non_neg_integer()
) :: map()
```

Returns a summary map of the session's current state against its limits.

Useful for logging or exposing session health to users.

## Examples

    Nous.Session.Guardrails.summary(config, 5, 10_000, 20_000)
    #=> %{
    #=>   turns: %{current: 5, max: 10, remaining: 5},
    #=>   tokens: %{used: 30_000, max: 200_000, remaining: 170_000},
    #=>   needs_compaction: false
    #=> }

---

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