diff --git a/python/packages/core/tests/azure/test_azure_responses_client.py b/python/packages/core/tests/azure/test_azure_responses_client.py index a495d05837..9b59a3d41a 100644 --- a/python/packages/core/tests/azure/test_azure_responses_client.py +++ b/python/packages/core/tests/azure/test_azure_responses_client.py @@ -578,7 +578,6 @@ async def test_azure_responses_client_agent_hosted_mcp_tool() -> None: @pytest.mark.flaky @skip_if_azure_integration_tests_disabled -@pytest.mark.skip(reason="File search requires API key auth, subscription only allows token auth") async def test_azure_responses_client_file_search() -> None: """Test Azure responses client with file search tool.""" azure_responses_client = AzureOpenAIResponsesClient(credential=AzureCliCredential()) @@ -586,7 +585,7 @@ async def test_azure_responses_client_file_search() -> None: assert isinstance(azure_responses_client, ChatClientProtocol) file_id, vector_store = await create_vector_store(azure_responses_client) - # Test that the client will use the web search tool + # Test that the client will use the file search tool response = await azure_responses_client.get_response( messages=[ ChatMessage( @@ -605,7 +604,6 @@ async def test_azure_responses_client_file_search() -> None: @pytest.mark.flaky @skip_if_azure_integration_tests_disabled -@pytest.mark.skip(reason="File search requires API key auth, subscription only allows token auth") async def test_azure_responses_client_file_search_streaming() -> None: """Test Azure responses client with file search tool and streaming.""" azure_responses_client = AzureOpenAIResponsesClient(credential=AzureCliCredential()) @@ -613,7 +611,7 @@ async def test_azure_responses_client_file_search_streaming() -> None: assert isinstance(azure_responses_client, ChatClientProtocol) file_id, vector_store = await create_vector_store(azure_responses_client) - # Test that the client will use the web search tool + # Test that the client will use the file search tool response = azure_responses_client.get_streaming_response( messages=[ ChatMessage( diff --git a/python/samples/getting_started/agents/azure_openai/README.md b/python/samples/getting_started/agents/azure_openai/README.md index a5b1db617c..466860de3e 100644 --- a/python/samples/getting_started/agents/azure_openai/README.md +++ b/python/samples/getting_started/agents/azure_openai/README.md @@ -21,6 +21,7 @@ This folder contains examples demonstrating different ways to create and use age | [`azure_responses_client_image_analysis.py`](azure_responses_client_image_analysis.py) | Shows how to use Azure OpenAI Responses for image analysis and vision tasks. Demonstrates multi-modal messages combining text and image content using remote URLs. | | [`azure_responses_client_with_code_interpreter.py`](azure_responses_client_with_code_interpreter.py) | Shows how to use the HostedCodeInterpreterTool with Azure agents to write and execute Python code. Includes helper methods for accessing code interpreter data from response chunks. | | [`azure_responses_client_with_explicit_settings.py`](azure_responses_client_with_explicit_settings.py) | Shows how to initialize an agent with a specific responses client, configuring settings explicitly including endpoint and deployment name. | +| [`azure_responses_client_with_file_search.py`](azure_responses_client_with_file_search.py) | Demonstrates using HostedFileSearchTool with Azure OpenAI Responses Client for direct document-based question answering and information retrieval from vector stores. | | [`azure_responses_client_with_function_tools.py`](azure_responses_client_with_function_tools.py) | Demonstrates how to use function tools with agents. Shows both agent-level tools (defined when creating the agent) and query-level tools (provided with specific queries). | | [`azure_responses_client_with_local_mcp.py`](azure_responses_client_with_local_mcp.py) | Shows how to integrate Azure OpenAI Responses Client with local Model Context Protocol (MCP) servers using MCPStreamableHTTPTool for extended functionality. | | [`azure_responses_client_with_thread.py`](azure_responses_client_with_thread.py) | Demonstrates thread management with Azure agents, including automatic thread creation for stateless conversations and explicit thread management for maintaining conversation context across multiple interactions. | diff --git a/python/samples/getting_started/agents/azure_openai/azure_responses_client_with_file_search.py b/python/samples/getting_started/agents/azure_openai/azure_responses_client_with_file_search.py new file mode 100644 index 0000000000..b42c7acf2f --- /dev/null +++ b/python/samples/getting_started/agents/azure_openai/azure_responses_client_with_file_search.py @@ -0,0 +1,71 @@ +# Copyright (c) Microsoft. All rights reserved. + +import asyncio + +from agent_framework import ChatAgent, HostedFileSearchTool, HostedVectorStoreContent +from agent_framework.azure import AzureOpenAIResponsesClient +from azure.identity import AzureCliCredential + +""" +Azure OpenAI Responses Client with File Search Example + +This sample demonstrates using HostedFileSearchTool with Azure OpenAI Responses Client +for direct document-based question answering and information retrieval. + +Prerequisites: +- Set environment variables: + - AZURE_OPENAI_ENDPOINT: Your Azure OpenAI endpoint URL + - AZURE_OPENAI_RESPONSES_DEPLOYMENT_NAME: Your Responses API deployment name +- Authenticate via 'az login' for AzureCliCredential +""" + +# Helper functions + + +async def create_vector_store(client: AzureOpenAIResponsesClient) -> tuple[str, HostedVectorStoreContent]: + """Create a vector store with sample documents.""" + file = await client.client.files.create( + file=("todays_weather.txt", b"The weather today is sunny with a high of 75F."), purpose="assistants" + ) + vector_store = await client.client.vector_stores.create( + name="knowledge_base", + expires_after={"anchor": "last_active_at", "days": 1}, + ) + result = await client.client.vector_stores.files.create_and_poll(vector_store_id=vector_store.id, file_id=file.id) + if result.last_error is not None: + raise Exception(f"Vector store file processing failed with status: {result.last_error.message}") + + return file.id, HostedVectorStoreContent(vector_store_id=vector_store.id) + + +async def delete_vector_store(client: AzureOpenAIResponsesClient, file_id: str, vector_store_id: str) -> None: + """Delete the vector store after using it.""" + await client.client.vector_stores.delete(vector_store_id=vector_store_id) + await client.client.files.delete(file_id=file_id) + + +async def main() -> None: + print("=== Azure OpenAI Responses Client with File Search Example ===\n") + + # Initialize Responses client + # Make sure you're logged in via 'az login' before running this sample + client = AzureOpenAIResponsesClient(credential=AzureCliCredential()) + + file_id, vector_store = await create_vector_store(client) + + agent = ChatAgent( + chat_client=client, + instructions="You are a helpful assistant that can search through files to find information.", + tools=[HostedFileSearchTool(inputs=vector_store)], + ) + + query = "What is the weather today? Do a file search to find the answer." + print(f"User: {query}") + result = await agent.run(query) + print(f"Agent: {result}\n") + + await delete_vector_store(client, file_id, vector_store.vector_store_id) + + +if __name__ == "__main__": + asyncio.run(main())