diff --git a/python/packages/core/agent_framework/openai/_chat_client.py b/python/packages/core/agent_framework/openai/_chat_client.py index 0214c8df20..0562e68f3e 100644 --- a/python/packages/core/agent_framework/openai/_chat_client.py +++ b/python/packages/core/agent_framework/openai/_chat_client.py @@ -327,7 +327,9 @@ def _prepare_options(self, messages: Sequence[Message], options: Mapping[str, An 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: diff --git a/python/packages/core/tests/azure/test_azure_chat_client.py b/python/packages/core/tests/azure/test_azure_chat_client.py index 3e88504493..b6809d097d 100644 --- a/python/packages/core/tests/azure/test_azure_chat_client.py +++ b/python/packages/core/tests/azure/test_azure_chat_client.py @@ -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.""" diff --git a/python/packages/core/tests/openai/test_openai_chat_client.py b/python/packages/core/tests/openai/test_openai_chat_client.py index 58faac42a3..04321b0883 100644 --- a/python/packages/core/tests/openai/test_openai_chat_client.py +++ b/python/packages/core/tests/openai/test_openai_chat_client.py @@ -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()