Python: fix middleware and cleanup confusing function (#1865)

* fix middleware and cleanup redundant function

* added test to validate
This commit is contained in:
Eduard van Valkenburg
2025-11-03 19:42:59 +01:00
committed by GitHub
Unverified
parent 0b843d2b3e
commit e462d209fd
13 changed files with 61 additions and 149 deletions
@@ -15,7 +15,6 @@ from agent_framework import (
ChatAgent,
ChatClientProtocol,
ChatMessage,
ChatOptions,
ChatResponse,
ChatResponseUpdate,
HostedCodeInterpreterTool,
@@ -155,18 +154,6 @@ def test_azure_assistants_client_init_with_default_headers(azure_openai_unit_tes
assert chat_client.client.default_headers[key] == value
def test_azure_assistants_client_instructions_sent_once(mock_async_azure_openai: MagicMock) -> None:
"""Ensure instructions are only included once for Azure OpenAI Assistants requests."""
chat_client = create_test_azure_assistants_client(mock_async_azure_openai)
instructions = "You are a helpful assistant."
chat_options = ChatOptions(instructions=instructions)
prepared_messages = chat_client.prepare_messages([ChatMessage(role="user", text="Hello")], chat_options)
run_options, _ = chat_client._prepare_options(prepared_messages, chat_options) # type: ignore[reportPrivateUsage]
assert run_options.get("instructions") == instructions
async def test_azure_assistants_client_get_assistant_id_or_create_existing_assistant(
mock_async_azure_openai: MagicMock,
) -> None:
@@ -23,7 +23,6 @@ from agent_framework import (
ChatAgent,
ChatClientProtocol,
ChatMessage,
ChatOptions,
ChatResponse,
ChatResponseUpdate,
TextContent,
@@ -84,18 +83,6 @@ def test_init_base_url(azure_openai_unit_test_env: dict[str, str]) -> None:
assert azure_chat_client.client.default_headers[key] == value
def test_azure_openai_chat_client_instructions_sent_once(azure_openai_unit_test_env: dict[str, str]) -> None:
"""Ensure instructions are only included once when preparing Azure OpenAI chat requests."""
client = AzureOpenAIChatClient()
instructions = "You are a helpful assistant."
chat_options = ChatOptions(instructions=instructions)
prepared_messages = client.prepare_messages([ChatMessage(role="user", text="Hello")], chat_options)
request_options = client._prepare_options(prepared_messages, chat_options) # type: ignore[reportPrivateUsage]
assert json.dumps(request_options).count(instructions) == 1
@pytest.mark.parametrize("exclude_list", [["AZURE_OPENAI_BASE_URL"]], indirect=True)
def test_init_endpoint(azure_openai_unit_test_env: dict[str, str]) -> None:
azure_chat_client = AzureOpenAIChatClient()
@@ -1,6 +1,5 @@
# Copyright (c) Microsoft. All rights reserved.
import json
import os
from typing import Annotated
@@ -15,7 +14,6 @@ from agent_framework import (
ChatAgent,
ChatClientProtocol,
ChatMessage,
ChatOptions,
ChatResponse,
ChatResponseUpdate,
HostedCodeInterpreterTool,
@@ -114,18 +112,6 @@ def test_init_with_default_header(azure_openai_unit_test_env: dict[str, str]) ->
assert azure_responses_client.client.default_headers[key] == value
def test_azure_responses_client_instructions_sent_once(azure_openai_unit_test_env: dict[str, str]) -> None:
"""Ensure instructions are only included once for Azure OpenAI Responses requests."""
client = AzureOpenAIResponsesClient()
instructions = "You are a helpful assistant."
chat_options = ChatOptions(instructions=instructions)
prepared_messages = client.prepare_messages([ChatMessage(role="user", text="Hello")], chat_options)
request_options = client._prepare_options(prepared_messages, chat_options) # type: ignore[reportPrivateUsage]
assert json.dumps(request_options).count(instructions) == 1
@pytest.mark.parametrize("exclude_list", [["AZURE_OPENAI_RESPONSES_DEPLOYMENT_NAME"]], indirect=True)
def test_init_with_empty_model_id(azure_openai_unit_test_env: dict[str, str]) -> None:
with pytest.raises(ServiceInitializationError):
@@ -1,10 +1,13 @@
# Copyright (c) Microsoft. All rights reserved.
from unittest.mock import patch
from agent_framework import (
BaseChatClient,
ChatClientProtocol,
ChatMessage,
ChatOptions,
Role,
)
@@ -39,3 +42,20 @@ async def test_base_client_get_response(chat_client_base: ChatClientProtocol):
async def test_base_client_get_streaming_response(chat_client_base: ChatClientProtocol):
async for update in chat_client_base.get_streaming_response(ChatMessage(role="user", text="Hello")):
assert update.text == "update - Hello" or update.text == "another update"
async def test_chat_client_instructions_handling(chat_client_base: ChatClientProtocol):
instructions = "You are a helpful assistant."
with patch.object(
chat_client_base,
"_inner_get_response",
) as mock_inner_get_response:
await chat_client_base.get_response("hello", chat_options=ChatOptions(instructions=instructions))
mock_inner_get_response.assert_called_once()
_, kwargs = mock_inner_get_response.call_args
messages = kwargs.get("messages", [])
assert len(messages) == 2
assert messages[0].role == Role.SYSTEM
assert messages[0].text == instructions
assert messages[1].role == Role.USER
assert messages[1].text == "hello"
@@ -193,18 +193,6 @@ def test_openai_assistants_client_init_with_default_headers(openai_unit_test_env
assert chat_client.client.default_headers[key] == value
def test_openai_assistants_client_instructions_sent_once(mock_async_openai: MagicMock) -> None:
"""Ensure instructions are only included once for OpenAI Assistants requests."""
chat_client = create_test_openai_assistants_client(mock_async_openai)
instructions = "You are a helpful assistant."
chat_options = ChatOptions(instructions=instructions)
prepared_messages = chat_client.prepare_messages([ChatMessage(role=Role.USER, text="Hello")], chat_options)
run_options, _ = chat_client._prepare_options(prepared_messages, chat_options) # type: ignore[reportPrivateUsage]
assert run_options.get("instructions") == instructions
async def test_openai_assistants_client_get_assistant_id_or_create_existing_assistant(
mock_async_openai: MagicMock,
) -> None:
@@ -1,6 +1,5 @@
# Copyright (c) Microsoft. All rights reserved.
import json
import os
from typing import Annotated
from unittest.mock import MagicMock, patch
@@ -100,18 +99,6 @@ def test_init_base_url_from_settings_env() -> None:
assert str(client.client.base_url) == "https://custom-openai-endpoint.com/v1/"
def test_openai_chat_client_instructions_sent_once(openai_unit_test_env: dict[str, str]) -> None:
"""Ensure instructions are only included once for OpenAI chat requests."""
client = OpenAIChatClient()
instructions = "You are a helpful assistant."
chat_options = ChatOptions(instructions=instructions)
prepared_messages = client.prepare_messages([ChatMessage(role="user", text="Hello")], chat_options)
request_options = client._prepare_options(prepared_messages, chat_options) # type: ignore[reportPrivateUsage]
assert json.dumps(request_options).count(instructions) == 1
@pytest.mark.parametrize("exclude_list", [["OPENAI_CHAT_MODEL_ID"]], indirect=True)
def test_init_with_empty_model_id(openai_unit_test_env: dict[str, str]) -> None:
with pytest.raises(ServiceInitializationError):
@@ -2,7 +2,6 @@
import asyncio
import base64
import json
import os
from typing import Annotated
from unittest.mock import MagicMock, patch
@@ -138,18 +137,6 @@ def test_init_with_default_header(openai_unit_test_env: dict[str, str]) -> None:
assert openai_responses_client.client.default_headers[key] == value
def test_openai_responses_client_instructions_sent_once(openai_unit_test_env: dict[str, str]) -> None:
"""Ensure instructions are only included once for OpenAI Responses requests."""
client = OpenAIResponsesClient()
instructions = "You are a helpful assistant."
chat_options = ChatOptions(instructions=instructions)
prepared_messages = client.prepare_messages([ChatMessage(role="user", text="Hello")], chat_options)
request_options = client._prepare_options(prepared_messages, chat_options) # type: ignore[reportPrivateUsage]
assert json.dumps(request_options).count(instructions) == 1
@pytest.mark.parametrize("exclude_list", [["OPENAI_RESPONSES_MODEL_ID"]], indirect=True)
def test_init_with_empty_model_id(openai_unit_test_env: dict[str, str]) -> None:
with pytest.raises(ServiceInitializationError):