Skip to content

Python: [Bug]: HandoffBuilder store=False breaks FunctionInvocationLayer tool result submission #4376

@omargalal20

Description

@omargalal20

Description

What happened

When using HandoffBuilder with AzureOpenAIResponsesClient, the workflow crashes with openai.BadRequestError: Item with id 'rs_...' not found after a tool call completes and the framework tries to submit the tool result back to the model.
HandoffBuilder._clone_chat_agent() forces store=False (line 373 of _handoff.py). This is intentional — handoff workflows manage conversation state explicitly. However, the FunctionInvocationLayer's streaming tool loop (_tools.py, line 2280-2282) still captures response.conversation_id from the streaming response and passes it as previous_response_id on the next iteration (the tool result submission). Since store=False means the response was never persisted server-side, the API rejects the reference.

What I expected to happen

The tool invocation loop should respect store=False by not setting conversation_id/previous_response_id when store is disabled. When store=False, the loop should replay the full message history (including the tool call + tool result) instead of referencing a non-persisted response ID.

Steps to reproduce

  1. Create agents with AzureOpenAIResponsesClient and register tools on them
  2. Build a HandoffBuilder workflow with those agents
  3. Run the workflow with stream=True
  4. Send a message that triggers a tool call (e.g., verify_patient)
  5. After the tool executes, the framework crashes when submitting the tool result

Code Sample

from agent_framework import Agent, tool
from agent_framework.azure import AzureOpenAIResponsesClient
from agent_framework.orchestrations import HandoffBuilder
from azure.identity import AzureCliCredential

@tool(approval_mode="never_require")
def verify_patient(full_name: str, date_of_birth: str) -> dict:
    return {"verified": True, "patient_id": "P-12345"}

client = AzureOpenAIResponsesClient(
    project_endpoint="...",
    deployment_name="gpt-5.1-chat",
    credential=AzureCliCredential(),
)

agent_a = client.as_agent(name="agent_a", instructions="...", tools=[verify_patient])
agent_b = client.as_agent(name="agent_b", instructions="...")

builder = HandoffBuilder(name="demo", participants=[agent_a, agent_b])
builder.add_handoff(agent_a, [agent_b])
workflow = builder.with_start_agent(agent_a).build()

# Trigger a message that causes agent_a to call verify_patient
# → After tool executes, framework crashes on tool result submission
stream = workflow.run("Verify patient Omar, DOB 2000-09-14", stream=True)
async for event in stream:
    pass  # Crashes here

Error Messages / Stack Traces

openai.BadRequestError: Error code: 400 - {'error': {'message': "Item with id 'rs_...' not found. Items are not persisted when `store` is set to false.", ...}}


**Root cause in framework code:**
- `_handoff.py` line 373: forces `"store": False`
- `_tools.py` line 2280-2282 (streaming path): captures `response.conversation_id` and sets it via `_update_conversation_id`, which causes the next API call to include `previous_response_id` referencing a non-persisted response

Package Versions

agent-framework: 1.0.0rc2, agent-framework-azure-ai: 1.0.0rc2, agent-framework-orchestrations: 1.0.0b260225

Python Version

Python 3.12

Additional Context

This also affects the non-streaming path (_tools.py line 2146-2147). The _get_conversation_id method correctly returns None when store=False, but the FunctionInvocationLayer reads response.conversation_id directly from the ChatResponse object, bypassing the store check.

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingpythonv1.0Features being tracked for the version 1.0 GA

Type

Projects

Status

No status

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions