Python: Exclude conversation_id from chat completions API options (#4517)

* Python: Exclude conversation_id from chat completions options (#4315)

When a session with service_session_id is passed to an agent using the
Chat Completions client, conversation_id leaked through _prepare_options()
into AsyncCompletions.create(), causing an 'unexpected keyword argument'
error. The Responses client already excluded conversation_id but the Chat
Completions client did not.

Added conversation_id to the exclusion set in _prepare_options().

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Apply pre-commit auto-fixes

* Remove reproduction report artifact

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Evan Mattson
2026-03-10 02:03:50 +09:00
committed by GitHub
Unverified
parent f74bda5a83
commit 2aaca50217
3 changed files with 85 additions and 1 deletions
@@ -327,7 +327,9 @@ class RawOpenAIChatClient( # type: ignore[misc]
messages = prepend_instructions_to_messages(list(messages), instructions, role="system")
# Start with a copy of options
run_options = {k: v for k, v in options.items() if v is not None and k not in {"instructions", "tools"}}
run_options = {
k: v for k, v in options.items() if v is not None and k not in {"instructions", "tools", "conversation_id"}
}
# messages
if messages and "messages" not in run_options:
@@ -626,6 +626,73 @@ async def test_streaming_with_none_delta(
assert any(msg.contents for msg in results)
@patch.object(AsyncChatCompletions, "create", new_callable=AsyncMock)
async def test_cmc_with_conversation_id(
mock_create: AsyncMock,
azure_openai_unit_test_env: dict[str, str],
chat_history: list[Message],
mock_chat_completion_response: ChatCompletion,
) -> None:
"""Test that conversation_id is excluded from the completions create call."""
mock_create.return_value = mock_chat_completion_response
chat_history.append(Message(text="hello world", role="user"))
azure_chat_client = AzureOpenAIChatClient()
await azure_chat_client.get_response(
messages=chat_history,
options={"conversation_id": "12345"},
)
call_kwargs = mock_create.call_args.kwargs
assert "conversation_id" not in call_kwargs
@patch.object(AsyncChatCompletions, "create", new_callable=AsyncMock)
async def test_cmc_streaming_with_conversation_id(
mock_create: AsyncMock,
azure_openai_unit_test_env: dict[str, str],
chat_history: list[Message],
mock_streaming_chat_completion_response: AsyncStream[ChatCompletionChunk],
) -> None:
"""Test that conversation_id is excluded from the streaming completions create call."""
mock_create.return_value = mock_streaming_chat_completion_response
chat_history.append(Message(text="hello world", role="user"))
azure_chat_client = AzureOpenAIChatClient()
async for _ in azure_chat_client.get_response(
messages=chat_history,
options={"conversation_id": "12345"},
stream=True,
):
pass
call_kwargs = mock_create.call_args.kwargs
assert "conversation_id" not in call_kwargs
@patch.object(AsyncChatCompletions, "create", new_callable=AsyncMock)
async def test_cmc_agent_with_service_session_id(
mock_create: AsyncMock,
azure_openai_unit_test_env: dict[str, str],
mock_chat_completion_response: ChatCompletion,
) -> None:
"""Test that agent.run() with a session containing service_session_id works correctly."""
mock_create.return_value = mock_chat_completion_response
azure_chat_client = AzureOpenAIChatClient()
agent = azure_chat_client.as_agent(
name="TestAgent",
instructions="You are a helpful assistant.",
)
session = agent.get_session(service_session_id="12345")
response = await agent.run("hello", session=session)
assert response is not None
call_kwargs = mock_create.call_args.kwargs
assert "conversation_id" not in call_kwargs
@tool(approval_mode="never_require")
def get_story_text() -> str:
"""Returns a story about Emily and David."""
@@ -1161,6 +1161,21 @@ def test_prepare_options_removes_parallel_tool_calls_when_no_tools(openai_unit_t
assert "parallel_tool_calls" not in prepared_options
def test_prepare_options_excludes_conversation_id(openai_unit_test_env: dict[str, str]) -> None:
"""Test that conversation_id is excluded from prepared options for chat completions."""
client = OpenAIChatClient()
messages = [Message(role="user", text="test")]
options = {"conversation_id": "12345", "temperature": 0.7}
prepared_options = client._prepare_options(messages, options)
# conversation_id is not a valid parameter for AsyncCompletions.create()
assert "conversation_id" not in prepared_options
# Other options should still be present
assert prepared_options["temperature"] == 0.7
async def test_streaming_exception_handling(openai_unit_test_env: dict[str, str]) -> None:
"""Test that streaming errors are properly handled."""
client = OpenAIChatClient()