On this page
- Visible answer text is the user-facing response
- “Reasoning” can mean several different things
- Hidden internal reasoning
- Visible reasoning summary
- Reasoning metadata/state
- Reasoning effort/budget
- Streaming order can be interleaved
- Do not render opaque continuation state
- Separate buffers simplify the renderer
- Reasoning Markdown can be streamed too
- Reasoning may finish before answer text starts
- TTFT should specify what “token” means
- Reasoning streams can create long silent periods
- Provider-native event order can matter for continuation
- Do not expose hidden chain-of-thought accidentally
- Reasoning summary and final answer can disagree
- Cancellation should preserve channel identity
- Regeneration should not duplicate stale reasoning state blindly
- Editing prior turns invalidates provider reasoning state
- Reasoning and tools can interleave
- UI should reflect semantics, not wire events
- Persistence can be layered
- Portable conversation data
- Provider execution metadata
- Do not send reasoning summary to another provider automatically
- Usage accounting can include reasoning separately
- Rendering strategy
- Tests to include
- Where BYOKchat fits
- Further reading
Reasoning-capable models can emit more than one kind of output while a response is in progress.
A stream may contain:
reasoning summary events
visible answer text
provider-native reasoning state
tool-call events
usage/completion metadata
If a client treats all of those as one append-only string, it can accidentally expose hidden state, corrupt the final answer, or make future continuation impossible.
The key rule is:
Reasoning is a separate semantic channel. Preserve provider-defined boundaries instead of flattening every streamed delta into assistant text.
Visible answer text is the user-facing response
The simplest stream contains only:
text delta
text delta
text delta
completed
The client can append those deltas into one visible answer buffer.
Reasoning models complicate this because the provider may also expose:
- a user-visible reasoning summary;
- structured reasoning items;
- encrypted continuation data;
- no reasoning content at all;
- provider-specific lifecycle events around reasoning.
These are not interchangeable.
“Reasoning” can mean several different things
Separate at least four concepts.
Hidden internal reasoning
The model’s internal computation that is not returned to the client.
Visible reasoning summary
A provider-generated summary intended to be shown to the user.
Reasoning metadata/state
Opaque or structured provider state used to continue the response correctly.
Reasoning effort/budget
A request control that influences how much reasoning the model may perform.
A client should not assume one implies another.
See Reasoning Effort Explained.
Streaming order can be interleaved
A provider might emit a sequence like:
reasoning_summary_delta
reasoning_summary_delta
output_text_delta
output_text_delta
completed
Another provider might emit:
reasoning item start
reasoning item delta
reasoning item complete
text item start
text delta
text item complete
response complete
The adapter should preserve semantic event type and item identity.
Do not render opaque continuation state
Some reasoning workflows require provider-native state to be carried across turns.
That state can be:
- encrypted;
- opaque;
- binary/base64-like;
- tied to one provider;
- meaningless to users.
It belongs in provider metadata, not in the chat transcript.
Bad architecture:
reasoning blob → assistant message text
Better:
visible reasoning summary → optional reasoning UI
visible answer → assistant answer UI
opaque reasoning state → provider continuation metadata
Separate buffers simplify the renderer
A generation record can hold:
type ActiveGeneration = {
reasoningSummary: string;
answerText: string;
providerReasoningState?: unknown;
toolCalls: PendingToolCall[];
};
Then the UI can decide independently whether to:
- show reasoning summary expanded;
- collapse it;
- hide it entirely;
- stream it live;
- render the final answer below it.
Reasoning Markdown can be streamed too
If visible reasoning summaries contain Markdown, the same incremental-rendering problems apply as with answer text:
- incomplete code fences;
- half-written lists;
- unfinished emphasis markers;
- partial math;
- links still being typed.
Use a streaming-safe Markdown renderer or coalesced render buffer.
See How to Render Markdown While AI Is Still Streaming.
Reasoning may finish before answer text starts
This makes timing metrics more nuanced.
You can measure:
request start
first protocol event
first reasoning event
first visible answer token
response complete
For user-perceived latency, first visible answer may matter more than first reasoning event if reasoning is hidden.
For diagnostics, both are useful.
TTFT should specify what “token” means
If the provider emits hidden/reasoning events first, measuring “time to first stream event” can make the system look faster than the user experiences.
Track separately:
time to first byte/event
time to first reasoning content
time to first visible answer content
See Measuring Time to First Token Correctly.
Reasoning streams can create long silent periods
A model may reason internally for a long time before visible answer text appears.
If the provider does not expose reasoning progress, the client may receive no meaningful content during that phase.
Do not use an aggressive “no text for 10 seconds = dead stream” rule.
Timeout policies should distinguish:
no network activity
vs
network alive but no visible text
vs
known reasoning phase
Provider-native event order can matter for continuation
Some APIs require prior response items to be replayed in a particular order.
If reasoning items and answer items are flattened into one string, later continuation may lose required structure.
Store the neutral conversation representation and provider metadata needed to reconstruct native continuation.
See How to Preserve Reasoning Across AI Turns.
Do not expose hidden chain-of-thought accidentally
A provider may return metadata that looks text-like but is not intended as user-visible reasoning.
Client code should render only fields explicitly documented as displayable.
Avoid heuristics such as:
if field contains string → show in reasoning panel
Use provider capability/event definitions.
Reasoning summary and final answer can disagree
A reasoning summary is not necessarily a contract for the final answer.
The model can revise its conclusion during inference.
So do not build application logic that treats intermediate reasoning summary text as an authoritative decision before the final response completes.
For structured workflows, wait for the final structured/answer boundary.
Cancellation should preserve channel identity
If the user stops generation, you may have:
reasoning summary: complete/partial
answer text: partial/empty
Persist both with interrupted/cancelled state.
Do not merge the reasoning summary into the answer just because the answer buffer is empty.
Regeneration should not duplicate stale reasoning state blindly
If the user regenerates from the same prompt:
- visible reasoning summary from the previous attempt can remain historical UI;
- provider reasoning continuation state from the interrupted attempt may be invalid for the new attempt;
- a fresh generation should get its own provider state.
Treat each generation attempt as separate execution state.
Editing prior turns invalidates provider reasoning state
If the conversation before a stored reasoning continuation changes, provider-native reasoning state may no longer match the semantic context.
A safe rule is:
edit earlier history
→ invalidate continuation metadata after edit point
Then rebuild from portable history.
Reasoning and tools can interleave
A reasoning model may decide to call a tool before producing final answer text.
Sequence:
reasoning summary
→ tool call
→ tool result
→ more reasoning
→ final answer
The generation state machine should support this without assuming “reasoning is one pre-answer block.”
UI should reflect semantics, not wire events
Provider wire events may be very granular:
item_started
summary_part_added
summary_text_delta
summary_part_done
item_done
The UI usually needs a simpler model:
reasoning summary changed
answer changed
tool status changed
generation completed
Normalize inside the provider adapter or generation layer.
Persistence can be layered
A good architecture may store:
Portable conversation data
visible assistant answer
visible reasoning summary if product chooses to persist it
tool call/result semantics
Provider execution metadata
response IDs
opaque reasoning continuation state
native item IDs
finish metadata
This allows chat history to remain readable even if the provider disappears.
Do not send reasoning summary to another provider automatically
If a user switches providers mid-conversation, visible assistant answer text is usually portable.
Reasoning summary may or may not be desirable as context.
Opaque reasoning state is not portable.
A provider switch should deliberately decide:
answer text → portable
reasoning summary → optional semantic context
opaque reasoning → drop
See How to Switch AI Providers Mid-Conversation.
Usage accounting can include reasoning separately
Some providers/models account for reasoning-related tokens or expose usage categories that differ from visible output tokens.
Do not estimate cost or tokens from rendered answer length alone.
Use provider-reported usage when available and label categories accurately.
See Context Window vs Output Limit vs Reasoning Tokens.
Rendering strategy
A stable UI pipeline can be:
This makes accidental leakage much harder.
Tests to include
Test:
- reasoning summary only, no answer yet;
- answer starts after long reasoning delay;
- reasoning and answer events interleave;
- tool call appears between reasoning phases;
- cancellation during reasoning before answer;
- disconnect after reasoning but before answer;
- opaque reasoning state present;
- provider returns reasoning metadata with no display summary;
- provider switch after reasoning turn;
- edit prior message invalidates continuation;
- Markdown reasoning summary streams incomplete syntax;
- usage includes hidden/reasoning accounting.
Where BYOKchat fits
A multi-provider client benefits from one shared UI concept for reasoning while each provider adapter keeps native continuation mechanics private. Visible reasoning summaries can be rendered consistently, but opaque provider reasoning state stays attached only to the provider turn that needs it.
That keeps reasoning useful without turning provider internals into chat text.