# `MingaAgent.Session.TurnExecution`
[🔗](https://github.com/jsmestad/minga/blob/main/lib/minga_agent/session/turn_execution.ex#L1)

Owns one session's execution mode, runtime phase, and turn-scoped resources.

Transitions are pure. They return the next owned value or a domain outcome; `MingaAgent.Session` remains responsible for provider calls, notifications, broadcasts, transcript updates, and persistence.

# `active_tool`

```elixir
@type active_tool() :: {tool_call_id :: String.t(), name :: String.t()}
```

An active provider tool identified by its stable call ID.

# `activity`

```elixir
@type activity() ::
  :starting | :thinking | :completion | {:tool_execution, [active_tool(), ...]}
```

Provider activity within one active turn.

# `approval_decision`

```elixir
@type approval_decision() :: :approve | :approve_session | :approve_turn | :reject
```

Supported approval response.

# `content`

```elixir
@type content() :: String.t() | [ReqLLM.Message.ContentPart.t()]
```

Prompt content admitted to steering and follow-up queues.

# `mode`

```elixir
@type mode() :: :exec | :plan
```

Execution mode, independent of whether a provider turn is active.

# `phase`

```elixir
@type phase() ::
  :idle
  | {:active, activity(), MingaAgent.ToolApproval.t() | nil, String.t() | nil}
  | {:failure, String.t()}
```

Runtime phase. Approval and nonterminal error presentation are orthogonal to provider activity within an active turn.

# `prompt_admission`

```elixir
@type prompt_admission() :: {:send_now, t()} | {:queued, t()}
```

Whether a prompt starts a turn now or joins one of the active turn's queues.

# `prompt_kind`

```elixir
@type prompt_kind() :: :steering | :follow_up
```

How an active turn should admit an additional prompt.

# `status`

```elixir
@type status() :: :idle | :plan | :thinking | :tool_executing | :error
```

Public status retained at the Session API boundary.

# `t`

```elixir
@type t() :: %MingaAgent.Session.TurnExecution{
  boundaries: %{required(String.t()) =&gt; MingaAgent.EditBoundary.t()},
  follow_up_queue: [content()],
  mode: mode(),
  pending_auto_approvals: %{required(String.t()) =&gt; trust_scope()},
  phase: phase(),
  steering_queue: [content()],
  trust_levels: %{required(String.t()) =&gt; trust_scope()}
}
```

Canonical turn execution state.

# `trust_scope`

```elixir
@type trust_scope() :: :session | :turn
```

Tool trust lifetime.

# `abort`

```elixir
@spec abort(t()) :: t()
```

Aborts provider and tool work before returning to an inactive phase.

# `active?`

```elixir
@spec active?(t()) :: boolean()
```

Returns true while provider work belongs to the current turn.

# `active_tool_name`

```elixir
@spec active_tool_name(t()) :: String.t() | nil
```

Returns the most recently started active tool name.

# `active_tools`

```elixir
@spec active_tools(t()) :: [active_tool()]
```

Returns active tools in provider start order.

# `admit_prompt`

```elixir
@spec admit_prompt(t(), prompt_kind(), content()) :: prompt_admission()
```

Admits a prompt by starting an inactive turn or queueing behind an active turn.

# `auto_approve`

```elixir
@spec auto_approve(t(), MingaAgent.Event.ToolApproval.t(), trust_scope()) ::
  {:approved, MingaAgent.ToolApproval.t(), t()}
  | {:rejected, MingaAgent.ToolApproval.t()}
```

Records a trusted approval, or rejects it outside an admitted turn.

# `begin_completion`

```elixir
@spec begin_completion(t()) :: {:ok, t()} | {:error, :invalid_phase}
```

Moves an admitted turn into completion.

# `begin_turn`

```elixir
@spec begin_turn(t()) :: {:ok, t()} | {:error, :turn_active}
```

Begins a provider turn from an inactive state.

# `boundary`

```elixir
@spec boundary(t(), String.t()) :: {non_neg_integer(), non_neg_integer()} | nil
```

Returns one edit boundary as its public line tuple.

# `clear_boundaries`

```elixir
@spec clear_boundaries(t()) :: t()
```

Clears every edit boundary.

# `clear_boundary`

```elixir
@spec clear_boundary(t(), String.t()) :: t()
```

Clears one edit boundary.

# `clear_queues`

```elixir
@spec clear_queues(t()) :: t()
```

Clears both prompt queues.

# `dequeue_steering`

```elixir
@spec dequeue_steering(t()) :: {[content()], t()}
```

Dequeues steering prompts without changing follow-up admission.

# `enter_exec`

```elixir
@spec enter_exec(t()) :: {:changed, t()} | :unchanged
```

Switches from plan mode to execution mode.

# `enter_plan`

```elixir
@spec enter_plan(t()) :: t()
```

Switches to plan mode while preserving the runtime phase.

# `error`

```elixir
@spec error(t()) :: String.t() | nil
```

Returns the current error message, if any.

# `fail`

```elixir
@spec fail(t(), String.t()) :: t()
```

Moves any runtime phase into failure and clears turn-owned active resources.

# `finish_completion`

```elixir
@spec finish_completion(t()) ::
  {:idle, t()} | {:send_next, [content(), ...], t()} | {:error, :invalid_phase}
```

Finishes completion, clearing turn trust before admitting queued work.

# `mode`

```elixir
@spec mode(t()) :: mode()
```

Returns the current execution mode.

# `new`

```elixir
@spec new(mode()) :: t()
```

Builds an idle execution state.

# `pending_approval`

```elixir
@spec pending_approval(t()) :: MingaAgent.ToolApproval.t() | nil
```

Returns the current pending approval, if any.

# `phase`

```elixir
@spec phase(t()) ::
  :idle
  | :starting
  | :thinking
  | :approval_waiting
  | :tool_execution
  | :completion
  | :failure
```

Returns the current runtime phase name.

# `provider_started`

```elixir
@spec provider_started(t()) :: {:ok, t()} | {:error, :invalid_phase}
```

Accepts the provider's turn-start event.

# `put_trust`

```elixir
@spec put_trust(t(), String.t(), trust_scope()) :: t()
```

Adds or replaces one tool trust decision.

# `queued_send_failed`

```elixir
@spec queued_send_failed(t()) :: {:ok, t()} | {:error, :invalid_phase}
```

Returns a failed queued-send transition to idle without restoring consumed entries.

# `queues`

```elixir
@spec queues(t()) :: {[content()], [content()]}
```

Returns steering and follow-up queues in FIFO order.

# `recall_queues`

```elixir
@spec recall_queues(t()) :: {{[content()], [content()]}, t()}
```

Returns and clears both prompt queues.

# `reclaimable?`

```elixir
@spec reclaimable?(t()) :: boolean()
```

Returns true when turn state does not prevent detached-session reclamation.

# `recover`

```elixir
@spec recover(t()) :: {:changed, t()} | :unchanged
```

Clears a provider failure after provider recovery.

# `report_error`

```elixir
@spec report_error(t(), String.t()) :: t()
```

Records a provider-reported error without discarding active turn work.

# `request_approval`

```elixir
@spec request_approval(t(), MingaAgent.ToolApproval.t()) ::
  {:accepted, t()} | :rejected
```

Moves an active turn into approval waiting.

# `reset`

```elixir
@spec reset(t()) :: t()
```

Resets every turn resource for a fresh session.

# `resolve_approval`

```elixir
@spec resolve_approval(t(), String.t() | nil, approval_decision()) ::
  {:ok, MingaAgent.ToolApproval.t(), t()}
  | {:error, :approval_not_found | :no_pending_approval}
```

Resolves the matching pending approval and restores the active runtime phase.

# `restore`

```elixir
@spec restore(t()) :: t()
```

Restores an idle execution value after live work is cleaned up.

# `revoke_trust`

```elixir
@spec revoke_trust(t(), String.t() | :all) :: t()
```

Removes one or all tool trust decisions.

# `set_boundary`

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

Validates and stores an edit boundary by absolute path.

# `status`

```elixir
@spec status(t()) :: status()
```

Derives the stable public Session status.

# `tool_completed`

```elixir
@spec tool_completed(t(), MingaAgent.Event.ToolEnd.t()) ::
  {:ok, t()} | {:error, :tool_not_active}
```

Completes one matching active tool and rejects stale or duplicate completions.

# `tool_name`

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

Returns the name for one active tool call.

# `tool_started`

```elixir
@spec tool_started(t(), MingaAgent.Event.ToolStart.t()) ::
  {:ok, trust_scope() | nil, t()}
  | {:error, :invalid_phase | :tool_already_active}
```

Starts one tool and records its stable identity.

# `trust_levels`

```elixir
@spec trust_levels(t()) :: %{required(String.t()) =&gt; trust_scope()}
```

Returns all current tool trust decisions.

# `trusted_scope`

```elixir
@spec trusted_scope(t(), MingaAgent.Event.ToolApproval.t()) :: trust_scope() | nil
```

Returns the matching trust scope for one provider approval event.

# `update_failure`

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

Updates the current provider failure presentation without changing its phase.

---

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