# `ExAthena.Result`
[🔗](https://github.com/udin-io/ex_athena/blob/v0.7.1/lib/ex_athena/result.ex#L1)

Canonical run outcome returned by `ExAthena.run/2` and
`ExAthena.Loop.run/2`.

Carries the terminal state plus full accounting so consumers can drive
retries, billing, and observability off a single uniform shape. Every
termination — success OR error — produces a `Result`, including the
caps (`:error_max_turns`, `:error_max_budget_usd`, …).

## Fields

  * `:text` — the assistant's final text (may be empty for error
    terminations).
  * `:messages` — the full conversation thread.
  * `:finish_reason` — a `ExAthena.Loop.Terminations.subtype/0`. See that
    module for the enumeration and category helpers.
  * `:halted_reason` — the `:halt` payload when `finish_reason` is
    `:error_halted`; `nil` otherwise.
  * `:iterations` — number of completed loop iterations.
  * `:tool_calls_made` — total tool calls executed across all iterations.
  * `:usage` — aggregated token usage `%{input_tokens:, output_tokens:,
    total_tokens:}` or nil if the provider didn't report.
  * `:cost_usd` — aggregated cost in USD, nil if unknown.
  * `:duration_ms` — wall-clock time from `ExAthena.run/2` entry to
    termination.
  * `:model` — the model identifier as reported by the provider.
  * `:provider` — the provider atom / module that served the run.
  * `:telemetry` — span metadata summarising OTel attrs for the run
    (Phase 4).

# `t`

```elixir
@type t() :: %ExAthena.Result{
  cost_usd: float() | nil,
  duration_ms: non_neg_integer() | nil,
  finish_reason: ExAthena.Loop.Terminations.subtype(),
  halted_reason: term() | nil,
  iterations: non_neg_integer(),
  messages: [ExAthena.Messages.Message.t()],
  model: String.t() | nil,
  provider: atom() | module() | nil,
  telemetry: map(),
  text: String.t() | nil,
  tool_calls_made: non_neg_integer(),
  usage: usage() | nil
}
```

# `usage`

```elixir
@type usage() :: %{
  optional(:input_tokens) =&gt; non_neg_integer(),
  optional(:output_tokens) =&gt; non_neg_integer(),
  optional(:total_tokens) =&gt; non_neg_integer()
}
```

# `category`

```elixir
@spec category(t()) :: :success | :retryable | :capacity | :fatal
```

Shortcut for `ExAthena.Loop.Terminations.category/1` on this Result.

# `error?`

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

Whether the run ended with an error termination.

# `success?`

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

Whether the run finished normally (no error termination).

---

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