-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Closed
Labels
questionQuestion about using the SDKQuestion about using the SDK
Description
Describe the bug
When using streaming with handoffs, the SDK emits both ToolCallItem
and HandoffCallItem
with the same call_id
for a single handoff. If frameworks persist both events (as they naturally would when processing the stream), this creates duplicate function_call
entries in conversation history, causing API errors on subsequent turns.
Debug information
- Agents SDK version: 0.3.3
- Python version: 3.13
Repro steps
"""
Minimal reproduction: SDK emits duplicate events for handoffs with same call_id
Run: export OPENAI_API_KEY=your_key && python repro_duplicate_handoff_events.py
"""
import asyncio
import os
from agents import Agent, Runner, set_tracing_disabled
if not os.getenv("OPENAI_API_KEY"):
exit("Set OPENAI_API_KEY")
set_tracing_disabled(disabled=True)
worker_agent = Agent(name="Worker", instructions="You are helpful.")
coordinator_agent = Agent(
name="Coordinator",
instructions="When asked to delegate, transfer to Worker.",
handoffs=[worker_agent],
)
async def main():
# Turn 1: Collect streaming events
persisted_history = []
result = Runner.run_streamed(coordinator_agent, "Transfer to worker")
async for event in result.stream_events():
if event.type == "run_item_stream_event":
persisted_history.append(event.item.to_input_item())
# Turn 2: Use persisted history (will fail with duplicate error)
persisted_history.append({"role": "user", "content": "What did I ask?"})
result2 = await Runner.run(coordinator_agent, persisted_history)
print(result2.final_output)
if __name__ == "__main__":
asyncio.run(main())
Output:
openai.BadRequestError: Error code: 400 - {'error': {'message': 'Duplicate item found with id fc_... Remove duplicate items from your input and try again.', 'type': 'invalid_request_error', 'param': 'input', 'code': None}}
Root cause: In agents/_run_impl.py:498-505
, both ToolCallItem
and HandoffCallItem
are appended for handoffs, sharing the same call_id
.
Expected behavior
Only one event should be emitted per handoff, OR the SDK should deduplicate when converting to input history. Currently, frameworks must implement workarounds to skip one of the events.
Metadata
Metadata
Assignees
Labels
questionQuestion about using the SDKQuestion about using the SDK