A search round goes back with and without a local `tool_use` after its blocks: the endpoint takes both, and the model answers from the results it already holds. With the blocks stripped it calls its own earlier answer fabricated instead. The note sits where the ordering decision lives, so the shape needs no re-probe.
`provider_blocks` means something only to the surface that produced them (Anthropic `thinking` / server-tool blocks). A session that switched surface would otherwise send those dicts to a chat-completions provider as an assistant-message key it does not know; the request normalization drops the field, on a copy, so the history keeps it.
Streaming is the default path: `thinking` fragments, a `server_tool_use`'s `partial_json` query and a `web_search_tool_result`'s entries arrive as separate SSE events, so the blocks the round has to hand back exist only as fragments. The dispatch rebuilds each one from its start payload (field for field, under the stream's own names) plus the fragments that follow, and passes it to the loop as a chunk; the loop copies it onto the round's message, where a round that kept only those blocks counts as payload rather than an empty completion.
The thinking text streams as reasoning as it arrives — the search query and the signature go back with the round only.
DeepSeek's Anthropic compat answers a hosted search inside the turn: the response carries the `thinking` that picked the query, the `server_tool_use`, and the `web_search_tool_result`. The response mapping kept text and tool_use only, so the round lost its evidence — and the `thinking` signature, which only the provider can verify, could not go back at all. `AssistantChatMessage.provider_blocks` carries those blocks as raw JSON now (`thinking` text *and* signature, the query, the result entries with an `encrypted_content` the API rejects when trimmed) and the assistant turn hands them back first, ahead of its text and tool_use blocks; `thinking` also lands in `reasoning_content`, so the chain of thought streams as reasoning like every other surface's.
`AnthropicRawContentBlock` names the provider fields a streamed block carries, and `AnthropicServerToolUseContent` keeps the `caller` metadata the wire sends.
The ``responses_bridge`` bullet records that ``response.reasoning_text.done`` repeats the fragments: the loop streams each part once, and the round's message still carries the whole chain of thought back to the API.
DeepSeek's Responses stream sends ``response.reasoning_text.delta`` fragments and then ``response.reasoning_text.done`` carrying the whole chain of thought those fragments spelled out. The loop folded a full delta into the round — it replaces the fragments, and that is what the assistant message hands back to the API — but streamed every delta verbatim, so the chain of thought was printed twice: once as it arrived and again as the ``.done`` text.
A full delta now streams only a tail the fragments did not cover, and nothing at all when it merely repeats them; a round whose fragments never arrived still streams the full text once. The message keeps the complete text either way.