# `Alloy.Agent.State`
[🔗](https://github.com/alloy-ex/alloy/blob/v0.10.1/lib/alloy/agent/state.ex#L1)

Mutable state for an agent run.

Tracks the conversation history, turn count, token usage, and
current status. Passed through each iteration of the agent loop.

# `status`

```elixir
@type status() ::
  :idle
  | :running
  | :completed
  | :error
  | :max_turns
  | :budget_exceeded
  | :halted
```

# `t`

```elixir
@type t() :: %Alloy.Agent.State{
  agent_id: String.t(),
  config: Alloy.Agent.Config.t(),
  current_task: {reference(), pid(), binary()} | nil,
  error: term() | nil,
  messages: [Alloy.Message.t()],
  messages_new: [Alloy.Message.t()],
  pending_requests: term(),
  provider_response_metadata: map(),
  provider_state: map(),
  run_metadata: map(),
  started_at: integer() | nil,
  status: status(),
  tool_calls: [map()],
  tool_defs: [map()],
  tool_fns: %{required(String.t()) =&gt; module()},
  turn: non_neg_integer(),
  usage: Alloy.Usage.t()
}
```

# `append_messages`

```elixir
@spec append_messages(t(), [Alloy.Message.t()] | Alloy.Message.t()) :: t()
```

Append messages to the conversation history.

Uses an internal accumulator for O(1) append. Call `messages/1` to
retrieve the full list in chronological order.

# `append_tool_calls`

```elixir
@spec append_tool_calls(t(), [map()]) :: t()
```

Append tool execution metadata for the current run.

# `cleanup`

```elixir
@spec cleanup(t()) :: :ok
```

Clean up resources owned by this state. No-op currently; reserved
for future resource management.

# `increment_turn`

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

Increment the turn counter.

# `init`

```elixir
@spec init(Alloy.Agent.Config.t(), [Alloy.Message.t()]) :: t()
```

Initialize state from config and optional existing messages.

# `last_assistant_text`

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

Extract the text from the last assistant message.

# `materialize`

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

Flush the accumulator into the messages field.

After this call, `state.messages` contains the full chronological
list and `state.messages_new` is empty. Call at process boundaries
where code reads `state.messages` directly.

# `merge_provider_state`

```elixir
@spec merge_provider_state(t(), map() | nil) :: t()
```

Merge provider-owned state returned by the model backend.

# `merge_run_metadata`

```elixir
@spec merge_run_metadata(t(), map() | nil) :: t()
```

Merge agent-loop runtime metadata for the current run.

# `merge_usage`

```elixir
@spec merge_usage(t(), map()) :: t()
```

Merge usage from a provider response.

# `messages`

```elixir
@spec messages(t()) :: [Alloy.Message.t()]
```

Return messages in chronological order.

Flushes the internal accumulator and returns the full message list.

# `put_provider_response_metadata`

```elixir
@spec put_provider_response_metadata(t(), map() | nil) :: t()
```

Replace the latest provider response metadata for this run.

---

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