Skip to content

fix(bedrock): deliver streaming chunks individually instead of in batches#2950

Open
chaynabors wants to merge 1 commit into
strands-agents:mainfrom
chaynabors:agent-tasks/1523-bedrock-stream-chunks
Open

fix(bedrock): deliver streaming chunks individually instead of in batches#2950
chaynabors wants to merge 1 commit into
strands-agents:mainfrom
chaynabors:agent-tasks/1523-bedrock-stream-chunks

Conversation

@chaynabors

Copy link
Copy Markdown
Member

Supersedes #1759 with a clean rebase on current main after the monorepo restructure.

When Bedrock delivers a burst of chunks in a single TCP segment, call_soon_threadsafe schedules every put_nowait on the same event-loop tick, so the queue accumulates all chunks before any consumer await runs and the stream feels batched. Switching the producer callback to run_coroutine_threadsafe with a maxsize=1 queue forces real backpressure between the boto3 worker thread and the asyncio consumer, so each chunk is delivered before the next is enqueued. The pattern matches what mcp_client.py already does and the regression test asserts queue depth stays at zero after every consumer get.

Refs #1759, fixes #1523. Original commit by @shivaber, carried forward to the strands-py/ layout.

…ches

Replace call_soon_threadsafe(queue.put_nowait) with
run_coroutine_threadsafe(queue.put()).result() and use a bounded queue
(maxsize=1). This blocks the producer thread until each event is
delivered to the event loop, preventing callback batching where all
chunks were processed in a single event loop iteration.

Previously, when Bedrock sent chunks in a burst (e.g., multiple chunks
in one TCP segment), call_soon_threadsafe scheduled all put_nowait
callbacks at once. The event loop processed them all before the
queue.get() waiter ran, causing queue depths of 5-6 items and
delivering all chunks simultaneously to the consumer.

With the fix, queue depth is always 0 after each get(), ensuring
chunks are yielded one at a time for proper real-time streaming.

Closes strands-agents#1523
@github-actions github-actions Bot added area-model Related to models or model providers area-async Related to asynchronous flows or multi-threading bug Something isn't working python Pull requests that update python code labels Jun 24, 2026
@codecov

codecov Bot commented Jun 24, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-async Related to asynchronous flows or multi-threading area-model Related to models or model providers bug Something isn't working python Pull requests that update python code size/s

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] BedrockModel streaming delivers chunks in batches sometimes instead of individual stream events

2 participants