refactor(bedrock): block_index resolves, callers own the current-index state

The helper wrote current_block_index for every event and the stop branch
immediately undid it; make it a pure resolver and assign in the start/delta
branches only. The test's replay tail re-covered ordering the sidecar
assertion already pins — dropped.
This commit is contained in:
kshitijk4poor
2026-09-19 00:36:52 +05:30
committed by kshitij
parent 5d4a206c92
commit e5af917aaa
2 changed files with 6 additions and 17 deletions

View File

@@ -829,12 +829,10 @@ def stream_converse_with_callbacks(
def block_index(payload: Dict[str, Any], *, new_block: bool = False) -> int:
"""Index of the block a contentBlock* event addresses. Without ``contentBlockIndex`` (test doubles,
proxies) a start opens a fresh slot and a delta/stop continues the current one."""
nonlocal current_block_index
idx = payload.get("contentBlockIndex")
if not isinstance(idx, int):
idx = len(stream_blocks) if new_block or current_block_index is None else current_block_index
current_block_index = idx
return idx
if isinstance(idx, int):
return idx
return len(stream_blocks) if new_block or current_block_index is None else current_block_index
def flush_text() -> None:
if current_text_buffer:
@@ -849,7 +847,7 @@ def stream_converse_with_callbacks(
break
if "contentBlockStart" in event:
start_event = event["contentBlockStart"]
idx = block_index(start_event, new_block=True)
idx = current_block_index = block_index(start_event, new_block=True)
start = start_event.get("start", {})
if "toolUse" in start:
has_tool_use = True
@@ -860,7 +858,7 @@ def stream_converse_with_callbacks(
on_tool_start(current_tool["name"])
elif "contentBlockDelta" in event:
delta_event = event["contentBlockDelta"]
idx = block_index(delta_event)
idx = current_block_index = block_index(delta_event)
delta = delta_event.get("delta", {})
if "text" in delta:
text = delta["text"]

View File

@@ -508,7 +508,7 @@ class TestNormalizeConverseStreamEvents:
the text into one block per delta and let the toolUse start (index 1) overwrite the second fragment
and sort into the middle — a ``[text, toolUse, text...]`` sidecar Claude 5 on Bedrock rejects on
replay as "does not support assistant message prefill"."""
from agent.bedrock_adapter import convert_messages_to_converse, normalize_converse_stream_events
from agent.bedrock_adapter import normalize_converse_stream_events
result = normalize_converse_stream_events({"stream": list(self._LIVE_TEXT_THEN_TOOL_EVENTS)})
msg = result.choices[0].message
assert msg.content == "I'll echo banana now."
@@ -517,15 +517,6 @@ class TestNormalizeConverseStreamEvents:
{"toolUse": {"toolUseId": "tooluse_1", "name": "echo", "input": {"s": "banana"}}},
]
assert [tc.function.name for tc in msg.tool_calls] == ["echo"]
# The sidecar is authoritative on replay: the next turn must go out as text THEN toolUse, nothing after.
_, converse = convert_messages_to_converse([
{"role": "user", "content": "echo banana"},
{"role": "assistant", "content": msg.content, "bedrock_content_blocks": msg.bedrock_content_blocks,
"tool_calls": [{"id": "tooluse_1", "type": "function", "function": {"name": "echo", "arguments": '{"s": "banana"}'}}]},
{"role": "tool", "tool_call_id": "tooluse_1", "content": "banana"},
])
assert [list(b)[0] for b in converse[1]["content"]] == ["text", "toolUse"]
assert converse[1]["content"][0]["text"] == "I'll echo banana now."
def test_events_without_content_block_index_fall_back_to_arrival_order(self):
"""Proxies/test doubles may omit contentBlockIndex: deltas continue the current block, a start opens a