mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
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
This commit is contained in:
committed by
GitHub
Unverified
parent
db424d56f3
commit
9f43108ef1
@@ -27,6 +27,7 @@
|
||||
"aiplatform",
|
||||
"azuredocindex",
|
||||
"azuredocs",
|
||||
"azurefunctions",
|
||||
"boto",
|
||||
"contentvector",
|
||||
"contoso",
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
Please install this package via pip:
|
||||
|
||||
```bash
|
||||
pip install agent-framework-aisearch --pre
|
||||
pip install agent-framework-azure-ai-search --pre
|
||||
```
|
||||
|
||||
## Azure AI Search Integration
|
||||
+12
-10
@@ -1,15 +1,5 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
"""Azure AI Search Context Provider for Agent Framework.
|
||||
|
||||
This module provides context providers for Azure AI Search integration with two modes:
|
||||
- Agentic: Recommended for most scenarios. Uses Knowledge Bases for query planning and
|
||||
multi-hop reasoning. Slightly slower with more token consumption, but more accurate.
|
||||
- Semantic: Fast hybrid search (vector + keyword) with semantic ranker. Best for simple
|
||||
queries where speed is critical.
|
||||
|
||||
See: https://techcommunity.microsoft.com/blog/azure-ai-foundry-blog/foundry-iq-boost-response-relevance-by-36-with-agentic-retrieval/4470720
|
||||
"""
|
||||
|
||||
import sys
|
||||
from collections.abc import Awaitable, Callable, MutableSequence
|
||||
@@ -111,6 +101,18 @@ if sys.version_info >= (3, 12):
|
||||
else:
|
||||
from typing_extensions import override # type: ignore[import] # pragma: no cover
|
||||
|
||||
"""Azure AI Search Context Provider for Agent Framework.
|
||||
|
||||
This module provides context providers for Azure AI Search integration with two modes:
|
||||
- Agentic: Recommended for most scenarios. Uses Knowledge Bases for query planning and
|
||||
multi-hop reasoning. Slightly slower with more token consumption, but more accurate.
|
||||
- Semantic: Fast hybrid search (vector + keyword) with semantic ranker. Best for simple
|
||||
queries where speed is critical.
|
||||
|
||||
See: https://techcommunity.microsoft.com/blog/azure-ai-foundry-blog/foundry-iq-boost-response-relevance-by-36-with-agentic-retrieval/4470720
|
||||
"""
|
||||
|
||||
|
||||
# Module-level constants
|
||||
logger = get_logger("agent_framework.azure")
|
||||
_DEFAULT_AGENTIC_MESSAGE_HISTORY_COUNT = 10
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
[project]
|
||||
name = "agent-framework-aisearch"
|
||||
name = "agent-framework-azure-ai-search"
|
||||
description = "Azure AI Search integration for Microsoft Agent Framework."
|
||||
authors = [{ name = "Microsoft", email = "af-support@microsoft.com"}]
|
||||
readme = "README.md"
|
||||
@@ -76,15 +76,15 @@ disallow_incomplete_defs = true
|
||||
disallow_untyped_decorators = true
|
||||
|
||||
[tool.bandit]
|
||||
targets = ["agent_framework_aisearch"]
|
||||
targets = ["agent_framework_azure_ai_search"]
|
||||
exclude_dirs = ["tests"]
|
||||
|
||||
[tool.poe]
|
||||
executor.type = "uv"
|
||||
include = "../../shared_tasks.toml"
|
||||
[tool.poe.tasks]
|
||||
mypy = "mypy --config-file $POE_ROOT/pyproject.toml agent_framework_aisearch"
|
||||
test = "pytest --cov=agent_framework_aisearch --cov-report=term-missing:skip-covered tests"
|
||||
mypy = "mypy --config-file $POE_ROOT/pyproject.toml agent_framework_azure_ai_search"
|
||||
test = "pytest --cov=agent_framework_azure_ai_search --cov-report=term-missing:skip-covered tests"
|
||||
|
||||
[build-system]
|
||||
requires = ["flit-core >= 3.11,<4.0"]
|
||||
+36
-38
@@ -6,13 +6,11 @@ from unittest.mock import AsyncMock, MagicMock, patch
|
||||
|
||||
import pytest
|
||||
from agent_framework import ChatMessage, Context, Role
|
||||
from agent_framework.azure import AzureAISearchContextProvider
|
||||
from agent_framework.azure import AzureAISearchContextProvider, AzureAISearchSettings
|
||||
from agent_framework.exceptions import ServiceInitializationError
|
||||
from azure.core.credentials import AzureKeyCredential
|
||||
from azure.core.exceptions import ResourceNotFoundError
|
||||
|
||||
from agent_framework_aisearch import AzureAISearchSettings
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_search_client() -> AsyncMock:
|
||||
@@ -246,7 +244,7 @@ class TestSemanticSearch:
|
||||
"""Test semantic search functionality."""
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@patch("agent_framework_aisearch._search_provider.SearchClient")
|
||||
@patch("agent_framework_azure_ai_search._search_provider.SearchClient")
|
||||
async def test_semantic_search_basic(
|
||||
self, mock_search_class: MagicMock, sample_messages: list[ChatMessage]
|
||||
) -> None:
|
||||
@@ -275,7 +273,7 @@ class TestSemanticSearch:
|
||||
assert "Test document content" in context.messages[1].text
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@patch("agent_framework_aisearch._search_provider.SearchClient")
|
||||
@patch("agent_framework_azure_ai_search._search_provider.SearchClient")
|
||||
async def test_semantic_search_empty_query(self, mock_search_class: MagicMock) -> None:
|
||||
"""Test that empty queries return empty context."""
|
||||
mock_search_client = AsyncMock()
|
||||
@@ -295,7 +293,7 @@ class TestSemanticSearch:
|
||||
assert len(context.messages) == 0
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@patch("agent_framework_aisearch._search_provider.SearchClient")
|
||||
@patch("agent_framework_azure_ai_search._search_provider.SearchClient")
|
||||
async def test_semantic_search_with_vector_query(
|
||||
self, mock_search_class: MagicMock, sample_messages: list[ChatMessage]
|
||||
) -> None:
|
||||
@@ -332,8 +330,8 @@ class TestKnowledgeBaseSetup:
|
||||
"""Test Knowledge Base setup for agentic mode."""
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@patch("agent_framework_aisearch._search_provider.SearchIndexClient")
|
||||
@patch("agent_framework_aisearch._search_provider.SearchClient")
|
||||
@patch("agent_framework_azure_ai_search._search_provider.SearchIndexClient")
|
||||
@patch("agent_framework_azure_ai_search._search_provider.SearchClient")
|
||||
async def test_ensure_knowledge_base_creates_when_not_exists(
|
||||
self, mock_search_class: MagicMock, mock_index_class: MagicMock
|
||||
) -> None:
|
||||
@@ -369,8 +367,8 @@ class TestKnowledgeBaseSetup:
|
||||
mock_index_client.create_or_update_knowledge_base.assert_called_once()
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@patch("agent_framework_aisearch._search_provider.SearchIndexClient")
|
||||
@patch("agent_framework_aisearch._search_provider.SearchClient")
|
||||
@patch("agent_framework_azure_ai_search._search_provider.SearchIndexClient")
|
||||
@patch("agent_framework_azure_ai_search._search_provider.SearchClient")
|
||||
async def test_ensure_knowledge_base_skips_when_exists(
|
||||
self, mock_search_class: MagicMock, mock_index_class: MagicMock
|
||||
) -> None:
|
||||
@@ -406,7 +404,7 @@ class TestContextProviderLifecycle:
|
||||
"""Test context provider lifecycle methods."""
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@patch("agent_framework_aisearch._search_provider.SearchClient")
|
||||
@patch("agent_framework_azure_ai_search._search_provider.SearchClient")
|
||||
async def test_context_manager(self, mock_search_class: MagicMock) -> None:
|
||||
"""Test that provider can be used as async context manager."""
|
||||
mock_search_client = AsyncMock()
|
||||
@@ -422,9 +420,9 @@ class TestContextProviderLifecycle:
|
||||
assert isinstance(provider, AzureAISearchContextProvider)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@patch("agent_framework_aisearch._search_provider.KnowledgeBaseRetrievalClient")
|
||||
@patch("agent_framework_aisearch._search_provider.SearchIndexClient")
|
||||
@patch("agent_framework_aisearch._search_provider.SearchClient")
|
||||
@patch("agent_framework_azure_ai_search._search_provider.KnowledgeBaseRetrievalClient")
|
||||
@patch("agent_framework_azure_ai_search._search_provider.SearchIndexClient")
|
||||
@patch("agent_framework_azure_ai_search._search_provider.SearchClient")
|
||||
async def test_context_manager_agentic_cleanup(
|
||||
self, mock_search_class: MagicMock, mock_index_class: MagicMock, mock_retrieval_class: MagicMock
|
||||
) -> None:
|
||||
@@ -470,7 +468,7 @@ class TestMessageFiltering:
|
||||
"""Test message filtering functionality."""
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@patch("agent_framework_aisearch._search_provider.SearchClient")
|
||||
@patch("agent_framework_azure_ai_search._search_provider.SearchClient")
|
||||
async def test_filters_non_user_assistant_messages(self, mock_search_class: MagicMock) -> None:
|
||||
"""Test that only USER and ASSISTANT messages are processed."""
|
||||
# Setup mock
|
||||
@@ -502,7 +500,7 @@ class TestMessageFiltering:
|
||||
mock_search_client.search.assert_called_once()
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@patch("agent_framework_aisearch._search_provider.SearchClient")
|
||||
@patch("agent_framework_azure_ai_search._search_provider.SearchClient")
|
||||
async def test_filters_empty_messages(self, mock_search_class: MagicMock) -> None:
|
||||
"""Test that empty/whitespace messages are filtered out."""
|
||||
mock_search_client = AsyncMock()
|
||||
@@ -532,7 +530,7 @@ class TestCitations:
|
||||
"""Test citation functionality."""
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@patch("agent_framework_aisearch._search_provider.SearchClient")
|
||||
@patch("agent_framework_azure_ai_search._search_provider.SearchClient")
|
||||
async def test_citations_included_in_semantic_search(self, mock_search_class: MagicMock) -> None:
|
||||
"""Test that citations are included in semantic search results."""
|
||||
# Setup mock with document ID
|
||||
@@ -564,9 +562,9 @@ class TestAgenticSearch:
|
||||
"""Test agentic search functionality."""
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@patch("agent_framework_aisearch._search_provider.KnowledgeBaseRetrievalClient")
|
||||
@patch("agent_framework_aisearch._search_provider.SearchIndexClient")
|
||||
@patch("agent_framework_aisearch._search_provider.SearchClient")
|
||||
@patch("agent_framework_azure_ai_search._search_provider.KnowledgeBaseRetrievalClient")
|
||||
@patch("agent_framework_azure_ai_search._search_provider.SearchIndexClient")
|
||||
@patch("agent_framework_azure_ai_search._search_provider.SearchClient")
|
||||
async def test_agentic_search_basic(
|
||||
self,
|
||||
mock_search_class: MagicMock,
|
||||
@@ -593,7 +591,7 @@ class TestAgenticSearch:
|
||||
mock_content = MagicMock()
|
||||
mock_content.text = "Agentic search result"
|
||||
# Make it pass isinstance check
|
||||
from agent_framework_aisearch._search_provider import _agentic_retrieval_available
|
||||
from agent_framework_azure_ai_search._search_provider import _agentic_retrieval_available
|
||||
|
||||
if _agentic_retrieval_available:
|
||||
from azure.search.documents.knowledgebases.models import KnowledgeBaseMessageTextContent
|
||||
@@ -623,9 +621,9 @@ class TestAgenticSearch:
|
||||
assert len(context.messages) >= 1
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@patch("agent_framework_aisearch._search_provider.KnowledgeBaseRetrievalClient")
|
||||
@patch("agent_framework_aisearch._search_provider.SearchIndexClient")
|
||||
@patch("agent_framework_aisearch._search_provider.SearchClient")
|
||||
@patch("agent_framework_azure_ai_search._search_provider.KnowledgeBaseRetrievalClient")
|
||||
@patch("agent_framework_azure_ai_search._search_provider.SearchIndexClient")
|
||||
@patch("agent_framework_azure_ai_search._search_provider.SearchClient")
|
||||
async def test_agentic_search_no_results(
|
||||
self,
|
||||
mock_search_class: MagicMock,
|
||||
@@ -670,9 +668,9 @@ class TestAgenticSearch:
|
||||
assert len(context.messages) >= 1
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@patch("agent_framework_aisearch._search_provider.KnowledgeBaseRetrievalClient")
|
||||
@patch("agent_framework_aisearch._search_provider.SearchIndexClient")
|
||||
@patch("agent_framework_aisearch._search_provider.SearchClient")
|
||||
@patch("agent_framework_azure_ai_search._search_provider.KnowledgeBaseRetrievalClient")
|
||||
@patch("agent_framework_azure_ai_search._search_provider.SearchIndexClient")
|
||||
@patch("agent_framework_azure_ai_search._search_provider.SearchClient")
|
||||
async def test_agentic_search_with_medium_reasoning(
|
||||
self,
|
||||
mock_search_class: MagicMock,
|
||||
@@ -696,7 +694,7 @@ class TestAgenticSearch:
|
||||
mock_message = MagicMock()
|
||||
mock_content = MagicMock()
|
||||
mock_content.text = "Medium reasoning result"
|
||||
from agent_framework_aisearch._search_provider import _agentic_retrieval_available
|
||||
from agent_framework_azure_ai_search._search_provider import _agentic_retrieval_available
|
||||
|
||||
if _agentic_retrieval_available:
|
||||
from azure.search.documents.knowledgebases.models import KnowledgeBaseMessageTextContent
|
||||
@@ -730,8 +728,8 @@ class TestVectorFieldAutoDiscovery:
|
||||
"""Test vector field auto-discovery functionality."""
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@patch("agent_framework_aisearch._search_provider.SearchIndexClient")
|
||||
@patch("agent_framework_aisearch._search_provider.SearchClient")
|
||||
@patch("agent_framework_azure_ai_search._search_provider.SearchIndexClient")
|
||||
@patch("agent_framework_azure_ai_search._search_provider.SearchClient")
|
||||
async def test_auto_discovers_single_vector_field(
|
||||
self, mock_search_class: MagicMock, mock_index_class: MagicMock
|
||||
) -> None:
|
||||
@@ -795,8 +793,8 @@ class TestVectorFieldAutoDiscovery:
|
||||
assert is_vector_3 is False
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@patch("agent_framework_aisearch._search_provider.SearchIndexClient")
|
||||
@patch("agent_framework_aisearch._search_provider.SearchClient")
|
||||
@patch("agent_framework_azure_ai_search._search_provider.SearchIndexClient")
|
||||
@patch("agent_framework_azure_ai_search._search_provider.SearchClient")
|
||||
async def test_no_false_positives_on_string_fields(
|
||||
self, mock_search_class: MagicMock, mock_index_class: MagicMock
|
||||
) -> None:
|
||||
@@ -839,8 +837,8 @@ class TestVectorFieldAutoDiscovery:
|
||||
assert provider._auto_discovered_vector_field is True
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@patch("agent_framework_aisearch._search_provider.SearchIndexClient")
|
||||
@patch("agent_framework_aisearch._search_provider.SearchClient")
|
||||
@patch("agent_framework_azure_ai_search._search_provider.SearchIndexClient")
|
||||
@patch("agent_framework_azure_ai_search._search_provider.SearchClient")
|
||||
async def test_multiple_vector_fields_without_vectorizer(
|
||||
self, mock_search_class: MagicMock, mock_index_class: MagicMock
|
||||
) -> None:
|
||||
@@ -884,8 +882,8 @@ class TestVectorFieldAutoDiscovery:
|
||||
assert provider._auto_discovered_vector_field is True
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@patch("agent_framework_aisearch._search_provider.SearchIndexClient")
|
||||
@patch("agent_framework_aisearch._search_provider.SearchClient")
|
||||
@patch("agent_framework_azure_ai_search._search_provider.SearchIndexClient")
|
||||
@patch("agent_framework_azure_ai_search._search_provider.SearchClient")
|
||||
async def test_multiple_vectorizable_fields(
|
||||
self, mock_search_class: MagicMock, mock_index_class: MagicMock
|
||||
) -> None:
|
||||
@@ -941,8 +939,8 @@ class TestVectorFieldAutoDiscovery:
|
||||
assert provider._auto_discovered_vector_field is True
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@patch("agent_framework_aisearch._search_provider.SearchIndexClient")
|
||||
@patch("agent_framework_aisearch._search_provider.SearchClient")
|
||||
@patch("agent_framework_azure_ai_search._search_provider.SearchIndexClient")
|
||||
@patch("agent_framework_azure_ai_search._search_provider.SearchClient")
|
||||
async def test_single_vectorizable_field_detected(
|
||||
self, mock_search_class: MagicMock, mock_index_class: MagicMock
|
||||
) -> None:
|
||||
@@ -1,185 +0,0 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
from ._agent import WorkflowAgent
|
||||
from ._agent_executor import (
|
||||
AgentExecutor,
|
||||
AgentExecutorRequest,
|
||||
AgentExecutorResponse,
|
||||
)
|
||||
from ._checkpoint import (
|
||||
CheckpointStorage,
|
||||
FileCheckpointStorage,
|
||||
InMemoryCheckpointStorage,
|
||||
WorkflowCheckpoint,
|
||||
)
|
||||
from ._checkpoint_summary import WorkflowCheckpointSummary, get_checkpoint_summary
|
||||
from ._concurrent import ConcurrentBuilder
|
||||
from ._const import DEFAULT_MAX_ITERATIONS
|
||||
from ._edge import (
|
||||
Case,
|
||||
Default,
|
||||
Edge,
|
||||
FanInEdgeGroup,
|
||||
FanOutEdgeGroup,
|
||||
SingleEdgeGroup,
|
||||
SwitchCaseEdgeGroup,
|
||||
SwitchCaseEdgeGroupCase,
|
||||
SwitchCaseEdgeGroupDefault,
|
||||
)
|
||||
from ._edge_runner import create_edge_runner
|
||||
from ._events import (
|
||||
AgentRunEvent,
|
||||
AgentRunUpdateEvent,
|
||||
ExecutorCompletedEvent,
|
||||
ExecutorEvent,
|
||||
ExecutorFailedEvent,
|
||||
ExecutorInvokedEvent,
|
||||
RequestInfoEvent,
|
||||
SuperStepCompletedEvent,
|
||||
SuperStepStartedEvent,
|
||||
WorkflowErrorDetails,
|
||||
WorkflowEvent,
|
||||
WorkflowEventSource,
|
||||
WorkflowFailedEvent,
|
||||
WorkflowLifecycleEvent,
|
||||
WorkflowOutputEvent,
|
||||
WorkflowRunState,
|
||||
WorkflowStartedEvent,
|
||||
WorkflowStatusEvent,
|
||||
)
|
||||
from ._executor import (
|
||||
Executor,
|
||||
handler,
|
||||
)
|
||||
from ._function_executor import FunctionExecutor, executor
|
||||
from ._group_chat import (
|
||||
DEFAULT_MANAGER_INSTRUCTIONS,
|
||||
DEFAULT_MANAGER_STRUCTURED_OUTPUT_PROMPT,
|
||||
GroupChatBuilder,
|
||||
GroupChatDirective,
|
||||
GroupChatStateSnapshot,
|
||||
)
|
||||
from ._handoff import HandoffBuilder, HandoffUserInputRequest
|
||||
from ._magentic import (
|
||||
MagenticAgentDeltaEvent,
|
||||
MagenticAgentMessageEvent,
|
||||
MagenticBuilder,
|
||||
MagenticContext,
|
||||
MagenticFinalResultEvent,
|
||||
MagenticManagerBase,
|
||||
MagenticOrchestratorMessageEvent,
|
||||
MagenticPlanReviewDecision,
|
||||
MagenticPlanReviewReply,
|
||||
MagenticPlanReviewRequest,
|
||||
StandardMagenticManager,
|
||||
)
|
||||
from ._orchestration_state import OrchestrationState
|
||||
from ._request_info_mixin import response_handler
|
||||
from ._runner import Runner
|
||||
from ._runner_context import (
|
||||
InProcRunnerContext,
|
||||
Message,
|
||||
RunnerContext,
|
||||
)
|
||||
from ._sequential import SequentialBuilder
|
||||
from ._shared_state import SharedState
|
||||
from ._validation import (
|
||||
EdgeDuplicationError,
|
||||
GraphConnectivityError,
|
||||
TypeCompatibilityError,
|
||||
ValidationTypeEnum,
|
||||
WorkflowValidationError,
|
||||
validate_workflow_graph,
|
||||
)
|
||||
from ._viz import WorkflowViz
|
||||
from ._workflow import Workflow, WorkflowRunResult
|
||||
from ._workflow_builder import WorkflowBuilder
|
||||
from ._workflow_context import WorkflowContext
|
||||
from ._workflow_executor import SubWorkflowRequestMessage, SubWorkflowResponseMessage, WorkflowExecutor
|
||||
|
||||
__all__ = [
|
||||
"DEFAULT_MANAGER_INSTRUCTIONS",
|
||||
"DEFAULT_MANAGER_STRUCTURED_OUTPUT_PROMPT",
|
||||
"DEFAULT_MAX_ITERATIONS",
|
||||
"AgentExecutor",
|
||||
"AgentExecutorRequest",
|
||||
"AgentExecutorResponse",
|
||||
"AgentRunEvent",
|
||||
"AgentRunUpdateEvent",
|
||||
"Case",
|
||||
"CheckpointStorage",
|
||||
"ConcurrentBuilder",
|
||||
"Default",
|
||||
"Edge",
|
||||
"EdgeDuplicationError",
|
||||
"Executor",
|
||||
"ExecutorCompletedEvent",
|
||||
"ExecutorEvent",
|
||||
"ExecutorFailedEvent",
|
||||
"ExecutorInvokedEvent",
|
||||
"FanInEdgeGroup",
|
||||
"FanOutEdgeGroup",
|
||||
"FileCheckpointStorage",
|
||||
"FunctionExecutor",
|
||||
"GraphConnectivityError",
|
||||
"GroupChatBuilder",
|
||||
"GroupChatDirective",
|
||||
"GroupChatStateSnapshot",
|
||||
"HandoffBuilder",
|
||||
"HandoffUserInputRequest",
|
||||
"InMemoryCheckpointStorage",
|
||||
"InProcRunnerContext",
|
||||
"MagenticAgentDeltaEvent",
|
||||
"MagenticAgentMessageEvent",
|
||||
"MagenticBuilder",
|
||||
"MagenticContext",
|
||||
"MagenticFinalResultEvent",
|
||||
"MagenticManagerBase",
|
||||
"MagenticOrchestratorMessageEvent",
|
||||
"MagenticPlanReviewDecision",
|
||||
"MagenticPlanReviewReply",
|
||||
"MagenticPlanReviewRequest",
|
||||
"Message",
|
||||
"OrchestrationState",
|
||||
"RequestInfoEvent",
|
||||
"Runner",
|
||||
"RunnerContext",
|
||||
"SequentialBuilder",
|
||||
"SharedState",
|
||||
"SingleEdgeGroup",
|
||||
"StandardMagenticManager",
|
||||
"SubWorkflowRequestMessage",
|
||||
"SubWorkflowResponseMessage",
|
||||
"SuperStepCompletedEvent",
|
||||
"SuperStepStartedEvent",
|
||||
"SwitchCaseEdgeGroup",
|
||||
"SwitchCaseEdgeGroupCase",
|
||||
"SwitchCaseEdgeGroupDefault",
|
||||
"TypeCompatibilityError",
|
||||
"ValidationTypeEnum",
|
||||
"Workflow",
|
||||
"WorkflowAgent",
|
||||
"WorkflowBuilder",
|
||||
"WorkflowCheckpoint",
|
||||
"WorkflowCheckpointSummary",
|
||||
"WorkflowContext",
|
||||
"WorkflowErrorDetails",
|
||||
"WorkflowEvent",
|
||||
"WorkflowEventSource",
|
||||
"WorkflowExecutor",
|
||||
"WorkflowFailedEvent",
|
||||
"WorkflowLifecycleEvent",
|
||||
"WorkflowOutputEvent",
|
||||
"WorkflowRunResult",
|
||||
"WorkflowRunState",
|
||||
"WorkflowStartedEvent",
|
||||
"WorkflowStatusEvent",
|
||||
"WorkflowValidationError",
|
||||
"WorkflowViz",
|
||||
"create_edge_runner",
|
||||
"executor",
|
||||
"get_checkpoint_summary",
|
||||
"handler",
|
||||
"response_handler",
|
||||
"validate_workflow_graph",
|
||||
]
|
||||
@@ -3,20 +3,20 @@
|
||||
import importlib
|
||||
from typing import Any
|
||||
|
||||
PACKAGE_NAME = "agent_framework_a2a"
|
||||
PACKAGE_EXTRA = "a2a"
|
||||
IMPORT_PATH = "agent_framework_a2a"
|
||||
PACKAGE_NAME = "agent-framework-a2a"
|
||||
_IMPORTS = ["__version__", "A2AAgent"]
|
||||
|
||||
|
||||
def __getattr__(name: str) -> Any:
|
||||
if name in _IMPORTS:
|
||||
try:
|
||||
return getattr(importlib.import_module(PACKAGE_NAME), name)
|
||||
return getattr(importlib.import_module(IMPORT_PATH), name)
|
||||
except ModuleNotFoundError as exc:
|
||||
raise ModuleNotFoundError(
|
||||
f"The '{PACKAGE_EXTRA}' extra is not installed, please do `pip install agent-framework-{PACKAGE_EXTRA}`"
|
||||
f"The '{PACKAGE_NAME}' package is not installed, please do `pip install {PACKAGE_NAME}`"
|
||||
) from exc
|
||||
raise AttributeError(f"Module {PACKAGE_NAME} has no attribute {name}.")
|
||||
raise AttributeError(f"Module {IMPORT_PATH} has no attribute {name}.")
|
||||
|
||||
|
||||
def __dir__() -> list[str]:
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
from agent_framework_a2a import A2AAgent, __version__
|
||||
from agent_framework_a2a import (
|
||||
A2AAgent,
|
||||
__version__,
|
||||
)
|
||||
|
||||
__all__ = ["A2AAgent", "__version__"]
|
||||
__all__ = [
|
||||
"A2AAgent",
|
||||
"__version__",
|
||||
]
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
import importlib
|
||||
from typing import Any
|
||||
|
||||
PACKAGE_NAME = "agent_framework_ag_ui"
|
||||
PACKAGE_EXTRA = "ag-ui"
|
||||
IMPORT_PATH = "agent_framework_ag_ui"
|
||||
PACKAGE_NAME = "agent-framework-ag-ui"
|
||||
_IMPORTS = [
|
||||
"__version__",
|
||||
"AgentFrameworkAgent",
|
||||
@@ -23,12 +23,12 @@ _IMPORTS = [
|
||||
def __getattr__(name: str) -> Any:
|
||||
if name in _IMPORTS:
|
||||
try:
|
||||
return getattr(importlib.import_module(PACKAGE_NAME), name)
|
||||
return getattr(importlib.import_module(IMPORT_PATH), name)
|
||||
except ModuleNotFoundError as exc:
|
||||
raise ModuleNotFoundError(
|
||||
f"The '{PACKAGE_EXTRA}' extra is not installed, please do `pip install agent-framework-{PACKAGE_EXTRA}`"
|
||||
f"The '{PACKAGE_NAME}' package is not installed, please do `pip install {PACKAGE_NAME}`"
|
||||
) from exc
|
||||
raise AttributeError(f"Module {PACKAGE_NAME} has no attribute {name}.")
|
||||
raise AttributeError(f"Module {IMPORT_PATH} has no attribute {name}.")
|
||||
|
||||
|
||||
def __dir__() -> list[str]:
|
||||
|
||||
@@ -3,20 +3,20 @@
|
||||
import importlib
|
||||
from typing import Any
|
||||
|
||||
PACKAGE_NAME = "agent_framework_anthropic"
|
||||
PACKAGE_EXTRA = "anthropic"
|
||||
IMPORT_PATH = "agent_framework_anthropic"
|
||||
PACKAGE_NAME = "agent-framework-anthropic"
|
||||
_IMPORTS = ["__version__", "AnthropicClient"]
|
||||
|
||||
|
||||
def __getattr__(name: str) -> Any:
|
||||
if name in _IMPORTS:
|
||||
try:
|
||||
return getattr(importlib.import_module(PACKAGE_NAME), name)
|
||||
return getattr(importlib.import_module(IMPORT_PATH), name)
|
||||
except ModuleNotFoundError as exc:
|
||||
raise ModuleNotFoundError(
|
||||
f"The '{PACKAGE_EXTRA}' extra is not installed, please do `pip install agent-framework-{PACKAGE_EXTRA}`"
|
||||
f"The '{PACKAGE_NAME}' package is not installed, please do `pip install {PACKAGE_NAME}`"
|
||||
) from exc
|
||||
raise AttributeError(f"Module {PACKAGE_NAME} has no attribute {name}.")
|
||||
raise AttributeError(f"Module {IMPORT_PATH} has no attribute {name}.")
|
||||
|
||||
|
||||
def __dir__() -> list[str]:
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
from agent_framework_anthropic import AnthropicClient, __version__
|
||||
from agent_framework_anthropic import (
|
||||
AnthropicClient,
|
||||
__version__,
|
||||
)
|
||||
|
||||
__all__ = ["AnthropicClient", "__version__"]
|
||||
__all__ = [
|
||||
"AnthropicClient",
|
||||
"__version__",
|
||||
]
|
||||
|
||||
@@ -1,36 +1,35 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
|
||||
import importlib
|
||||
from typing import Any
|
||||
|
||||
_IMPORTS: dict[str, tuple[str, str]] = {
|
||||
"AgentCallbackContext": ("agent_framework_azurefunctions", "azurefunctions"),
|
||||
"AgentFunctionApp": ("agent_framework_azurefunctions", "azurefunctions"),
|
||||
"AgentResponseCallbackProtocol": ("agent_framework_azurefunctions", "azurefunctions"),
|
||||
"AzureAIAgentClient": ("agent_framework_azure_ai", "azure-ai"),
|
||||
"AzureAIClient": ("agent_framework_azure_ai", "azure-ai"),
|
||||
"AzureAISearchContextProvider": ("agent_framework_aisearch", "aisearch"),
|
||||
"AzureAISearchSettings": ("agent_framework_aisearch", "aisearch"),
|
||||
"AzureOpenAIAssistantsClient": ("agent_framework.azure._assistants_client", "core"),
|
||||
"AzureOpenAIChatClient": ("agent_framework.azure._chat_client", "core"),
|
||||
"AzureAISettings": ("agent_framework_azure_ai", "azure-ai"),
|
||||
"AzureOpenAISettings": ("agent_framework.azure._shared", "core"),
|
||||
"AzureOpenAIResponsesClient": ("agent_framework.azure._responses_client", "core"),
|
||||
"DurableAIAgent": ("agent_framework_azurefunctions", "azurefunctions"),
|
||||
"get_entra_auth_token": ("agent_framework.azure._entra_id_authentication", "core"),
|
||||
"AgentCallbackContext": ("agent_framework_azurefunctions", "agent-framework-azurefunctions"),
|
||||
"AgentFunctionApp": ("agent_framework_azurefunctions", "agent-framework-azurefunctions"),
|
||||
"AgentResponseCallbackProtocol": ("agent_framework_azurefunctions", "agent-framework-azurefunctions"),
|
||||
"AzureAIAgentClient": ("agent_framework_azure_ai", "agent-framework-azure-ai"),
|
||||
"AzureAIClient": ("agent_framework_azure_ai", "agent-framework-azure-ai"),
|
||||
"AzureAISearchContextProvider": ("agent_framework_azure_ai_search", "agent-framework-azure-ai-search"),
|
||||
"AzureAISearchSettings": ("agent_framework_azure_ai_search", "agent-framework-azure-ai-search"),
|
||||
"AzureAISettings": ("agent_framework_azure_ai", "agent-framework-azure-ai"),
|
||||
"AzureOpenAIAssistantsClient": ("agent_framework.azure._assistants_client", "agent-framework-core"),
|
||||
"AzureOpenAIChatClient": ("agent_framework.azure._chat_client", "agent-framework-core"),
|
||||
"AzureOpenAIResponsesClient": ("agent_framework.azure._responses_client", "agent-framework-core"),
|
||||
"AzureOpenAISettings": ("agent_framework.azure._shared", "agent-framework-core"),
|
||||
"DurableAIAgent": ("agent_framework_azurefunctions", "agent-framework-azurefunctions"),
|
||||
"get_entra_auth_token": ("agent_framework.azure._entra_id_authentication", "agent-framework-core"),
|
||||
}
|
||||
|
||||
|
||||
def __getattr__(name: str) -> Any:
|
||||
if name in _IMPORTS:
|
||||
package_name, package_extra = _IMPORTS[name]
|
||||
import_path, package_name = _IMPORTS[name]
|
||||
try:
|
||||
return getattr(importlib.import_module(package_name), name)
|
||||
return getattr(importlib.import_module(import_path), name)
|
||||
except ModuleNotFoundError as exc:
|
||||
raise ModuleNotFoundError(
|
||||
f"please use `pip install agent-framework-{package_extra}`, "
|
||||
"or update your requirements.txt or pyproject.toml file."
|
||||
f"The package {package_name} is required to use `{name}`. "
|
||||
f"Please use `pip install {package_name}`, or update your requirements.txt or pyproject.toml file."
|
||||
) from exc
|
||||
raise AttributeError(f"Module `azure` has no attribute {name}.")
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
from agent_framework_azure_ai import AzureAIAgentClient, AzureAIClient, AzureAISettings
|
||||
from agent_framework_azure_ai_search import AzureAISearchContextProvider, AzureAISearchSettings
|
||||
from agent_framework_azurefunctions import (
|
||||
AgentCallbackContext,
|
||||
AgentFunctionApp,
|
||||
@@ -20,6 +21,8 @@ __all__ = [
|
||||
"AgentResponseCallbackProtocol",
|
||||
"AzureAIAgentClient",
|
||||
"AzureAIClient",
|
||||
"AzureAISearchContextProvider",
|
||||
"AzureAISearchSettings",
|
||||
"AzureAISettings",
|
||||
"AzureOpenAIAssistantsClient",
|
||||
"AzureOpenAIChatClient",
|
||||
|
||||
@@ -3,20 +3,20 @@
|
||||
import importlib
|
||||
from typing import Any
|
||||
|
||||
PACKAGE_NAME = "agent_framework_chatkit"
|
||||
PACKAGE_EXTRA = "chatkit"
|
||||
IMPORT_PATH = "agent_framework_chatkit"
|
||||
PACKAGE_NAME = "agent-framework-chatkit"
|
||||
_IMPORTS = ["__version__", "ThreadItemConverter", "simple_to_agent_input", "stream_agent_response"]
|
||||
|
||||
|
||||
def __getattr__(name: str) -> Any:
|
||||
if name in _IMPORTS:
|
||||
try:
|
||||
return getattr(importlib.import_module(PACKAGE_NAME), name)
|
||||
return getattr(importlib.import_module(IMPORT_PATH), name)
|
||||
except ModuleNotFoundError as exc:
|
||||
raise ModuleNotFoundError(
|
||||
f"The '{PACKAGE_EXTRA}' extra is not installed, please do `pip install agent-framework-{PACKAGE_EXTRA}`"
|
||||
f"The '{PACKAGE_NAME}' package is not installed, please do `pip install {PACKAGE_NAME}`"
|
||||
) from exc
|
||||
raise AttributeError(f"Module {PACKAGE_NAME} has no attribute {name}.")
|
||||
raise AttributeError(f"Module {IMPORT_PATH} has no attribute {name}.")
|
||||
|
||||
|
||||
def __dir__() -> list[str]:
|
||||
|
||||
@@ -7,4 +7,9 @@ from agent_framework_chatkit import (
|
||||
stream_agent_response,
|
||||
)
|
||||
|
||||
__all__ = ["ThreadItemConverter", "__version__", "simple_to_agent_input", "stream_agent_response"]
|
||||
__all__ = [
|
||||
"ThreadItemConverter",
|
||||
"__version__",
|
||||
"simple_to_agent_input",
|
||||
"stream_agent_response",
|
||||
]
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
import importlib
|
||||
from typing import Any
|
||||
|
||||
PACKAGE_NAME = "agent_framework_devui"
|
||||
PACKAGE_EXTRA = "devui"
|
||||
IMPORT_PATH = "agent_framework_devui"
|
||||
PACKAGE_NAME = "agent-framework-devui"
|
||||
_IMPORTS = [
|
||||
"AgentFrameworkRequest",
|
||||
"DevServer",
|
||||
@@ -22,12 +22,12 @@ _IMPORTS = [
|
||||
def __getattr__(name: str) -> Any:
|
||||
if name in _IMPORTS:
|
||||
try:
|
||||
return getattr(importlib.import_module(PACKAGE_NAME), name)
|
||||
return getattr(importlib.import_module(IMPORT_PATH), name)
|
||||
except ModuleNotFoundError as exc:
|
||||
raise ModuleNotFoundError(
|
||||
f"The '{PACKAGE_EXTRA}' extra is not installed, please do `pip install agent-framework-{PACKAGE_EXTRA}`"
|
||||
f"The '{PACKAGE_NAME}' package is not installed, please do `pip install {PACKAGE_NAME}`"
|
||||
) from exc
|
||||
raise AttributeError(f"Module {PACKAGE_NAME} has no attribute {name}.")
|
||||
raise AttributeError(f"Module {IMPORT_PATH} has no attribute {name}.")
|
||||
|
||||
|
||||
def __dir__() -> list[str]:
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
from agent_framework_devui import (
|
||||
AgentFrameworkRequest,
|
||||
DevServer,
|
||||
|
||||
@@ -3,20 +3,20 @@
|
||||
import importlib
|
||||
from typing import Any
|
||||
|
||||
PACKAGE_NAME = "agent_framework_mem0"
|
||||
PACKAGE_EXTRA = "mem0"
|
||||
IMPORT_PATH = "agent_framework_mem0"
|
||||
PACKAGE_NAME = "agent-framework-mem0"
|
||||
_IMPORTS = ["__version__", "Mem0Provider"]
|
||||
|
||||
|
||||
def __getattr__(name: str) -> Any:
|
||||
if name in _IMPORTS:
|
||||
try:
|
||||
return getattr(importlib.import_module(PACKAGE_NAME), name)
|
||||
return getattr(importlib.import_module(IMPORT_PATH), name)
|
||||
except ModuleNotFoundError as exc:
|
||||
raise ModuleNotFoundError(
|
||||
f"The '{PACKAGE_EXTRA}' extra is not installed, please do `pip install agent-framework-{PACKAGE_EXTRA}`"
|
||||
f"The '{PACKAGE_NAME}' package is not installed, please do `pip install {PACKAGE_NAME}`"
|
||||
) from exc
|
||||
raise AttributeError(f"Module {PACKAGE_NAME} has no attribute {name}.")
|
||||
raise AttributeError(f"Module {IMPORT_PATH} has no attribute {name}.")
|
||||
|
||||
|
||||
def __dir__() -> list[str]:
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
from agent_framework_mem0 import Mem0Provider, __version__
|
||||
from agent_framework_mem0 import (
|
||||
Mem0Provider,
|
||||
__version__,
|
||||
)
|
||||
|
||||
__all__ = ["Mem0Provider", "__version__"]
|
||||
__all__ = [
|
||||
"Mem0Provider",
|
||||
"__version__",
|
||||
]
|
||||
|
||||
@@ -3,35 +3,33 @@
|
||||
import importlib
|
||||
from typing import Any
|
||||
|
||||
_IMPORTS: dict[str, tuple[str, list[str]]] = {
|
||||
"CopilotStudioAgent": ("agent_framework_copilotstudio", ["microsoft-copilotstudio", "copilotstudio"]),
|
||||
"__version__": ("agent_framework_copilotstudio", ["microsoft-copilotstudio", "copilotstudio"]),
|
||||
"acquire_token": ("agent_framework_copilotstudio", ["microsoft-copilotstudio", "copilotstudio"]),
|
||||
# Purview (Graph Data Security & Governance) integration exports
|
||||
"PurviewPolicyMiddleware": ("agent_framework_purview", ["microsoft-purview", "purview"]),
|
||||
"PurviewChatPolicyMiddleware": ("agent_framework_purview", ["microsoft-purview", "purview"]),
|
||||
"PurviewSettings": ("agent_framework_purview", ["microsoft-purview", "purview"]),
|
||||
"PurviewAppLocation": ("agent_framework_purview", ["microsoft-purview", "purview"]),
|
||||
"PurviewLocationType": ("agent_framework_purview", ["microsoft-purview", "purview"]),
|
||||
"PurviewAuthenticationError": ("agent_framework_purview", ["microsoft-purview", "purview"]),
|
||||
"PurviewPaymentRequiredError": ("agent_framework_purview", ["microsoft-purview", "purview"]),
|
||||
"PurviewRateLimitError": ("agent_framework_purview", ["microsoft-purview", "purview"]),
|
||||
"PurviewRequestError": ("agent_framework_purview", ["microsoft-purview", "purview"]),
|
||||
"PurviewServiceError": ("agent_framework_purview", ["microsoft-purview", "purview"]),
|
||||
"CacheProvider": ("agent_framework_purview", ["microsoft-purview", "purview"]),
|
||||
_IMPORTS: dict[str, tuple[str, str]] = {
|
||||
"CopilotStudioAgent": ("agent_framework_copilotstudio", "agent-framework-copilotstudio"),
|
||||
"__version__": ("agent_framework_copilotstudio", "agent-framework-copilotstudio"),
|
||||
"acquire_token": ("agent_framework_copilotstudio", "agent-framework-copilotstudio"),
|
||||
"PurviewPolicyMiddleware": ("agent_framework_purview", "agent-framework-purview"),
|
||||
"PurviewChatPolicyMiddleware": ("agent_framework_purview", "agent-framework-purview"),
|
||||
"PurviewSettings": ("agent_framework_purview", "agent-framework-purview"),
|
||||
"PurviewAppLocation": ("agent_framework_purview", "agent-framework-purview"),
|
||||
"PurviewLocationType": ("agent_framework_purview", "agent-framework-purview"),
|
||||
"PurviewAuthenticationError": ("agent_framework_purview", "agent-framework-purview"),
|
||||
"PurviewPaymentRequiredError": ("agent_framework_purview", "agent-framework-purview"),
|
||||
"PurviewRateLimitError": ("agent_framework_purview", "agent-framework-purview"),
|
||||
"PurviewRequestError": ("agent_framework_purview", "agent-framework-purview"),
|
||||
"PurviewServiceError": ("agent_framework_purview", "agent-framework-purview"),
|
||||
"CacheProvider": ("agent_framework_purview", "agent-framework-purview"),
|
||||
}
|
||||
|
||||
|
||||
def __getattr__(name: str) -> Any:
|
||||
if name in _IMPORTS:
|
||||
package_name, package_extra = _IMPORTS[name]
|
||||
import_path, package_name = _IMPORTS[name]
|
||||
try:
|
||||
return getattr(importlib.import_module(package_name), name)
|
||||
return getattr(importlib.import_module(import_path), name)
|
||||
except ModuleNotFoundError as exc:
|
||||
raise ModuleNotFoundError(
|
||||
f"The {' or '.join(package_extra)} extra is not installed, "
|
||||
f"please use `pip install agent-framework-{package_extra[0]}`, "
|
||||
"or update your requirements.txt or pyproject.toml file."
|
||||
f"The package {package_name} is required to use `{name}`. "
|
||||
f"Please use `pip install {package_name}`, or update your requirements.txt or pyproject.toml file."
|
||||
) from exc
|
||||
raise AttributeError(f"Module `microsoft` has no attribute {name}.")
|
||||
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
from agent_framework_copilotstudio import CopilotStudioAgent, __version__, acquire_token
|
||||
from agent_framework_copilotstudio import (
|
||||
CopilotStudioAgent,
|
||||
__version__,
|
||||
acquire_token,
|
||||
)
|
||||
from agent_framework_purview import (
|
||||
CacheProvider,
|
||||
PurviewAppLocation,
|
||||
|
||||
@@ -46,9 +46,7 @@ RESPONSE_TYPE = Union[
|
||||
OPTION_TYPE = Union[ChatOptions, dict[str, Any]]
|
||||
|
||||
|
||||
__all__ = [
|
||||
"OpenAISettings",
|
||||
]
|
||||
__all__ = ["OpenAISettings"]
|
||||
|
||||
|
||||
def _check_openai_version_for_callable_api_key() -> None:
|
||||
|
||||
@@ -3,20 +3,20 @@
|
||||
import importlib
|
||||
from typing import Any
|
||||
|
||||
PACKAGE_NAME = "agent_framework_redis"
|
||||
PACKAGE_EXTRA = "redis"
|
||||
IMPORT_PATH = "agent_framework_redis"
|
||||
PACKAGE_NAME = "agent-framework-redis"
|
||||
_IMPORTS = ["__version__", "RedisProvider", "RedisChatMessageStore"]
|
||||
|
||||
|
||||
def __getattr__(name: str) -> Any:
|
||||
if name in _IMPORTS:
|
||||
try:
|
||||
return getattr(importlib.import_module(PACKAGE_NAME), name)
|
||||
return getattr(importlib.import_module(IMPORT_PATH), name)
|
||||
except ModuleNotFoundError as exc:
|
||||
raise ModuleNotFoundError(
|
||||
f"The '{PACKAGE_EXTRA}' extra is not installed, please do `pip install agent-framework-{PACKAGE_EXTRA}`"
|
||||
f"The '{PACKAGE_NAME}' package is not installed, please do `pip install {PACKAGE_NAME}`"
|
||||
) from exc
|
||||
raise AttributeError(f"Module {PACKAGE_NAME} has no attribute {name}.")
|
||||
raise AttributeError(f"Module {IMPORT_PATH} has no attribute {name}.")
|
||||
|
||||
|
||||
def __dir__() -> list[str]:
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
from agent_framework_redis import RedisChatMessageStore, RedisProvider, __version__
|
||||
from agent_framework_redis import (
|
||||
RedisChatMessageStore,
|
||||
RedisProvider,
|
||||
__version__,
|
||||
)
|
||||
|
||||
__all__ = ["RedisChatMessageStore", "RedisProvider", "__version__"]
|
||||
__all__ = [
|
||||
"RedisChatMessageStore",
|
||||
"RedisProvider",
|
||||
"__version__",
|
||||
]
|
||||
|
||||
@@ -43,7 +43,7 @@ dependencies = [
|
||||
all = [
|
||||
"agent-framework-a2a",
|
||||
"agent-framework-ag-ui",
|
||||
"agent-framework-aisearch",
|
||||
"agent-framework-azure-ai-search",
|
||||
"agent-framework-anthropic",
|
||||
"agent-framework-azure-ai",
|
||||
"agent-framework-azurefunctions",
|
||||
|
||||
@@ -81,7 +81,7 @@ agent-framework = { workspace = true }
|
||||
agent-framework-core = { workspace = true }
|
||||
agent-framework-a2a = { workspace = true }
|
||||
agent-framework-ag-ui = { workspace = true }
|
||||
agent-framework-aisearch = { workspace = true }
|
||||
agent-framework-azure-ai-search = { workspace = true }
|
||||
agent-framework-anthropic = { workspace = true }
|
||||
agent-framework-azure-ai = { workspace = true }
|
||||
agent-framework-azurefunctions = { workspace = true }
|
||||
|
||||
@@ -20,6 +20,8 @@ This folder contains examples demonstrating different ways to create and use age
|
||||
| [`azure_ai_with_file_search.py`](azure_ai_with_file_search.py) | Shows how to use the `HostedFileSearchTool` with Azure AI agents to upload files, create vector stores, and enable agents to search through uploaded documents to answer user questions. |
|
||||
| [`azure_ai_with_hosted_mcp.py`](azure_ai_with_hosted_mcp.py) | Shows how to integrate hosted Model Context Protocol (MCP) tools with Azure AI Agent. |
|
||||
| [`azure_ai_with_response_format.py`](azure_ai_with_response_format.py) | Shows how to use structured outputs (response format) with Azure AI agents using Pydantic models to enforce specific response schemas. |
|
||||
| [`azure_ai_with_search_context_agentic.py`](../../context_providers/azure_ai_search/azure_ai_with_search_context_agentic.py) | Shows how to use AzureAISearchContextProvider with agentic mode. Uses Knowledge Bases for multi-hop reasoning across documents with query planning. Recommended for most scenarios - slightly slower with more token consumption for query planning, but more accurate results. |
|
||||
| [`azure_ai_with_search_context_semantic.py`](../../context_providers/azure_ai_search/azure_ai_with_search_context_semantic.py) | Shows how to use AzureAISearchContextProvider with semantic mode. Fast hybrid search with vector + keyword search and semantic ranking for RAG. Best for simple queries where speed is critical. |
|
||||
| [`azure_ai_with_sharepoint.py`](azure_ai_with_sharepoint.py) | Shows how to use SharePoint grounding with Azure AI agents to search through SharePoint content and answer user questions with proper citations. Requires a SharePoint connection configured in your Azure AI project. |
|
||||
| [`azure_ai_with_thread.py`](azure_ai_with_thread.py) | Demonstrates thread management with Azure AI agents, including automatic thread creation for stateless conversations and explicit thread management for maintaining conversation context across multiple interactions. |
|
||||
| [`azure_ai_with_image_generation.py`](azure_ai_with_image_generation.py) | Shows how to use the `ImageGenTool` with Azure AI agents to generate images based on text prompts. |
|
||||
|
||||
@@ -20,8 +20,6 @@ This folder contains examples demonstrating different ways to create and use age
|
||||
| [`azure_ai_with_local_mcp.py`](azure_ai_with_local_mcp.py) | Shows how to integrate Azure AI agents with local Model Context Protocol (MCP) servers for enhanced functionality and tool integration. Demonstrates both agent-level and run-level tool configuration. |
|
||||
| [`azure_ai_with_multiple_tools.py`](azure_ai_with_multiple_tools.py) | Demonstrates how to use multiple tools together with Azure AI agents, including web search, MCP servers, and function tools. Shows coordinated multi-tool interactions and approval workflows. |
|
||||
| [`azure_ai_with_openapi_tools.py`](azure_ai_with_openapi_tools.py) | Demonstrates how to use OpenAPI tools with Azure AI agents to integrate external REST APIs. Shows OpenAPI specification loading, anonymous authentication, thread context management, and coordinated multi-API conversations using weather and countries APIs. |
|
||||
| [`azure_ai_with_search_context_agentic.py`](azure_ai_with_search_context_agentic.py) | Shows how to use AzureAISearchContextProvider with agentic mode. Uses Knowledge Bases for multi-hop reasoning across documents with query planning. Recommended for most scenarios - slightly slower with more token consumption for query planning, but more accurate results. |
|
||||
| [`azure_ai_with_search_context_semantic.py`](azure_ai_with_search_context_semantic.py) | Shows how to use AzureAISearchContextProvider with semantic mode. Fast hybrid search with vector + keyword search and semantic ranking for RAG. Best for simple queries where speed is critical. |
|
||||
| [`azure_ai_with_thread.py`](azure_ai_with_thread.py) | Demonstrates thread management with Azure AI agents, including automatic thread creation for stateless conversations and explicit thread management for maintaining conversation context across multiple interactions. |
|
||||
|
||||
## Environment Variables
|
||||
|
||||
@@ -0,0 +1,179 @@
|
||||
# Context Provider Examples
|
||||
|
||||
Context providers enable agents to maintain memory, retrieve relevant information, and enhance conversations with external context. The Agent Framework supports various context providers for different use cases, from simple in-memory storage to advanced persistent solutions with search capabilities.
|
||||
|
||||
This folder contains examples demonstrating how to use different context providers with the Agent Framework.
|
||||
|
||||
## Overview
|
||||
|
||||
Context providers implement two key methods:
|
||||
|
||||
- **`invoking`**: Called before the agent processes a request. Provides additional context, instructions, or retrieved information to enhance the agent's response.
|
||||
- **`invoked`**: Called after the agent generates a response. Allows for storing information, updating memory, or performing post-processing.
|
||||
|
||||
## Examples
|
||||
|
||||
### Simple Context Provider
|
||||
|
||||
| File | Description | Installation |
|
||||
|------|-------------|--------------|
|
||||
| [`simple_context_provider.py`](simple_context_provider.py) | Demonstrates building a custom context provider that extracts and stores user information (name and age) from conversations. Shows how to use structured output to extract data and provide dynamic instructions based on stored context. | No additional package required - uses core `agent-framework` |
|
||||
|
||||
**Install:**
|
||||
```bash
|
||||
pip install agent-framework-azure-ai
|
||||
```
|
||||
|
||||
### Azure AI Search
|
||||
|
||||
| File | Description |
|
||||
|------|-------------|
|
||||
| [`azure_ai_search/azure_ai_with_search_context_agentic.py`](azure_ai_search/azure_ai_with_search_context_agentic.py) | **Agentic mode** (recommended for most scenarios): Uses Knowledge Bases in Azure AI Search for query planning and multi-hop reasoning. Provides more accurate results through intelligent retrieval. Slightly slower with more token consumption. |
|
||||
| [`azure_ai_search/azure_ai_with_search_context_semantic.py`](azure_ai_search/azure_ai_with_search_context_semantic.py) | **Semantic mode** (fast queries): Fast hybrid search combining vector and keyword search with semantic ranking. Best for scenarios where speed is critical. |
|
||||
|
||||
**Install:**
|
||||
```bash
|
||||
pip install agent-framework-azure-ai-search agent-framework-azure-ai
|
||||
```
|
||||
|
||||
**Prerequisites:**
|
||||
- Azure AI Search service with a search index
|
||||
- Azure AI Foundry project with a model deployment
|
||||
- For agentic mode: Azure OpenAI resource for Knowledge Base model calls
|
||||
- Environment variables: `AZURE_SEARCH_ENDPOINT`, `AZURE_SEARCH_INDEX_NAME`, `AZURE_AI_PROJECT_ENDPOINT`
|
||||
|
||||
**Key Concepts:**
|
||||
- **Agentic mode**: Intelligent retrieval with multi-hop reasoning, better for complex queries
|
||||
- **Semantic mode**: Fast hybrid search with semantic ranking, better for simple queries and speed
|
||||
|
||||
### Mem0
|
||||
|
||||
The [mem0](mem0/) folder contains examples using Mem0, a self-improving memory layer that enables applications to have long-term memory capabilities.
|
||||
|
||||
| File | Description |
|
||||
|------|-------------|
|
||||
| [`mem0/mem0_basic.py`](mem0/mem0_basic.py) | Basic example storing and retrieving user preferences across different conversation threads. |
|
||||
| [`mem0/mem0_threads.py`](mem0/mem0_threads.py) | Advanced thread scoping strategies: global scope (memories shared), per-operation scope (memories isolated), and multiple agents with different memory configurations. |
|
||||
| [`mem0/mem0_oss.py`](mem0/mem0_oss.py) | Using Mem0 Open Source self-hosted version as the context provider. |
|
||||
|
||||
**Install:**
|
||||
```bash
|
||||
pip install agent-framework-mem0
|
||||
```
|
||||
|
||||
**Prerequisites:**
|
||||
- Mem0 API key from [app.mem0.ai](https://app.mem0.ai/) OR self-host [Mem0 Open Source](https://docs.mem0.ai/open-source/overview)
|
||||
- For Mem0 Platform: `MEM0_API_KEY` environment variable
|
||||
- For Mem0 OSS: `OPENAI_API_KEY` for embedding generation
|
||||
|
||||
**Key Concepts:**
|
||||
- **Global Scope**: Memories shared across all conversation threads
|
||||
- **Thread Scope**: Memories isolated per conversation thread
|
||||
- **Memory Association**: Records can be associated with `user_id`, `agent_id`, `thread_id`, or `application_id`
|
||||
|
||||
See the [mem0 README](mem0/README.md) for detailed documentation.
|
||||
|
||||
### Redis
|
||||
|
||||
The [redis](redis/) folder contains examples using Redis (RediSearch) for persistent, searchable memory with full-text and optional hybrid vector search.
|
||||
|
||||
| File | Description |
|
||||
|------|-------------|
|
||||
| [`redis/redis_basics.py`](redis/redis_basics.py) | Standalone provider usage and agent integration. Demonstrates writing messages, full-text/hybrid search, persisting preferences, and tool output memory. |
|
||||
| [`redis/redis_conversation.py`](redis/redis_conversation.py) | Conversational examples showing memory persistence across sessions. |
|
||||
| [`redis/redis_threads.py`](redis/redis_threads.py) | Thread scoping: global scope, per-operation scope, and multiple agents with isolated memory via different `agent_id` values. |
|
||||
|
||||
**Install:**
|
||||
```bash
|
||||
pip install agent-framework-redis
|
||||
```
|
||||
|
||||
**Prerequisites:**
|
||||
- Running Redis with RediSearch (Redis Stack or managed service)
|
||||
- **Docker**: `docker run --name redis -p 6379:6379 -d redis:8.0.3`
|
||||
- **Redis Cloud**: [redis.io/cloud](https://redis.io/cloud/)
|
||||
- **Azure Managed Redis**: [Azure quickstart](https://learn.microsoft.com/azure/redis/quickstart-create-managed-redis)
|
||||
- Optional: `OPENAI_API_KEY` for vector embeddings (hybrid search)
|
||||
|
||||
**Key Concepts:**
|
||||
- **Full-text search**: Fast keyword-based retrieval
|
||||
- **Hybrid vector search**: Optional embeddings for semantic search (`vectorizer_choice="openai"` or `"hf"`)
|
||||
- **Memory scoping**: Partition by `application_id`, `agent_id`, `user_id`, or `thread_id`
|
||||
- **Thread scoping**: `scope_to_per_operation_thread_id=True` isolates memory per operation
|
||||
|
||||
See the [redis README](redis/README.md) for detailed documentation.
|
||||
|
||||
## Choosing a Context Provider
|
||||
|
||||
| Provider | Use Case | Persistence | Search | Complexity |
|
||||
|----------|----------|-------------|--------|------------|
|
||||
| **Simple/Custom** | Learning, prototyping, simple memory needs | No (in-memory) | No | Low |
|
||||
| **Azure AI Search** | RAG, document search, enterprise knowledge bases | Yes | Hybrid + Semantic | Medium |
|
||||
| **Mem0** | Long-term user memory, preferences, personalization | Yes (cloud/self-hosted) | Semantic | Low-Medium |
|
||||
| **Redis** | Fast retrieval, session memory, full-text + vector search | Yes | Full-text + Hybrid | Medium |
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### 1. User Preference Memory
|
||||
Store and retrieve user preferences, settings, or personal information across sessions.
|
||||
- **Examples**: `simple_context_provider.py`, `mem0/mem0_basic.py`, `redis/redis_basics.py`
|
||||
|
||||
### 2. Document Retrieval (RAG)
|
||||
Retrieve relevant documents or knowledge base articles to answer questions.
|
||||
- **Examples**: `azure_ai_search/azure_ai_with_search_context_*.py`
|
||||
|
||||
### 3. Conversation History
|
||||
Maintain conversation context across multiple turns and sessions.
|
||||
- **Examples**: `redis/redis_conversation.py`, `mem0/mem0_threads.py`
|
||||
|
||||
### 4. Thread Scoping
|
||||
Isolate memory per conversation thread or share globally across threads.
|
||||
- **Examples**: `mem0/mem0_threads.py`, `redis/redis_threads.py`
|
||||
|
||||
### 5. Multi-Agent Memory
|
||||
Different agents with isolated or shared memory configurations.
|
||||
- **Examples**: `mem0/mem0_threads.py`, `redis/redis_threads.py`
|
||||
|
||||
## Building Custom Context Providers
|
||||
|
||||
To create a custom context provider, implement the `ContextProvider` protocol:
|
||||
|
||||
```python
|
||||
from agent_framework import ContextProvider, Context, ChatMessage
|
||||
from collections.abc import MutableSequence, Sequence
|
||||
from typing import Any
|
||||
|
||||
class MyContextProvider(ContextProvider):
|
||||
async def invoking(
|
||||
self,
|
||||
messages: ChatMessage | MutableSequence[ChatMessage],
|
||||
**kwargs: Any
|
||||
) -> Context:
|
||||
"""Provide context before the agent processes the request."""
|
||||
# Return additional instructions, messages, or context
|
||||
return Context(instructions="Additional instructions here")
|
||||
|
||||
async def invoked(
|
||||
self,
|
||||
request_messages: ChatMessage | Sequence[ChatMessage],
|
||||
response_messages: ChatMessage | Sequence[ChatMessage] | None = None,
|
||||
invoke_exception: Exception | None = None,
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
"""Process the response after the agent generates it."""
|
||||
# Store information, update memory, etc.
|
||||
pass
|
||||
|
||||
def serialize(self) -> str:
|
||||
"""Serialize the provider state for persistence."""
|
||||
return "{}"
|
||||
```
|
||||
|
||||
See `simple_context_provider.py` for a complete example.
|
||||
|
||||
## Additional Resources
|
||||
|
||||
- [Agent Framework Documentation](https://github.com/microsoft/agent-framework)
|
||||
- [Azure AI Search Documentation](https://learn.microsoft.com/azure/search/)
|
||||
- [Mem0 Documentation](https://docs.mem0.ai/)
|
||||
- [Redis Documentation](https://redis.io/docs/)
|
||||
@@ -0,0 +1,264 @@
|
||||
# Azure AI Search Context Provider Examples
|
||||
|
||||
Azure AI Search context provider enables Retrieval Augmented Generation (RAG) with your agents by retrieving relevant documents from Azure AI Search indexes. It supports two search modes optimized for different use cases.
|
||||
|
||||
This folder contains examples demonstrating how to use the Azure AI Search context provider with the Agent Framework.
|
||||
|
||||
## Examples
|
||||
|
||||
| File | Description |
|
||||
|------|-------------|
|
||||
| [`azure_ai_with_search_context_agentic.py`](azure_ai_with_search_context_agentic.py) | **Agentic mode** (recommended for most scenarios): Uses Knowledge Bases in Azure AI Search for query planning and multi-hop reasoning. Provides more accurate results through intelligent retrieval with automatic query reformulation. Slightly slower with more token consumption for query planning. [Learn more](https://techcommunity.microsoft.com/blog/azure-ai-foundry-blog/foundry-iq-boost-response-relevance-by-36-with-agentic-retrieval/4470720) |
|
||||
| [`azure_ai_with_search_context_semantic.py`](azure_ai_with_search_context_semantic.py) | **Semantic mode** (fast queries): Fast hybrid search combining vector and keyword search with semantic ranking. Returns raw search results as context. Best for scenarios where speed is critical and simple retrieval is sufficient. |
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
pip install agent-framework-azure-ai-search agent-framework-azure-ai
|
||||
```
|
||||
|
||||
## Prerequisites
|
||||
|
||||
### Required Resources
|
||||
|
||||
1. **Azure AI Search service** with a search index containing your documents
|
||||
- [Create Azure AI Search service](https://learn.microsoft.com/azure/search/search-create-service-portal)
|
||||
- [Create and populate a search index](https://learn.microsoft.com/azure/search/search-what-is-an-index)
|
||||
|
||||
2. **Azure AI Foundry project** with a model deployment
|
||||
- [Create Azure AI Foundry project](https://learn.microsoft.com/azure/ai-studio/how-to/create-projects)
|
||||
- Deploy a model (e.g., GPT-4o)
|
||||
|
||||
3. **For Agentic mode only**: Azure OpenAI resource for Knowledge Base model calls
|
||||
- [Create Azure OpenAI resource](https://learn.microsoft.com/azure/ai-services/openai/how-to/create-resource)
|
||||
- Note: This is separate from your Azure AI Foundry project endpoint
|
||||
|
||||
### Authentication
|
||||
|
||||
Both examples support two authentication methods:
|
||||
|
||||
- **API Key**: Set `AZURE_SEARCH_API_KEY` environment variable
|
||||
- **Entra ID (Managed Identity)**: Uses `DefaultAzureCredential` when API key is not provided
|
||||
|
||||
Run `az login` if using Entra ID authentication.
|
||||
|
||||
## Configuration
|
||||
|
||||
### Environment Variables
|
||||
|
||||
**Common (both modes):**
|
||||
- `AZURE_SEARCH_ENDPOINT`: Your Azure AI Search endpoint (e.g., `https://myservice.search.windows.net`)
|
||||
- `AZURE_SEARCH_INDEX_NAME`: Name of your search index
|
||||
- `AZURE_AI_PROJECT_ENDPOINT`: Your Azure AI Foundry project endpoint
|
||||
- `AZURE_AI_MODEL_DEPLOYMENT_NAME`: Model deployment name (e.g., `gpt-4o`, defaults to `gpt-4o`)
|
||||
- `AZURE_SEARCH_API_KEY`: _(Optional)_ Your search API key - if not provided, uses DefaultAzureCredential
|
||||
|
||||
**Agentic mode only:**
|
||||
- `AZURE_SEARCH_KNOWLEDGE_BASE_NAME`: Name of your Knowledge Base in Azure AI Search
|
||||
- `AZURE_OPENAI_RESOURCE_URL`: Your Azure OpenAI resource URL (e.g., `https://myresource.openai.azure.com`)
|
||||
- **Important**: This is different from `AZURE_AI_PROJECT_ENDPOINT` - Knowledge Base needs the OpenAI endpoint for model calls
|
||||
|
||||
### Example .env file
|
||||
|
||||
**For Semantic Mode:**
|
||||
```env
|
||||
AZURE_SEARCH_ENDPOINT=https://myservice.search.windows.net
|
||||
AZURE_SEARCH_INDEX_NAME=my-index
|
||||
AZURE_AI_PROJECT_ENDPOINT=https://myproject.api.azureml.ms
|
||||
AZURE_AI_MODEL_DEPLOYMENT_NAME=gpt-4o
|
||||
# Optional - omit to use Entra ID
|
||||
AZURE_SEARCH_API_KEY=your-search-key
|
||||
```
|
||||
|
||||
**For Agentic Mode (add these to semantic mode variables):**
|
||||
```env
|
||||
AZURE_SEARCH_KNOWLEDGE_BASE_NAME=my-knowledge-base
|
||||
AZURE_OPENAI_RESOURCE_URL=https://myresource.openai.azure.com
|
||||
```
|
||||
|
||||
## Search Modes Comparison
|
||||
|
||||
| Feature | Semantic Mode | Agentic Mode |
|
||||
|---------|--------------|--------------|
|
||||
| **Speed** | Fast | Slower (query planning overhead) |
|
||||
| **Token Usage** | Lower | Higher (query reformulation) |
|
||||
| **Retrieval Strategy** | Hybrid search + semantic ranking | Multi-hop reasoning with Knowledge Base |
|
||||
| **Query Handling** | Direct search | Automatic query reformulation |
|
||||
| **Best For** | Simple queries, speed-critical apps | Complex queries, multi-document reasoning |
|
||||
| **Additional Setup** | None | Requires Knowledge Base + OpenAI resource |
|
||||
|
||||
### When to Use Semantic Mode
|
||||
|
||||
- **Simple queries** where direct keyword/vector search is sufficient
|
||||
- **Speed is critical** and you need low latency
|
||||
- **Straightforward retrieval** from single documents
|
||||
- **Lower token costs** are important
|
||||
|
||||
### When to Use Agentic Mode
|
||||
|
||||
- **Complex queries** requiring multi-hop reasoning
|
||||
- **Cross-document analysis** where information spans multiple sources
|
||||
- **Ambiguous queries** that benefit from automatic reformulation
|
||||
- **Higher accuracy** is more important than speed
|
||||
- You need **intelligent query planning** and document synthesis
|
||||
|
||||
## How the Examples Work
|
||||
|
||||
### Semantic Mode Flow
|
||||
|
||||
1. User query is sent to Azure AI Search
|
||||
2. Hybrid search (vector + keyword) retrieves relevant documents
|
||||
3. Semantic ranking reorders results for relevance
|
||||
4. Top-k documents are returned as context
|
||||
5. Agent generates response using retrieved context
|
||||
|
||||
### Agentic Mode Flow
|
||||
|
||||
1. User query is sent to the Knowledge Base
|
||||
2. Knowledge Base plans the retrieval strategy
|
||||
3. Multiple search queries may be executed (multi-hop)
|
||||
4. Retrieved information is synthesized
|
||||
5. Enhanced context is provided to the agent
|
||||
6. Agent generates response with comprehensive context
|
||||
|
||||
## Code Example
|
||||
|
||||
### Semantic Mode
|
||||
|
||||
```python
|
||||
from agent_framework import ChatAgent
|
||||
from agent_framework.azure import AzureAIAgentClient, AzureAISearchContextProvider
|
||||
from azure.identity.aio import DefaultAzureCredential
|
||||
|
||||
# Create search provider with semantic mode (default)
|
||||
search_provider = AzureAISearchContextProvider(
|
||||
endpoint=search_endpoint,
|
||||
index_name=index_name,
|
||||
api_key=search_key, # Or use credential for Entra ID
|
||||
mode="semantic", # Default mode
|
||||
top_k=3, # Number of documents to retrieve
|
||||
)
|
||||
|
||||
# Create agent with search context
|
||||
async with AzureAIAgentClient(async_credential=DefaultAzureCredential()) as client:
|
||||
async with ChatAgent(
|
||||
chat_client=client,
|
||||
model=model_deployment,
|
||||
context_providers=search_provider,
|
||||
) as agent:
|
||||
response = await agent.run("What information is in the knowledge base?")
|
||||
```
|
||||
|
||||
### Agentic Mode
|
||||
|
||||
```python
|
||||
from agent_framework.azure import AzureAISearchContextProvider
|
||||
|
||||
# Create search provider with agentic mode
|
||||
search_provider = AzureAISearchContextProvider(
|
||||
endpoint=search_endpoint,
|
||||
index_name=index_name,
|
||||
api_key=search_key,
|
||||
mode="agentic", # Enable agentic retrieval
|
||||
knowledge_base_name=knowledge_base_name,
|
||||
azure_openai_resource_url=azure_openai_resource_url,
|
||||
top_k=5,
|
||||
)
|
||||
|
||||
# Use with agent (same as semantic mode)
|
||||
async with ChatAgent(
|
||||
chat_client=client,
|
||||
model=model_deployment,
|
||||
context_providers=search_provider,
|
||||
) as agent:
|
||||
response = await agent.run("Analyze and compare topics across documents")
|
||||
```
|
||||
|
||||
## Running the Examples
|
||||
|
||||
1. **Set up environment variables** (see Configuration section above)
|
||||
|
||||
2. **Ensure you have an Azure AI Search index** with documents:
|
||||
```bash
|
||||
# Verify your index exists
|
||||
curl -X GET "https://myservice.search.windows.net/indexes/my-index?api-version=2024-07-01" \
|
||||
-H "api-key: YOUR_API_KEY"
|
||||
```
|
||||
|
||||
3. **For agentic mode**: Create a Knowledge Base in Azure AI Search
|
||||
- [Knowledge Base documentation](https://learn.microsoft.com/azure/search/knowledge-store-create-portal)
|
||||
|
||||
4. **Run the examples**:
|
||||
```bash
|
||||
# Semantic mode (fast, simple)
|
||||
python azure_ai_with_search_context_semantic.py
|
||||
|
||||
# Agentic mode (intelligent, complex)
|
||||
python azure_ai_with_search_context_agentic.py
|
||||
```
|
||||
|
||||
## Key Parameters
|
||||
|
||||
### Common Parameters
|
||||
|
||||
- `endpoint`: Azure AI Search service endpoint
|
||||
- `index_name`: Name of the search index
|
||||
- `api_key`: API key for authentication (optional, can use credential instead)
|
||||
- `credential`: Azure credential for Entra ID auth (e.g., `DefaultAzureCredential()`)
|
||||
- `mode`: Search mode - `"semantic"` (default) or `"agentic"`
|
||||
- `top_k`: Number of documents to retrieve (default: 3 for semantic, 5 for agentic)
|
||||
|
||||
### Semantic Mode Parameters
|
||||
|
||||
- `semantic_configuration`: Name of semantic configuration in your index (optional)
|
||||
- `query_type`: Query type - `"semantic"` for semantic search (default)
|
||||
|
||||
### Agentic Mode Parameters
|
||||
|
||||
- `knowledge_base_name`: Name of your Knowledge Base (required)
|
||||
- `azure_openai_resource_url`: Azure OpenAI resource URL (required)
|
||||
- `max_search_queries`: Maximum number of search queries to generate (default: 3)
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
1. **Authentication errors**
|
||||
- Ensure `AZURE_SEARCH_API_KEY` is set, or run `az login` for Entra ID auth
|
||||
- Verify your credentials have search permissions
|
||||
|
||||
2. **Index not found**
|
||||
- Verify `AZURE_SEARCH_INDEX_NAME` matches your index name exactly
|
||||
- Check that the index exists and contains documents
|
||||
|
||||
3. **Agentic mode errors**
|
||||
- Ensure `AZURE_SEARCH_KNOWLEDGE_BASE_NAME` is correctly configured
|
||||
- Verify `AZURE_OPENAI_RESOURCE_URL` points to your Azure OpenAI resource (not AI Foundry endpoint)
|
||||
- Check that your OpenAI resource has the necessary model deployments
|
||||
|
||||
4. **No results returned**
|
||||
- Verify your index has documents with vector embeddings (for semantic/hybrid search)
|
||||
- Check that your queries match the content in your index
|
||||
- Try increasing `top_k` parameter
|
||||
|
||||
5. **Slow responses in agentic mode**
|
||||
- This is expected - agentic mode trades speed for accuracy
|
||||
- Reduce `max_search_queries` if needed
|
||||
- Consider semantic mode for speed-critical applications
|
||||
|
||||
## Performance Tips
|
||||
|
||||
- **Use semantic mode** as the default for most scenarios - it's fast and effective
|
||||
- **Switch to agentic mode** when you need multi-hop reasoning or complex queries
|
||||
- **Adjust `top_k`** based on your needs - higher values provide more context but increase token usage
|
||||
- **Enable semantic configuration** in your index for better semantic ranking
|
||||
- **Use Entra ID authentication** in production for better security
|
||||
|
||||
## Additional Resources
|
||||
|
||||
- [Azure AI Search Documentation](https://learn.microsoft.com/azure/search/)
|
||||
- [Azure AI Foundry Documentation](https://learn.microsoft.com/azure/ai-studio/)
|
||||
- [RAG with Azure AI Search](https://learn.microsoft.com/azure/search/retrieval-augmented-generation-overview)
|
||||
- [Semantic Search in Azure AI Search](https://learn.microsoft.com/azure/search/semantic-search-overview)
|
||||
- [Knowledge Bases in Azure AI Search](https://learn.microsoft.com/azure/search/knowledge-store-concept-intro)
|
||||
- [Agentic Retrieval Blog Post](https://techcommunity.microsoft.com/blog/azure-ai-foundry-blog/foundry-iq-boost-response-relevance-by-36-with-agentic-retrieval/4470720)
|
||||
+1
-2
@@ -4,8 +4,7 @@ import asyncio
|
||||
import os
|
||||
|
||||
from agent_framework import ChatAgent
|
||||
from agent_framework_aisearch import AzureAISearchContextProvider
|
||||
from agent_framework_azure_ai import AzureAIAgentClient
|
||||
from agent_framework.azure import AzureAIAgentClient, AzureAISearchContextProvider
|
||||
from azure.identity.aio import AzureCliCredential
|
||||
from dotenv import load_dotenv
|
||||
|
||||
+1
-2
@@ -4,8 +4,7 @@ import asyncio
|
||||
import os
|
||||
|
||||
from agent_framework import ChatAgent
|
||||
from agent_framework_aisearch import AzureAISearchContextProvider
|
||||
from agent_framework_azure_ai import AzureAIAgentClient
|
||||
from agent_framework.azure import AzureAIAgentClient, AzureAISearchContextProvider
|
||||
from azure.identity.aio import AzureCliCredential
|
||||
from dotenv import load_dotenv
|
||||
|
||||
@@ -5,7 +5,7 @@ from collections.abc import MutableSequence, Sequence
|
||||
from typing import Any
|
||||
|
||||
from agent_framework import ChatAgent, ChatClientProtocol, ChatMessage, ChatOptions, Context, ContextProvider
|
||||
from agent_framework.azure import AzureAIAgentClient
|
||||
from agent_framework.azure import AzureAIClient
|
||||
from azure.identity.aio import AzureCliCredential
|
||||
from pydantic import BaseModel
|
||||
|
||||
@@ -47,7 +47,8 @@ class UserInfoMemory(ContextProvider):
|
||||
result = await self._chat_client.get_response(
|
||||
messages=request_messages, # type: ignore
|
||||
chat_options=ChatOptions(
|
||||
instructions="Extract the user's name and age from the message if present. If not present return nulls.",
|
||||
instructions="Extract the user's name and age from the message if present. "
|
||||
"If not present return nulls.",
|
||||
response_format=UserInfo,
|
||||
),
|
||||
)
|
||||
@@ -90,7 +91,7 @@ class UserInfoMemory(ContextProvider):
|
||||
|
||||
async def main():
|
||||
async with AzureCliCredential() as credential:
|
||||
chat_client = AzureAIAgentClient(async_credential=credential)
|
||||
chat_client = AzureAIClient(async_credential=credential)
|
||||
|
||||
# Create the memory provider
|
||||
memory_provider = UserInfoMemory(chat_client)
|
||||
|
||||
Generated
+3503
-3486
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user