Fold a Token Stream
When you stream a response, the model sends the answer as a series of small events instead of one big payload, so you can show text as it is typed. The SDK gives you a clean iterator of text chunks, but underneath it is folding a stream of typed events: a message_start, then many content_block_delta events each carrying a tiny text_delta, with content_block_stop and message_stop markers around them. To rebuild the full answer you keep only the text deltas and concatenate them.
The friendly real version looks like this (illustrative only -> we do not call the network):
with client.messages.stream(model="claude-sonnet-4-6", max_tokens=1024,
messages=[{"role": "user", "content": "Hi"}]) as stream:
for text in stream.text_stream: # already just the text chunks
print(text, end="", flush=True)
final = stream.get_final_message()That text_stream is a convenience. Under it, the raw events look like the list below, and folding them is exactly the skill this lesson drills. We model the stream as a list of event dicts so it runs offline:
[
{"type": "message_start"},
{"type": "content_block_delta", "delta": {"type": "text_delta", "text": "He"}},
{"type": "content_block_delta", "delta": {"type": "text_delta", "text": "llo"}},
{"type": "content_block_stop"},
{"type": "message_stop"}
]You are building collect_stream(events). Walk the list and concatenate, in order, the text from every event that is a content_block_delta whose inner delta has type == "text_delta". Skip every other event -> the lifecycle markers (message_start, content_block_stop, message_stop) carry no text, and a non-text delta (such as an input_json_delta for a streamed tool call) is not part of the visible answer. An empty list returns "".
Build it so two different event lists rebuild two different strings, the lifecycle and non-text events are skipped, and an empty stream returns "".
Write collect_stream(events) where events is a list of streaming event dicts. Concatenate, in order, the text of every {"type": "content_block_delta", "delta": {"type": "text_delta", "text": ...}} event. Skip all other events (lifecycle markers like message_start/content_block_stop, and non-text deltas). Return "" for an empty stream.
This lesson is locked
Lessons open one at a time. Finish the previous lesson to unlock this one.