-
Notifications
You must be signed in to change notification settings - Fork 6.6k
Description
Bug Description
I believe this is a bug and unintended behavior, but if it is not, then please give guidance on how we should be utilizing AgentStream events from BedrockConverse!
Version(s) used:
llama-index-core==0.14.10, llama-index-llms-bedrock-converse==0.12.2
Behavior:
Currently, we're creating an instance of a BedrockConverse model with thinking enabled like so:
claude_4_sonnet = BedrockConverse(
model=f"{AWS_BEDROCK_GEO}.anthropic.claude-sonnet-4-20250514-v1:0",
region_name=AWS_REGION,
thinking={"type": "enabled", "budget_tokens": 1024},
)
We then use the model as part of the following FunctionAgent configuration:
constructor_kwargs = {
"llm": llm,
"tools": function_tools,
"system_prompt": AGENT_SYSTEM_PROMPT.format(agent_instructions=agent_request.system_prompt),
}
.
.
.
agent = FunctionAgent(**constructor_kwargs)
We then create a WorkflowHandler instance and pull stream_events() from the handler, which are AgentStream events:
handler = agent.run(
user_msg=make_user_message(agent_request.prompt),
ctx=ctx,
memory=memory,
system_prompt=AGENT_SYSTEM_PROMPT.format(agent_instructions=agent_request.system_prompt),
)
.
.
.
async for event in handler.stream_events():
# custom serializer
payload = _serialize_event(event, stream_event_types, thinking)
if not payload or payload.get("delta") == "":
continue
yield f"data: {json.dumps(payload, ensure_ascii=False)}\n\n"
At this point when we're handling the AgentStream events returned from the WorkflowHandler with thinking mode on, the events returned for the "thinking" phase of the AgentStream lack the delta and thinking_delta fields. Here's a view of the values of attributes present on the AgentStream event during the thinking phase:
event.raw:
{'contentBlockDelta': {'delta': {'reasoningContent': {'text': 'The user is asking'}}, 'contentBlockIndex': 0}}
event.delta:
""
event.thinking_delta:
None
As shown above, there is no event.thinking_delta that can be easily accessed. Instead, if I wanted to access the thinking content, we have to inspect the raw attribute and select down into the models per event like so:
thinking_content = event['raw']['delta']['reasoningContent']['text']
Contrast this with what is returned from the AgentOutput event when returned:
event.raw:
{'contentBlockDelta': {'delta': {'text': '-Week Performance'}, 'contentBlockIndex': 0}}
event.delta:
-Week Performance
event.thinking_delta:
None
Accessing thinking content from a nested dictionary is not intuitive and feels fragile, especially considering the thinking_delta field already exists, in addition to the delta field on the AgentStream events. We would expect either one of those fields to be present.
Version
llama-index-core==0.14.10, llama-index-llms-bedrock-converse==0.12.2
Steps to Reproduce
The Behavior section of the Bug Description section has information on our setup to reproduce the issue. A checklist is provided below:
- Create an instance of a
BedrockConversemodel with thinking enabled - Create an instance of a
FunctionAgentusing theBedrockConversemodel with thinking enabled - Call the
FunctionAgentwithagent.runto yield aWorkflowHandler - Stream the events from the
WorkflowHandlerwithhandler.stream_events() - Inspect the
AgentStreamevents from the thinking portion of the workflow and verifydeltanorthinking_deltaare populated
Relevant Logs/Tracbacks
Sample of data dump from AgentStream/AgentOutput events from WorkflowHandler
---
event.raw:
{'contentBlockDelta': {'delta': {'reasoningContent': {'text': "'t need to ask for"}}, 'contentBlockIndex': 0}}
event.delta:
event.thinking_delta:
None
---
event.raw:
{'contentBlockDelta': {'delta': {'reasoningContent': {'text': ' any missing'}}, 'contentBlockIndex': 0}}
event.delta:
event.thinking_delta:
None
---
event.raw:
{'contentBlockDelta': {'delta': {'reasoningContent': {'text': ' information.'}}, 'contentBlockIndex': 0}}
event.delta:
event.thinking_delta:
None
---
event.raw:
{'contentBlockDelta': {'delta': {'reasoningContent': {'signature': 'EoQFCkgIChABGAIqQEZN54U92o9LzJReFIQ7ySWGVnUthUxHCGHGKJLvxt4zSAoWZMzz2XY5BTk/MFNOXyHL0iTDPqmNdlwIsOF8xRUSDJHiRa3bM1FelTsTOxoMmP+F/d+fn0YLepEJIjD/EFGlR6PpCmNecbmb/I9+MLFQrUVLj0NQusO7FsrBJDDuHT+BAuIDoECJxRvrxk8q6QNqXF1YIgAc7g3LCdR+LlmQBYG7gEp3w1bRhop4XSlCilXLwJh5eiHOi+L7y4q05aKE8vc0zbj2u8M10TylwR2Dt8N5wPKNdOhT7f14uAQt9Z9hdZMF09l6XEFOZYlkFaZtCgG+0Ixo61BBMDvE+VwLrjGfu19cSxTLQ3xpbvkbNFTJZvT1imm+DLXn1TzYzh8pulH68fp/icVO6Z+ZhE9T+pXlVSups3pc7bs3BethT28kmK5nAFQcHwS5Nbx/9Y444rAfHsAPHEm+DOauzeTeR4oz6WHryyEjtggIdmAItm9Weg6Q+PUrGU7WoOuzyp64wHGSDaZWuT8O0nVGp/Wn+hisCljsVRzCM8ffxo55QheFJoAj118F/HqbLl7qPJCocPAQqCSXj7Bst0QoiptnE+S+zIk9jHBZBbP9sBrnZxjKCclNQMHUJWj4mgOcvzIWu83ww2irbjHm/GwR9MB3Orb5Lr/yreojJrjiaaRPda+zygMJ0Qk8vT0luABfShYZIaQ2sl66J9EPFga7UgqZ3nYRJCbvalrkFOGGVVXJO8o075t+qLPD1ulIynXCHVjof7AmhuO6ZTvvo87Gmv/wFbZwqeh7m08wUXZEaZHinN0zPu4Xocmw873qrEDTmAmsD3HIXiU2GCwYAQ=='}}, 'contentBlockIndex': 0}}
event.delta:
event.thinking_delta:
None
---
event.raw:
{'contentBlockDelta': {'delta': {'text': "I'll fetch the stock information for"}, 'contentBlockIndex': 1}}
event.delta:
I'll fetch the stock information for
event.thinking_delta:
None
---
event.raw:
{'contentBlockDelta': {'delta': {'text': ' AAPL,'}, 'contentBlockIndex': 1}}
event.delta:
AAPL,
event.thinking_delta:
None
---
event.raw:
{'contentBlockDelta': {'delta': {'text': ' TSLA, an'}, 'contentBlockIndex': 1}}
event.delta:
TSLA, an
event.thinking_delta:
None
---```