Skip to content

Commit 9f43108

Browse files
Python: renamed ai search and cleanup of samples and unified import logic (#2369)
* renamed ai search and cleanup of samples and unified import logic * fixed error messages * fixed folder name * remove old samples from readme
1 parent db424d5 commit 9f43108

File tree

36 files changed

+4181
-3872
lines changed

36 files changed

+4181
-3872
lines changed

python/.cspell.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
"aiplatform",
2828
"azuredocindex",
2929
"azuredocs",
30+
"azurefunctions",
3031
"boto",
3132
"contentvector",
3233
"contoso",
File renamed without changes.

python/packages/aisearch/README.md renamed to python/packages/azure-ai-search/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
Please install this package via pip:
44

55
```bash
6-
pip install agent-framework-aisearch --pre
6+
pip install agent-framework-azure-ai-search --pre
77
```
88

99
## Azure AI Search Integration

python/packages/aisearch/agent_framework_aisearch/_search_provider.py renamed to python/packages/azure-ai-search/agent_framework_azure_ai_search/_search_provider.py

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,5 @@
11
# Copyright (c) Microsoft. All rights reserved.
22

3-
"""Azure AI Search Context Provider for Agent Framework.
4-
5-
This module provides context providers for Azure AI Search integration with two modes:
6-
- Agentic: Recommended for most scenarios. Uses Knowledge Bases for query planning and
7-
multi-hop reasoning. Slightly slower with more token consumption, but more accurate.
8-
- Semantic: Fast hybrid search (vector + keyword) with semantic ranker. Best for simple
9-
queries where speed is critical.
10-
11-
See: https://techcommunity.microsoft.com/blog/azure-ai-foundry-blog/foundry-iq-boost-response-relevance-by-36-with-agentic-retrieval/4470720
12-
"""
133

144
import sys
155
from collections.abc import Awaitable, Callable, MutableSequence
@@ -111,6 +101,18 @@
111101
else:
112102
from typing_extensions import override # type: ignore[import] # pragma: no cover
113103

104+
"""Azure AI Search Context Provider for Agent Framework.
105+
106+
This module provides context providers for Azure AI Search integration with two modes:
107+
- Agentic: Recommended for most scenarios. Uses Knowledge Bases for query planning and
108+
multi-hop reasoning. Slightly slower with more token consumption, but more accurate.
109+
- Semantic: Fast hybrid search (vector + keyword) with semantic ranker. Best for simple
110+
queries where speed is critical.
111+
112+
See: https://techcommunity.microsoft.com/blog/azure-ai-foundry-blog/foundry-iq-boost-response-relevance-by-36-with-agentic-retrieval/4470720
113+
"""
114+
115+
114116
# Module-level constants
115117
logger = get_logger("agent_framework.azure")
116118
_DEFAULT_AGENTIC_MESSAGE_HISTORY_COUNT = 10

python/packages/aisearch/pyproject.toml renamed to python/packages/azure-ai-search/pyproject.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[project]
2-
name = "agent-framework-aisearch"
2+
name = "agent-framework-azure-ai-search"
33
description = "Azure AI Search integration for Microsoft Agent Framework."
44
authors = [{ name = "Microsoft", email = "[email protected]"}]
55
readme = "README.md"
@@ -76,15 +76,15 @@ disallow_incomplete_defs = true
7676
disallow_untyped_decorators = true
7777

7878
[tool.bandit]
79-
targets = ["agent_framework_aisearch"]
79+
targets = ["agent_framework_azure_ai_search"]
8080
exclude_dirs = ["tests"]
8181

8282
[tool.poe]
8383
executor.type = "uv"
8484
include = "../../shared_tasks.toml"
8585
[tool.poe.tasks]
86-
mypy = "mypy --config-file $POE_ROOT/pyproject.toml agent_framework_aisearch"
87-
test = "pytest --cov=agent_framework_aisearch --cov-report=term-missing:skip-covered tests"
86+
mypy = "mypy --config-file $POE_ROOT/pyproject.toml agent_framework_azure_ai_search"
87+
test = "pytest --cov=agent_framework_azure_ai_search --cov-report=term-missing:skip-covered tests"
8888

8989
[build-system]
9090
requires = ["flit-core >= 3.11,<4.0"]

python/packages/aisearch/tests/test_search_provider.py renamed to python/packages/azure-ai-search/tests/test_search_provider.py

Lines changed: 36 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,11 @@
66

77
import pytest
88
from agent_framework import ChatMessage, Context, Role
9-
from agent_framework.azure import AzureAISearchContextProvider
9+
from agent_framework.azure import AzureAISearchContextProvider, AzureAISearchSettings
1010
from agent_framework.exceptions import ServiceInitializationError
1111
from azure.core.credentials import AzureKeyCredential
1212
from azure.core.exceptions import ResourceNotFoundError
1313

14-
from agent_framework_aisearch import AzureAISearchSettings
15-
1614

1715
@pytest.fixture
1816
def mock_search_client() -> AsyncMock:
@@ -246,7 +244,7 @@ class TestSemanticSearch:
246244
"""Test semantic search functionality."""
247245

248246
@pytest.mark.asyncio
249-
@patch("agent_framework_aisearch._search_provider.SearchClient")
247+
@patch("agent_framework_azure_ai_search._search_provider.SearchClient")
250248
async def test_semantic_search_basic(
251249
self, mock_search_class: MagicMock, sample_messages: list[ChatMessage]
252250
) -> None:
@@ -275,7 +273,7 @@ async def test_semantic_search_basic(
275273
assert "Test document content" in context.messages[1].text
276274

277275
@pytest.mark.asyncio
278-
@patch("agent_framework_aisearch._search_provider.SearchClient")
276+
@patch("agent_framework_azure_ai_search._search_provider.SearchClient")
279277
async def test_semantic_search_empty_query(self, mock_search_class: MagicMock) -> None:
280278
"""Test that empty queries return empty context."""
281279
mock_search_client = AsyncMock()
@@ -295,7 +293,7 @@ async def test_semantic_search_empty_query(self, mock_search_class: MagicMock) -
295293
assert len(context.messages) == 0
296294

297295
@pytest.mark.asyncio
298-
@patch("agent_framework_aisearch._search_provider.SearchClient")
296+
@patch("agent_framework_azure_ai_search._search_provider.SearchClient")
299297
async def test_semantic_search_with_vector_query(
300298
self, mock_search_class: MagicMock, sample_messages: list[ChatMessage]
301299
) -> None:
@@ -332,8 +330,8 @@ class TestKnowledgeBaseSetup:
332330
"""Test Knowledge Base setup for agentic mode."""
333331

334332
@pytest.mark.asyncio
335-
@patch("agent_framework_aisearch._search_provider.SearchIndexClient")
336-
@patch("agent_framework_aisearch._search_provider.SearchClient")
333+
@patch("agent_framework_azure_ai_search._search_provider.SearchIndexClient")
334+
@patch("agent_framework_azure_ai_search._search_provider.SearchClient")
337335
async def test_ensure_knowledge_base_creates_when_not_exists(
338336
self, mock_search_class: MagicMock, mock_index_class: MagicMock
339337
) -> None:
@@ -369,8 +367,8 @@ async def test_ensure_knowledge_base_creates_when_not_exists(
369367
mock_index_client.create_or_update_knowledge_base.assert_called_once()
370368

371369
@pytest.mark.asyncio
372-
@patch("agent_framework_aisearch._search_provider.SearchIndexClient")
373-
@patch("agent_framework_aisearch._search_provider.SearchClient")
370+
@patch("agent_framework_azure_ai_search._search_provider.SearchIndexClient")
371+
@patch("agent_framework_azure_ai_search._search_provider.SearchClient")
374372
async def test_ensure_knowledge_base_skips_when_exists(
375373
self, mock_search_class: MagicMock, mock_index_class: MagicMock
376374
) -> None:
@@ -406,7 +404,7 @@ class TestContextProviderLifecycle:
406404
"""Test context provider lifecycle methods."""
407405

408406
@pytest.mark.asyncio
409-
@patch("agent_framework_aisearch._search_provider.SearchClient")
407+
@patch("agent_framework_azure_ai_search._search_provider.SearchClient")
410408
async def test_context_manager(self, mock_search_class: MagicMock) -> None:
411409
"""Test that provider can be used as async context manager."""
412410
mock_search_client = AsyncMock()
@@ -422,9 +420,9 @@ async def test_context_manager(self, mock_search_class: MagicMock) -> None:
422420
assert isinstance(provider, AzureAISearchContextProvider)
423421

424422
@pytest.mark.asyncio
425-
@patch("agent_framework_aisearch._search_provider.KnowledgeBaseRetrievalClient")
426-
@patch("agent_framework_aisearch._search_provider.SearchIndexClient")
427-
@patch("agent_framework_aisearch._search_provider.SearchClient")
423+
@patch("agent_framework_azure_ai_search._search_provider.KnowledgeBaseRetrievalClient")
424+
@patch("agent_framework_azure_ai_search._search_provider.SearchIndexClient")
425+
@patch("agent_framework_azure_ai_search._search_provider.SearchClient")
428426
async def test_context_manager_agentic_cleanup(
429427
self, mock_search_class: MagicMock, mock_index_class: MagicMock, mock_retrieval_class: MagicMock
430428
) -> None:
@@ -470,7 +468,7 @@ class TestMessageFiltering:
470468
"""Test message filtering functionality."""
471469

472470
@pytest.mark.asyncio
473-
@patch("agent_framework_aisearch._search_provider.SearchClient")
471+
@patch("agent_framework_azure_ai_search._search_provider.SearchClient")
474472
async def test_filters_non_user_assistant_messages(self, mock_search_class: MagicMock) -> None:
475473
"""Test that only USER and ASSISTANT messages are processed."""
476474
# Setup mock
@@ -502,7 +500,7 @@ async def test_filters_non_user_assistant_messages(self, mock_search_class: Magi
502500
mock_search_client.search.assert_called_once()
503501

504502
@pytest.mark.asyncio
505-
@patch("agent_framework_aisearch._search_provider.SearchClient")
503+
@patch("agent_framework_azure_ai_search._search_provider.SearchClient")
506504
async def test_filters_empty_messages(self, mock_search_class: MagicMock) -> None:
507505
"""Test that empty/whitespace messages are filtered out."""
508506
mock_search_client = AsyncMock()
@@ -532,7 +530,7 @@ class TestCitations:
532530
"""Test citation functionality."""
533531

534532
@pytest.mark.asyncio
535-
@patch("agent_framework_aisearch._search_provider.SearchClient")
533+
@patch("agent_framework_azure_ai_search._search_provider.SearchClient")
536534
async def test_citations_included_in_semantic_search(self, mock_search_class: MagicMock) -> None:
537535
"""Test that citations are included in semantic search results."""
538536
# Setup mock with document ID
@@ -564,9 +562,9 @@ class TestAgenticSearch:
564562
"""Test agentic search functionality."""
565563

566564
@pytest.mark.asyncio
567-
@patch("agent_framework_aisearch._search_provider.KnowledgeBaseRetrievalClient")
568-
@patch("agent_framework_aisearch._search_provider.SearchIndexClient")
569-
@patch("agent_framework_aisearch._search_provider.SearchClient")
565+
@patch("agent_framework_azure_ai_search._search_provider.KnowledgeBaseRetrievalClient")
566+
@patch("agent_framework_azure_ai_search._search_provider.SearchIndexClient")
567+
@patch("agent_framework_azure_ai_search._search_provider.SearchClient")
570568
async def test_agentic_search_basic(
571569
self,
572570
mock_search_class: MagicMock,
@@ -593,7 +591,7 @@ async def test_agentic_search_basic(
593591
mock_content = MagicMock()
594592
mock_content.text = "Agentic search result"
595593
# Make it pass isinstance check
596-
from agent_framework_aisearch._search_provider import _agentic_retrieval_available
594+
from agent_framework_azure_ai_search._search_provider import _agentic_retrieval_available
597595

598596
if _agentic_retrieval_available:
599597
from azure.search.documents.knowledgebases.models import KnowledgeBaseMessageTextContent
@@ -623,9 +621,9 @@ async def test_agentic_search_basic(
623621
assert len(context.messages) >= 1
624622

625623
@pytest.mark.asyncio
626-
@patch("agent_framework_aisearch._search_provider.KnowledgeBaseRetrievalClient")
627-
@patch("agent_framework_aisearch._search_provider.SearchIndexClient")
628-
@patch("agent_framework_aisearch._search_provider.SearchClient")
624+
@patch("agent_framework_azure_ai_search._search_provider.KnowledgeBaseRetrievalClient")
625+
@patch("agent_framework_azure_ai_search._search_provider.SearchIndexClient")
626+
@patch("agent_framework_azure_ai_search._search_provider.SearchClient")
629627
async def test_agentic_search_no_results(
630628
self,
631629
mock_search_class: MagicMock,
@@ -670,9 +668,9 @@ async def test_agentic_search_no_results(
670668
assert len(context.messages) >= 1
671669

672670
@pytest.mark.asyncio
673-
@patch("agent_framework_aisearch._search_provider.KnowledgeBaseRetrievalClient")
674-
@patch("agent_framework_aisearch._search_provider.SearchIndexClient")
675-
@patch("agent_framework_aisearch._search_provider.SearchClient")
671+
@patch("agent_framework_azure_ai_search._search_provider.KnowledgeBaseRetrievalClient")
672+
@patch("agent_framework_azure_ai_search._search_provider.SearchIndexClient")
673+
@patch("agent_framework_azure_ai_search._search_provider.SearchClient")
676674
async def test_agentic_search_with_medium_reasoning(
677675
self,
678676
mock_search_class: MagicMock,
@@ -696,7 +694,7 @@ async def test_agentic_search_with_medium_reasoning(
696694
mock_message = MagicMock()
697695
mock_content = MagicMock()
698696
mock_content.text = "Medium reasoning result"
699-
from agent_framework_aisearch._search_provider import _agentic_retrieval_available
697+
from agent_framework_azure_ai_search._search_provider import _agentic_retrieval_available
700698

701699
if _agentic_retrieval_available:
702700
from azure.search.documents.knowledgebases.models import KnowledgeBaseMessageTextContent
@@ -730,8 +728,8 @@ class TestVectorFieldAutoDiscovery:
730728
"""Test vector field auto-discovery functionality."""
731729

732730
@pytest.mark.asyncio
733-
@patch("agent_framework_aisearch._search_provider.SearchIndexClient")
734-
@patch("agent_framework_aisearch._search_provider.SearchClient")
731+
@patch("agent_framework_azure_ai_search._search_provider.SearchIndexClient")
732+
@patch("agent_framework_azure_ai_search._search_provider.SearchClient")
735733
async def test_auto_discovers_single_vector_field(
736734
self, mock_search_class: MagicMock, mock_index_class: MagicMock
737735
) -> None:
@@ -795,8 +793,8 @@ async def test_vector_detection_accuracy(self) -> None:
795793
assert is_vector_3 is False
796794

797795
@pytest.mark.asyncio
798-
@patch("agent_framework_aisearch._search_provider.SearchIndexClient")
799-
@patch("agent_framework_aisearch._search_provider.SearchClient")
796+
@patch("agent_framework_azure_ai_search._search_provider.SearchIndexClient")
797+
@patch("agent_framework_azure_ai_search._search_provider.SearchClient")
800798
async def test_no_false_positives_on_string_fields(
801799
self, mock_search_class: MagicMock, mock_index_class: MagicMock
802800
) -> None:
@@ -839,8 +837,8 @@ async def test_no_false_positives_on_string_fields(
839837
assert provider._auto_discovered_vector_field is True
840838

841839
@pytest.mark.asyncio
842-
@patch("agent_framework_aisearch._search_provider.SearchIndexClient")
843-
@patch("agent_framework_aisearch._search_provider.SearchClient")
840+
@patch("agent_framework_azure_ai_search._search_provider.SearchIndexClient")
841+
@patch("agent_framework_azure_ai_search._search_provider.SearchClient")
844842
async def test_multiple_vector_fields_without_vectorizer(
845843
self, mock_search_class: MagicMock, mock_index_class: MagicMock
846844
) -> None:
@@ -884,8 +882,8 @@ async def test_multiple_vector_fields_without_vectorizer(
884882
assert provider._auto_discovered_vector_field is True
885883

886884
@pytest.mark.asyncio
887-
@patch("agent_framework_aisearch._search_provider.SearchIndexClient")
888-
@patch("agent_framework_aisearch._search_provider.SearchClient")
885+
@patch("agent_framework_azure_ai_search._search_provider.SearchIndexClient")
886+
@patch("agent_framework_azure_ai_search._search_provider.SearchClient")
889887
async def test_multiple_vectorizable_fields(
890888
self, mock_search_class: MagicMock, mock_index_class: MagicMock
891889
) -> None:
@@ -941,8 +939,8 @@ async def test_multiple_vectorizable_fields(
941939
assert provider._auto_discovered_vector_field is True
942940

943941
@pytest.mark.asyncio
944-
@patch("agent_framework_aisearch._search_provider.SearchIndexClient")
945-
@patch("agent_framework_aisearch._search_provider.SearchClient")
942+
@patch("agent_framework_azure_ai_search._search_provider.SearchIndexClient")
943+
@patch("agent_framework_azure_ai_search._search_provider.SearchClient")
946944
async def test_single_vectorizable_field_detected(
947945
self, mock_search_class: MagicMock, mock_index_class: MagicMock
948946
) -> None:

0 commit comments

Comments
 (0)