Skip to content

LLM Responses and Streams

For the integration flow, read LLM-Related Protocols. For the input side, use LLM Requests.

Response forms

Response is the host-facing envelope. Its llm_response is either LlmResponse::Agg, containing an AggLlmResponse, or LlmResponse::Stream, containing a live LlmResponseStream. The stream has one consumer.

Protocol field and type Meaning Anthropic Messages OpenAI Responses Chat Completions
AggLlmResponse.id: Option<String> Provider response identifier, if available. id id id
AggLlmResponse.model: Option<String> Provider-reported model name. model model model
AggLlmResponse.outputs: Vec<ResponseOutput> Completed output items. Assistant content blocks Items in output choices[].message
ResponseOutput.content: Vec<ContentBlock> Ordered text, reasoning, tool, and other output content. text, thinking, tool_use, and other blocks Message content, reasoning, function calls, and other items Message content, tool_calls, and provider-specific reasoning fields
ResponseOutput.stop_reason: Option<StopReason> Why this output stopped. stop_reason Response status and incomplete_details choices[].finish_reason
ResponseOutput.url_citations: Vec<UrlCitation> Cited URLs with text offsets. Not normalized by the current codec output_text.annotations Message annotations when supplied
AggLlmResponse.usage: Usage Normalized usage counts and any provider-reported cost. usage usage usage
AggLlmResponse.extensions: ProviderExtensions Provider-only response fields. Source fields retained by the codec Source fields retained by the codec Source fields retained by the codec
AggLlmResponse.preservation: PreservationMetadata Original JSON for same-format buffered replay. Original parsed body Original parsed body Original parsed body

The envelope also carries Response.metadata and Response.upstream_headers. Response.served_model() reads the Switchyard target recorded in metadata. Response.selected_model() reads the provider model from a buffered result and returns no model for a live stream, since inspecting its events would consume it.

Usage

Usage.input_tokens counts non-cached input. When an OpenAI-style provider reports aggregate input counts, the codecs subtract reported cache-read and cache-write counts. The cache details remain separate.

Protocol field and type Meaning Anthropic Messages OpenAI Responses Chat Completions
Usage.input_tokens: Option<u64> Non-cached input tokens. input_tokens input_tokens minus reported cache detail prompt_tokens minus reported cache detail
InputCacheUsage.cached_input_tokens: Option<u64> Input read from cache. cache_read_input_tokens Input token details, when reported Prompt token details, when reported
InputCacheUsage.cache_creation_input_tokens: Option<u64> Input written to cache. cache_creation_input_tokens Input token details, when reported Prompt token details, when reported
Usage.output_tokens: Option<u64> Output tokens, including reasoning when counted by the provider. output_tokens output_tokens completion_tokens
Usage.reasoning_tokens: Option<u64> Reasoning output reported separately. Provider token details, when reported output_tokens_details.reasoning_tokens Completion token details, when reported
Usage.total_tokens: Option<u64> Provider-reported or codec-computed total. Computed when needed total_tokens or computed total total_tokens or computed total
Usage.provider_cost: Option<f64> Provider-reported monetary charge in USD. Only when reported Only when reported Only when reported

Missing counts remain unknown. Do not turn an absent count into a measured zero when adapting a response. Usage.cache holds optional InputCacheUsage details.

Stream events

Each item of LlmResponseStream is a result containing LlmResponseStreamEvent. An event contains zero or more neutral LlmResponseChunk values and may retain one parsed provider event for same-format replay.

Protocol variant Meaning Anthropic Messages OpenAI Responses Chat Completions
LlmResponseChunk::MessageStart Establish or update response identity. message_start Response creation/start events Initial model and response fields
LlmResponseChunk::TextDelta Append text at an output index. Text content_block_delta Output text delta events choices[].delta.content
LlmResponseChunk::ReasoningDelta Append reasoning text. Thinking deltas Reasoning summary deltas Provider-specific reasoning deltas
LlmResponseChunk::ReasoningDetailsDelta Retain structured or encrypted reasoning detail. Reasoning signatures and related detail Encrypted reasoning items Provider-specific structured reasoning fields
LlmResponseChunk::ToolCallDelta Build a tool call's ID, name, and argument string. Tool start and input JSON deltas Function-call item and argument events Tool-call deltas
LlmResponseChunk::Usage Update available token counts. Message usage and deltas Usage on response events Usage chunks
LlmResponseChunk::MessageStop End the message. Message stop events Response completion events Finish reasons and terminal framing
LlmResponseChunk::DecodeError / LlmResponseChunk::StreamError Report decoding or in-band upstream failure. Codec/upstream error events Codec/upstream error events Codec/upstream error events

These are semantic mappings. One provider event can produce several chunks, and some events have no normalized chunks. Raw replay can still retain those events. Algorithms read neutral chunks through normalized().

Stream lifetime and preservation

Pass original LlmResponseStreamEvent values through when exact same-format parsed-JSON replay matters. replace_normalized() returns an event with the new chunks and clears its stale raw replay data.

LlmResponse::into_agg().await consumes the stream and folds its normalized chunks into an AggLlmResponse. Stream item failures, decode failures, and in-band upstream errors become errors. Aggregation does not preserve the original provider event sequence, MCP activity, unknown blocks, or all response extensions. The current accumulator also folds output indices into one assistant output.

Dropping a stream stops local consumption. It cannot guarantee that the provider stops generation or billing. See concurrency and cancellation for host-owned work, and Translation for decoding, encoding, and finishing provider streams.