-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Description
This issue originates from #1996 (comment)
There are two concrete issues:
remove_all_toolsconflicts with server-managed conversation (usingprevious_response_idorconversation_id).- “Nest handoff history by default” (Nest handoff history by default #1996) also conflicts with server-managed conversation.
The root cause is that any internal modification of chat history makes it inconsistent with the server-managed conversation, leading to unexpected behavior or errors.
Debug information
- Agents SDK version: v0.6.1
- Python version: 3.10
Repro steps for remove_all_tools
from agents import Agent, handoff, Runner, function_tool
from agents.extensions import handoff_filters
from openai import AsyncOpenAI
async def main():
client = AsyncOpenAI()
conversation = await client.conversations.create()
conv_id = conversation.id
refund_agent = Agent(name="Refund agent")
triage_agent = Agent(
name="Triage agent",
handoffs=[handoff(refund_agent, input_filter=handoff_filters.remove_all_tools)]
)
result = await Runner.run(
triage_agent,
"please transfer to refund.",
conversation_id=conv_id
)
print(f"{result.last_agent.name}: {result.final_output}")
import asyncio
if __name__ == "__main__":
asyncio.run(main())This results in the following error:
openai.BadRequestError: Error code: 400 - {
'error': {
'message': 'No tool output found for function call call_Vqk7s2LCkloV0vViUrIKnV4V.',
'type': 'invalid_request_error',
'param': 'input',
'code': None
}
}
The cause is that remove_all_tools removes the tool-output message, but the server-side conversation history is not modified. This mismatch causes the API error.
Using previous_response_id produces the same error.
Repro steps for “Nest handoff history”
from agents import Agent, handoff, Runner, function_tool
from openai import AsyncOpenAI
async def main():
client = AsyncOpenAI()
conversation = await client.conversations.create()
conv_id = conversation.id
refund_agent = Agent(name="Refund agent")
triage_agent = Agent(
name="Triage agent",
handoffs=[handoff(refund_agent)]
)
result = await Runner.run(
triage_agent,
"please transfer to refund.",
conversation_id=conv_id
)
print(f"{result.last_agent.name}: {result.final_output}")
import asyncio
if __name__ == "__main__":
asyncio.run(main())This does not produce an API error. However, the result is incorrect.
The intention of “Nest handoff history” is to clear the previous conversation, but when server-managed conversation is enabled, the conversation history is never actually cleared.
Attached logs:
- When Nest handoff history is used without
conversation_id(correct behavior)
- When Nest handoff history is used together with
conversation_id(incorrect: previous messages remain and no<CONVERSATION HISTORY>on the server-side)
Expected behavior
There are a few possible approaches:
1. Allow it: support Nest handoff history and remove_all_tools with server-managed conversation
But since the OpenAI API does not support modifying the server-side conversation, the SDK has limited options.
The SDK may detect this situation and automatically reset previous_response_id to None and start a new conversation_id. This might work, but I feel it's not transparent to developers. This needs further study on feasibility or API design.
2. or Disallow it
Add warnings (or raise an error) when the user attempts this combination.
Documentation should clearly state: If using server-managed conversations, avoid remove_all_tools and Set nest_handoff_history=False
3. Consider turning off Nest handoff history by default
Using nest_handoff_history=False avoids this issue because it does not modify the chat history.

