Skip to content

fix(streaming): handle tool use metadata in contentBlockDelta for non-standard models#2077

Open
Zelys-DFKH wants to merge 1 commit intostrands-agents:mainfrom
Zelys-DFKH:fix/streaming-tool-use-delta-metadata
Open

fix(streaming): handle tool use metadata in contentBlockDelta for non-standard models#2077
Zelys-DFKH wants to merge 1 commit intostrands-agents:mainfrom
Zelys-DFKH:fix/streaming-tool-use-delta-metadata

Conversation

@Zelys-DFKH
Copy link
Copy Markdown

Problem

When Kimi K2.5 (moonshotai.kimi-k2.5) is used via the Amazon Bedrock Converse streaming API, tool calls on the second cycle crash with a KeyError. The streaming parser in handle_content_block_delta only reads input from contentBlockDelta.delta.toolUse, ignoring toolUseId and name. When a model provides those fields in the delta rather than in contentBlockStart (a non-standard but valid variation), current_tool_use reaches handle_content_block_stop without toolUseId or name, causing a crash.

A secondary gap: if delta.toolUse has no input key, the direct dict access raises KeyError instead of treating it as an empty string.

Solution

In handle_content_block_delta, capture toolUseId and name from the delta when they are present and not already set from a prior contentBlockStart. Use .get("input", "") to handle deltas with no input key.

In handle_content_block_stop, replace the direct current_tool_use["toolUseId"] and current_tool_use["name"] accesses with .get() calls, and log a warning and skip the block if either field is still missing after processing all events.

Testing

  • Added test_handle_content_block_delta_captures_tool_use_id_and_name_from_delta: delta with all three fields populates current_tool_use correctly.
  • Added test_handle_content_block_delta_does_not_override_existing_tool_use_id_and_name: fields set by contentBlockStart are not overwritten by a later delta.
  • Added test_handle_content_block_delta_tool_use_without_input_key: delta missing input does not raise.
  • Added test_handle_content_block_stop_skips_incomplete_tool_use_missing_id / _missing_name: warning logged and block skipped when fields are absent.
  • Added test_process_stream_tool_use_info_in_delta: end-to-end check simulating a model that sends all tool use metadata in the delta.
  • All 111 existing event loop tests pass. Lint clean.

Fixes #1646

Documentation PR

N/A

Type of Change

Bug fix

Checklist

  • I have read the CONTRIBUTING document
  • I have added any necessary tests that prove my fix is effective or my feature works
  • I have updated the documentation accordingly
  • My changes generate no new warnings
  • Any dependent changes have been merged and published

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

…-standard models

Some Bedrock models (e.g., Kimi K2.5) send toolUseId and name in
contentBlockDelta rather than in contentBlockStart. The parser only
extracted input from the delta, leaving current_tool_use without those
fields and crashing in handle_content_block_stop.

- Capture toolUseId and name from delta when not already set by start
- Use .get("input", "") to avoid KeyError when input key is absent
- Add warning + skip for incomplete tool use blocks in stop handler

Fixes strands-agents#1646
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] KeyError: 'toolUse' in event_loop when using Kimi K2.5 via Bedrock

1 participant