crewAIInc / crewAIInc/crewAI

[BUG] Bedrock streaming drops native tool calls, so the tool never runs

Open
#7,438 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
58.8k
Forks
8.5k
Avg merge
1d 15h
Merged PRs (30d)
109

Description

Description

With a Bedrock model and streaming on (LLM(..., stream=True), or Crew(stream=True)), native tool calls are dropped. The tool never runs, and the task's answer becomes "I apologize, but I couldn't generate a response. Please try again." No error is raised.

The agent executor calls the LLM with available_functions=None and runs the returned tool calls itself. _handle_converse returns the tool uses in that case, but _handle_streaming_converse and _ahandle_streaming_converse only use a tool call when available_functions is set, then throw it away. The stream has no text, so the empty-content fallback string is returned as the final answer.

Steps to Reproduce
  1. Create an agent with a Bedrock LLM (stream=True) and one tool.
  2. Mock converse_stream to return a toolUse block, then a text answer on the next call.
  3. Kick off a crew with one task for that agent.
Expected behavior

Same as stream=False: the tool runs and the crew returns the model's answer.

Screenshots/Code snippets
stream=False tool ran with=['Paris'] final answer='It is sunny in Paris.'
stream=True  tool ran with=[]        final answer="I apologize, but I couldn't generate a response. Please try again."

The Converse stream events are the same shape as _make_tool_use_stream() in tests/llms/bedrock/test_bedrock_streaming_tool_args.py.

Operating System

macOS

Python Version

3.12

crewAI Version

1.15.21 (main at 894898f)

crewAI Tools Version

not used

Virtual Environment

uv venv

Evidence

Non-streaming returns the calls at bedrock/completion.py:741-752. The streaming handlers only use them under if available_functions: (sync at 1096, async at 1707), and the executor always passes available_functions=None (experimental/agent_executor.py:1567). #6150 fixed the streamed arguments, but its tests always pass available_functions, so this path isn't covered.

Possible Solution

When available_functions is empty, collect the parsed tool uses in the streaming handlers and return them after the stream ends, the way the non-streaming path does. I have a fix with tests and will open a PR.

Additional context

This issue was written with AI assistance (Claude Code). I can't add the llm-generated label as an outside contributor; could a maintainer add it?

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in bedrock/completion.py at the streaming handlers around lines 1096 and 1707, then compare their behavior with the non-streaming path at lines 741-752 and the executor call in experimental/agent_executor.py:1567. Use the Converse stream shape from tests/llms/bedrock/test_bedrock_streaming_tool_args.py and verify both sync and async streaming return tool uses when available_functions is None, then confirm the tool runs and the final answer matches the non-streaming case.

Written by the indexing model from the issue text.

Assessment

Tech stack
aws, python
Domain
ai, backend-api-design, testing-qa
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.