Skip to content

Conversation

ihower
Copy link
Contributor

@ihower ihower commented Sep 28, 2025

This PR fixes incorrect behavior when using conversation_id or previous_response_id during internal multi-turn calls, i.e. when function calling is involved.

It provides better support for the OpenAI Conversation state feature, as described in the https://platform.openai.com/docs/guides/conversation-state?api-mode=responses, aligning with the intended API design.

Resolved: #1789

Problem

  • When using conversation_id, the runner resent all items on every turn, which caused server-side duplicate item error.
  • When using previous_response_id, the SDK also resent all items and the previous_response_id was not updated across internal loops. This led to duplicated items and wasted bandwidth, even though it did not trigger errors currently. On the OpenAI platform dashboard logs, this can be observed as the responses repeatedly forking (based on the initially provided previous_response_id) instead of properly chaining.

Minimal repro code:

from agents import Agent, function_tool, Runner
from openai import OpenAI
client = OpenAI()

conversation = client.conversations.create()
conv_id = conversation.id

@function_tool
async def foobar() -> str:
    return "41"

agent = Agent(
    name="Assistant",
    instructions="just call foobar and answer me only the number",
    model="gpt-4.1-mini",
    tools=[foobar]
)

Runner.run_sync(agent, "hi", conversation_id=conv_id)

This produces the following error:

openai.BadRequestError: Error code: 400 - {'error': {'message': 'Duplicate item found with id fc_68d281ab76108195ac719f9b7c48eac103032f3a88a761f2. Remove duplicate items from your input and try again.', 'type': 'invalid_request_error', 'param': 'input', 'code': None}}

Solution

  • Added a _ServerConversationTracker to track items that should not be sent:
    • conversation_id: only send new items on each turn.
    • previous_response_id: only send new items and update previous_response_id to the latest server response.
  • Added tests to cover six scenarios:
    • conversation_id
      • non-streaming: test_conversation_id_only_sends_new_items_multi_turn
      • streaming: test_conversation_id_only_sends_new_items_multi_turn_streamed
    • previous_response_id
      • non-streaming: test_previous_response_id_only_sends_new_items_multi_turn
      • streaming: test_previous_response_id_only_sends_new_items_multi_turn_streamed
    • default (no conversation_id or previous_response_id)
      • non-streaming: test_default_send_all_items
      • streaming: test_default_send_all_items_streamed
  • Updated an existing test that checks the previous_response_id of the last model response.
    • Since behavior has changed to update previous_response_id on each turn, the assertion was modified accordingly.
  • Updated documentation to clarify how to use conversation_id and previous_response_id with server-managed conversations.
  • Unlike session memory e.g. OpenAIConversationsSession, which does not support passing lists of items containing images or files by default, this approach works out of the box and fully supports such items between turns.

@ihower ihower force-pushed the fix-openai-conversation branch from c4e8691 to e7a5e25 Compare September 28, 2025 15:59
@ihower ihower force-pushed the fix-openai-conversation branch from 4e2ae56 to 79aac01 Compare September 28, 2025 17:19
@seratch seratch added bug Something isn't working feature:core labels Sep 30, 2025
@seratch
Copy link
Member

seratch commented Sep 30, 2025

Thanks for sending this. Overall, this looks great! I have a few other things on my plate right now, but I will look into details shortly.

@seratch seratch changed the title Fix multi-turn handling for conversation_id and previous_response_id: only send new items fix: #1789 Fix multi-turn handling for conversation_id and previous_response_id: only send new items Sep 30, 2025
Copy link
Member

@seratch seratch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great to me

@seratch seratch merged commit d86886c into openai:main Oct 1, 2025
5 checks passed
seratch added a commit to openai/openai-agents-js that referenced this pull request Oct 1, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working feature:core
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Duplicate item found with id fc_xxxx when using conversation_id with function calling
2 participants