# `Arcana.Loop.Context`
[🔗](https://github.com/georgeguimaraes/arcana/blob/main/lib/arcana/loop/context.ex#L1)

State carried through an `Arcana.Loop` run.

This is the loop's working memory. It accumulates chunks across iterations,
records the tool history, and tracks termination state.

## Fields

  * `:question` - The original user question.
  * `:repo` - Ecto repo to use for retrieval tools.
  * `:collections` - Collection scope for retrieval tools. Either `:all`, one
    name, or a list of names, where `[]` matches no collections.
  * `:messages` - The `ReqLLM.Context` carrying the running conversation.
  * `:chunks` - Accumulated chunks from `search` tool calls (capped via `:chunk_cap`).
  * `:tool_history` - List of `%{tool, args, iteration, summary}` entries in call order.
  * `:iterations` - Number of LLM controller turns executed.
  * `:answer` - Final answer text once the loop terminates.
  * `:terminated_by` - One of `:answered`, `:gave_up`, `:max_iterations`, `:error`, or `nil`.
  * `:error` - Error reason when `terminated_by == :error`.
  * `:grounding` - Populated by `Arcana.Loop.ground/2` with an
    `%Arcana.Grounding.Result{}` scoring the answer against `ctx.chunks`.
    `nil` until grounding runs.

# `t`

```elixir
@type t() :: %Arcana.Loop.Context{
  answer: String.t() | nil,
  chunks: [map()],
  collections: Arcana.CollectionScope.input(),
  error: term() | nil,
  grounding: Arcana.Grounding.Result.t() | nil,
  iterations: non_neg_integer(),
  messages: term() | nil,
  question: String.t(),
  repo: module() | nil,
  terminated_by: atom() | nil,
  tool_history: [tool_history_entry()]
}
```

# `tool_history_entry`

```elixir
@type tool_history_entry() :: %{
  tool: atom(),
  args: map(),
  iteration: non_neg_integer(),
  summary: String.t()
}
```

---

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