mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
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:
committed by
GitHub
Unverified
parent
f74bda5a83
commit
2aaca50217
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user