# `ALLM.Response`
[🔗](https://github.com/cykod/ALLM/blob/v0.3.0/lib/allm/response.ex#L1)

A single LLM response. See spec §5.5.

Layer A — pure serializable data. Carries the assistant `:message`, optional
top-level `:output_text` convenience, `:tool_calls` the model wants invoked,
`:finish_reason` (closed union), and `:usage` / `:raw` provider extras.

`:output_text` exists so callers can read the flat text payload without
re-deriving it from `:message.content`; use `text/1` for the canonical
fallback behaviour.

# `finish_reason`

```elixir
@type finish_reason() ::
  :stop | :length | :tool_calls | :content_filter | :error | :other
```

Canonical finish-reason atom; see spec §5.5.

# `t`

```elixir
@type t() :: %ALLM.Response{
  finish_reason: finish_reason() | nil,
  id: String.t() | nil,
  message: ALLM.Message.t() | nil,
  metadata: map(),
  model: String.t() | nil,
  output_text: String.t() | nil,
  raw: term(),
  raw_finish_reason: String.t() | nil,
  request_id: String.t() | nil,
  tool_calls: [ALLM.ToolCall.t()],
  usage: ALLM.Usage.t()
}
```

# `new`

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

Build a `%Response{}` from keyword opts.

Every field is optional. Unknown keys raise `ArgumentError` via `struct!/2`.

## Examples

    iex> resp = ALLM.Response.new(output_text: "hi", finish_reason: :stop)
    iex> resp.output_text
    "hi"
    iex> resp.finish_reason
    :stop

# `text`

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

Return the flat text of a response: `:output_text` if set, else the string
`:content` of `:message`, else `nil`.

A list-shaped `message.content` (structured parts) returns `nil` — callers
that need to flatten structured parts should do so explicitly.

## Examples

    iex> ALLM.Response.text(ALLM.Response.new(output_text: "direct"))
    "direct"

    iex> ALLM.Response.text(ALLM.Response.new(message: %ALLM.Message{role: :assistant, content: "from-msg"}))
    "from-msg"

    iex> ALLM.Response.text(ALLM.Response.new([]))
    nil

---

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