Python: AzureAI Bing Connection Name Support (#1364)

* bing connection name support

* error handling + unit tests

* connection id and name handling
This commit is contained in:
Giles Odigwe
2025-10-09 21:13:07 +00:00
committed by GitHub
parent 4cd81fe8e7
commit 7238cde5af
4 changed files with 112 additions and 25 deletions
@@ -46,7 +46,7 @@ from azure.ai.agents.models import (
)
from azure.ai.projects.models import ConnectionType
from azure.core.credentials_async import AsyncTokenCredential
from azure.core.exceptions import HttpResponseError
from azure.core.exceptions import HttpResponseError, ResourceNotFoundError
from azure.identity.aio import AzureCliCredential
from pydantic import BaseModel, Field, ValidationError
from pytest import MonkeyPatch
@@ -834,7 +834,7 @@ async def test_azure_ai_chat_client_prep_tools_web_search_bing_grounding(mock_ai
web_search_tool = HostedWebSearchTool(
additional_properties={
"connection_id": "test-connection-id",
"connection_name": "test-connection-name",
"count": 5,
"freshness": "Day",
"market": "en-US",
@@ -842,6 +842,11 @@ async def test_azure_ai_chat_client_prep_tools_web_search_bing_grounding(mock_ai
}
)
# Mock connection get
mock_connection = MagicMock()
mock_connection.id = "test-connection-id"
mock_ai_project_client.connections.get = AsyncMock(return_value=mock_connection)
# Mock BingGroundingTool
with patch("agent_framework_azure_ai._chat_client.BingGroundingTool") as mock_bing_grounding:
mock_bing_tool = MagicMock()
@@ -857,6 +862,35 @@ async def test_azure_ai_chat_client_prep_tools_web_search_bing_grounding(mock_ai
)
async def test_azure_ai_chat_client_prep_tools_web_search_bing_grounding_with_connection_id(
mock_ai_project_client: MagicMock,
) -> None:
"""Test _prep_tools with HostedWebSearchTool using Bing Grounding with connection_id (no HTTP call)."""
chat_client = create_test_azure_ai_chat_client(mock_ai_project_client, agent_id="test-agent")
web_search_tool = HostedWebSearchTool(
additional_properties={
"connection_id": "direct-connection-id",
"count": 3,
}
)
# Mock BingGroundingTool
with patch("agent_framework_azure_ai._chat_client.BingGroundingTool") as mock_bing_grounding:
mock_bing_tool = MagicMock()
mock_bing_tool.definitions = [{"type": "bing_grounding"}]
mock_bing_grounding.return_value = mock_bing_tool
result = await chat_client._prep_tools([web_search_tool]) # type: ignore
assert len(result) == 1
assert result[0] == {"type": "bing_grounding"}
# Verify that connection_id was used directly (no HTTP call to connections.get)
mock_ai_project_client.connections.get.assert_not_called()
mock_bing_grounding.assert_called_once_with(connection_id="direct-connection-id", count=3)
async def test_azure_ai_chat_client_prep_tools_web_search_custom_bing(mock_ai_project_client: MagicMock) -> None:
"""Test _prep_tools with HostedWebSearchTool using Custom Bing Search."""
@@ -912,15 +946,23 @@ async def test_azure_ai_chat_client_prep_tools_web_search_custom_bing_connection
await chat_client._prep_tools([web_search_tool]) # type: ignore
async def test_azure_ai_chat_client_prep_tools_web_search_missing_config(mock_ai_project_client: MagicMock) -> None:
"""Test _prep_tools with HostedWebSearchTool missing required configuration."""
async def test_azure_ai_chat_client_prep_tools_web_search_bing_grounding_connection_error(
mock_ai_project_client: MagicMock,
) -> None:
"""Test _prep_tools with HostedWebSearchTool when Bing Grounding connection is not found."""
chat_client = create_test_azure_ai_chat_client(mock_ai_project_client, agent_id="test-agent")
# Web search tool with no connection configuration
web_search_tool = HostedWebSearchTool()
web_search_tool = HostedWebSearchTool(
additional_properties={
"connection_name": "nonexistent-bing-connection",
}
)
with pytest.raises(ServiceInitializationError, match="Bing search tool requires either a 'connection_id'"):
# Mock connection get to raise HttpResponseError
mock_ai_project_client.connections.get = AsyncMock(side_effect=HttpResponseError("Connection not found"))
with pytest.raises(ServiceInitializationError, match="Bing connection 'nonexistent-bing-connection' not found"):
await chat_client._prep_tools([web_search_tool]) # type: ignore
@@ -1397,6 +1439,28 @@ async def test_azure_ai_chat_client_create_agent_stream_submit_tool_outputs(
assert final_thread_id == "test-thread"
async def test_azure_ai_chat_client_setup_azure_ai_observability_resource_not_found(
mock_ai_project_client: MagicMock,
) -> None:
"""Test setup_azure_ai_observability when Application Insights connection string is not found."""
chat_client = create_test_azure_ai_chat_client(mock_ai_project_client, agent_id="test-agent")
# Mock telemetry.get_application_insights_connection_string to raise ResourceNotFoundError
mock_ai_project_client.telemetry.get_application_insights_connection_string = AsyncMock(
side_effect=ResourceNotFoundError("No Application Insights found")
)
# Mock logger.warning to capture the warning message
with patch("agent_framework_azure_ai._chat_client.logger") as mock_logger:
await chat_client.setup_azure_ai_observability()
# Verify warning was logged
mock_logger.warning.assert_called_once_with(
"No Application Insights connection string found for the Azure AI Project, "
"please call setup_observability() manually."
)
def get_weather(
location: Annotated[str, Field(description="The location to get the weather for.")],
) -> str: