Claudio.Messages.Response (Claudio v0.7.0)
View SourceStructured response from the Messages API.
stop_details is the raw API map ("type", "category", "explanation"), set only
when stop_reason is :refusal. With Request.set_fallbacks/2 it can also carry
"recommended_model" (a model to retry directly when the fallback attempt was
skipped), "fallback_credit_token" and "fallback_has_prefill_claim". For streamed
responses it is read from message_delta.delta next to stop_reason; that location
is unconfirmed in Anthropic's streaming docs.
diagnostics is carried raw (see Request.enable_cache_diagnostics/2):
nil when diagnostics were not requested, there was nothing to compare, or the
comparison found no divergence; %{"cache_miss_reason" => nil} when the comparison
was still pending (inconclusive — check the next turn); otherwise a reason map such
as %{"cache_miss_reason" => %{"type" => "system_changed", "cache_missed_input_tokens" => n}}.
With Request.set_fallbacks/2, a refused request may be retried on another model.
Each handoff is a :fallback content block (fallbacks/1); served_by/1 names the
model that produced the message, and usage.iterations records every attempt.
Context management: context_management is the raw response map
(%{"applied_edits" => [...]}, nil when the request configured no edits). A
:compaction content block holds a compaction summary; stop_reason is :compaction
when the reply is only that block (on-demand compaction, or pause_after_compaction).
Continue with Request.apply_compaction/2.
input_transformations (only with the thinking-binding-controls-2026-08-01 beta, see
Request.set_thinking_block_binding/2) is the raw list of what the API changed in the
input: entries %{"type" => "thinking_dropped" | "thinking_mismatch_allowed", "path" => "messages.N.content.M", "reason" => "prefix_binding_mismatch" | "model_binding_mismatch"}.
[] when nothing changed; nil without the beta. Ignore unknown type/reason values.
usage keeps every field the API returns: documented fields are atom keys (nil
when absent); any other field keeps the key it arrived with (so it may be a string
key). This applies when both input_tokens and output_tokens are present (either
key style); a usage map missing one of them is returned as received.
Summary
Types
A compaction summary (Request.add_compaction/2 threshold compaction, or
Request.request_compaction/2 on demand). content is the summary text (nil when
compaction failed). raw is the block as received — including signature for on-demand
blocks — and is what to_assistant_content/1 replays.
A server-side fallback handoff (Request.set_fallbacks/2). raw is the block as
received; Response.to_assistant_content/1 re-emits it unchanged.
A server-tool result other than web search (web_fetch_tool_result,
code_execution_tool_result, bash_code_execution_tool_result,
text_editor_code_execution_tool_result, tool_search_tool_result,
advisor_tool_result). content is the raw nested value (its variants and error codes
change over time); raw is the block as received and is what
to_assistant_content/1 replays.
Token usage. Documented fields are atom keys (nil when the API did not send
them); any other field the API returns is kept under the key it arrived with.
A usage map missing input_tokens or output_tokens is returned as received.
iterations (present when fallbacks was set) lists each attempt as the raw
API map: "type" => "message" for a model that declined, "fallback_message"
for the one that served; the top-level counts cover only the returned attempt.
With compaction, iterations also holds "type" => "compaction" entries; the top-level
counts exclude them (the billed total is the sum over iterations).
Functions
Returns the last compaction block, or nil. See Request.apply_compaction/2 to
continue from it.
Returns every fallback block, in content order ([] when the request was not
retried on a fallback model). One block marks each handoff between models.
Converts a raw API response map into a structured Response.
Aggregates every citation across all text blocks, in document order.
Extracts all MCP tool use requests from the response.
Extracts MCP tool use requests from the response for a specific server.
Returns server-tool result blocks in content order: web_search_tool_result,
web_fetch_tool_result, code_execution_tool_result, bash_code_execution_tool_result,
text_editor_code_execution_tool_result, tool_search_tool_result, advisor_tool_result
and container_upload. content is the raw nested value.
Returns the server-tool result blocks of one type (e.g. :code_execution_tool_result).
Extracts all server-side tool use requests (server_tool_use) from the
response — e.g. web_search / web_fetch invocations Claude ran on the
server. The matching results are web_search_tool_result blocks.
Extracts all text content from the response.
Returns the non-empty thinking texts, in content order.
Extracts the tool use requests to execute. After a server-side fallback, tool_use
blocks before the last fallback block came from the model that declined; they are
skipped here, as to_assistant_content/1 drops them from the replay.
Returns the model that produced the returned message: the last fallback block's
to.model, else model.
True when block is a thinking block holding the API's placeholder for an
update that was cut off: "This part of the response was interrupted before it finished.".
Converts the response content into API-shaped assistant content blocks for replaying as the assistant turn in a follow-up request
Types
A compaction summary (Request.add_compaction/2 threshold compaction, or
Request.request_compaction/2 on demand). content is the summary text (nil when
compaction failed). raw is the block as received — including signature for on-demand
blocks — and is what to_assistant_content/1 replays.
@type content_block() :: text_block() | thinking_block() | redacted_thinking_block() | tool_use_block() | tool_result_block() | mcp_tool_use_block() | mcp_tool_result_block() | server_tool_use_block() | web_search_tool_result_block() | fallback_block() | compaction_block() | server_tool_result_block() | container_upload_block()
@type fallback_block() :: %{ type: :fallback, from: map() | nil, to: map() | nil, trigger: map() | nil, raw: map() }
A server-side fallback handoff (Request.set_fallbacks/2). raw is the block as
received; Response.to_assistant_content/1 re-emits it unchanged.
@type redacted_thinking_block() :: %{type: :redacted_thinking, data: String.t()}
@type server_tool_result_block() :: %{ type: atom(), tool_use_id: String.t(), content: term(), caller: map() | nil, raw: map() }
A server-tool result other than web search (web_fetch_tool_result,
code_execution_tool_result, bash_code_execution_tool_result,
text_editor_code_execution_tool_result, tool_search_tool_result,
advisor_tool_result). content is the raw nested value (its variants and error codes
change over time); raw is the block as received and is what
to_assistant_content/1 replays.
@type stop_reason() ::
:end_turn
| :max_tokens
| :stop_sequence
| :tool_use
| :pause_turn
| :refusal
| :model_context_window_exceeded
| :compaction
@type t() :: %Claudio.Messages.Response{ container: map() | nil, content: [content_block()], context_management: map() | nil, diagnostics: map() | nil, id: String.t(), input_transformations: [map()] | nil, model: String.t(), role: String.t(), stop_details: map() | nil, stop_reason: stop_reason() | nil, stop_sequence: String.t() | nil, type: String.t(), usage: usage() }
@type usage() :: %{ optional(atom() | String.t()) => term(), input_tokens: integer(), output_tokens: integer(), cache_creation_input_tokens: integer() | nil, cache_read_input_tokens: integer() | nil, output_tokens_details: map() | nil, cache_creation: map() | nil, service_tier: String.t() | nil, inference_geo: String.t() | nil, speed: String.t() | nil, iterations: [map()] | nil }
Token usage. Documented fields are atom keys (nil when the API did not send
them); any other field the API returns is kept under the key it arrived with.
A usage map missing input_tokens or output_tokens is returned as received.
iterations (present when fallbacks was set) lists each attempt as the raw
API map: "type" => "message" for a model that declined, "fallback_message"
for the one that served; the top-level counts cover only the returned attempt.
With compaction, iterations also holds "type" => "compaction" entries; the top-level
counts exclude them (the billed total is the sum over iterations).
Functions
@spec compaction_block(t()) :: compaction_block() | nil
Returns the last compaction block, or nil. See Request.apply_compaction/2 to
continue from it.
@spec fallbacks(t()) :: [fallback_block()]
Returns every fallback block, in content order ([] when the request was not
retried on a fallback model). One block marks each handoff between models.
Converts a raw API response map into a structured Response.
Aggregates every citation across all text blocks, in document order.
Each entry is the raw citation map as returned by the API (e.g.
char_location, page_location, content_block_location,
search_result_location, web_search_result_location). Returns [] when no
citations are present.
@spec get_mcp_tool_uses(t()) :: [mcp_tool_use_block()]
Extracts all MCP tool use requests from the response.
@spec get_mcp_tool_uses(t(), String.t()) :: [mcp_tool_use_block()]
Extracts MCP tool use requests from the response for a specific server.
Returns server-tool result blocks in content order: web_search_tool_result,
web_fetch_tool_result, code_execution_tool_result, bash_code_execution_tool_result,
text_editor_code_execution_tool_result, tool_search_tool_result, advisor_tool_result
and container_upload. content is the raw nested value.
Returns the server-tool result blocks of one type (e.g. :code_execution_tool_result).
@spec get_server_tool_uses(t()) :: [server_tool_use_block()]
Extracts all server-side tool use requests (server_tool_use) from the
response — e.g. web_search / web_fetch invocations Claude ran on the
server. The matching results are web_search_tool_result blocks.
Extracts all text content from the response.
Also accepts the legacy string-keyed map returned by Claudio.Messages.create_message/2.
Returns the non-empty thinking texts, in content order.
A list, not a joined string: with display: :updates each thinking block is a
separate progress note. Empty texts (display: :omitted) and redacted_thinking
blocks are skipped. An interrupted update's placeholder text is kept — filter it
with thinking_interrupted?/1.
@spec get_tool_uses(t()) :: [tool_use_block()]
Extracts the tool use requests to execute. After a server-side fallback, tool_use
blocks before the last fallback block came from the model that declined; they are
skipped here, as to_assistant_content/1 drops them from the replay.
Returns the model that produced the returned message: the last fallback block's
to.model, else model.
Not simply model: a streamed response that fell back mid-output keeps the
requested (declining) model from message_start in model. When every model in
the chain declined (stop_reason: :refusal), it names the model whose refusal was
returned.
@spec thinking_interrupted?(content_block()) :: boolean()
True when block is a thinking block holding the API's placeholder for an
update that was cut off: "This part of the response was interrupted before it finished.".
Converts the response content into API-shaped assistant content blocks for replaying as the assistant turn in a follow-up request:
request
|> Request.add_message(:assistant, Response.to_assistant_content(response))Emits string-keyed blocks that preserve signature (thinking) and data
(redacted_thinking) — both required by the API when continuing an
extended-thinking + tool-use conversation. Unknown block types are passed
through unchanged (coverage grows in later specs).
After a server-side fallback (Request.set_fallbacks/2) it applies the API's
continuation rules: before the last fallback block it drops thinking,
redacted_thinking, connector_text and tool_use blocks, and keeps a
server_tool_use or mcp_tool_use only when its result block is present.
fallback blocks stay where they are. In practice this only changes a streamed
response that fell back mid-output; a non-streaming response normally puts the
fallback block first. response.content still holds every block.
If you edit earlier messages before replaying, a thinking block's signature may no longer
match; see Request.set_thinking_block_binding/2.