diff --git a/.github/instructions/cookbook.instructions.md b/.github/instructions/cookbook.instructions.md index 23dab9d9..7299728a 100644 --- a/.github/instructions/cookbook.instructions.md +++ b/.github/instructions/cookbook.instructions.md @@ -26,7 +26,7 @@ Always use `DefaultAzureCredential` from `azure-identity`. Never hardcode API ke ## Key Packages -- `azure-search-documents` (>=11.6.0b13) — Search index, knowledge source, knowledge base, and retrieval APIs +- `azure-search-documents` (>=12.1.0b1) — Search index, knowledge source, knowledge base, and retrieval APIs - `azure-ai-projects` — Foundry Agent Service client (`AIProjectClient`, `MCPTool`) - `azure-identity` — `DefaultAzureCredential` for RBAC-based auth - `python-dotenv` — Load `.env` files @@ -56,8 +56,8 @@ from azure.search.documents.indexes.models import ( KnowledgeBase, KnowledgeBaseAzureOpenAIModel, KnowledgeSourceReference, - KnowledgeRetrievalOutputMode, ) +from azure.search.documents.knowledgebases.models import KnowledgeRetrievalOutputMode knowledge_base = KnowledgeBase( name="my-kb", models=[KnowledgeBaseAzureOpenAIModel(...)], diff --git a/Foundry-IQ/1-Foundry-IQ-Unlocking-Knowledge-for-Agents/cookbook/README.md b/Foundry-IQ/1-Foundry-IQ-Unlocking-Knowledge-for-Agents/cookbook/README.md index ac1c0b02..f538a265 100644 --- a/Foundry-IQ/1-Foundry-IQ-Unlocking-Knowledge-for-Agents/cookbook/README.md +++ b/Foundry-IQ/1-Foundry-IQ-Unlocking-Knowledge-for-Agents/cookbook/README.md @@ -67,7 +67,7 @@ The [**Foundry IQ Cookbook**](./foundry-iq-cookbook.ipynb) walks you through Fou ### Quick Start -1. Install dependencies: `pip install -U azure-search-documents==11.7.0b2 azure-ai-projects azure-identity python-dotenv` +1. Install dependencies: `pip install -U azure-search-documents==12.1.0b1 azure-ai-projects azure-identity python-dotenv` 2. Sign in to Azure: run `az login` in a terminal 3. Create a `.env` file with your endpoint values (see above) 4. Open `foundry-iq-cookbook.ipynb` in VS Code and run the cells diff --git a/Foundry-IQ/1-Foundry-IQ-Unlocking-Knowledge-for-Agents/cookbook/foundry-iq-cookbook.ipynb b/Foundry-IQ/1-Foundry-IQ-Unlocking-Knowledge-for-Agents/cookbook/foundry-iq-cookbook.ipynb index 2587a251..7e8e5415 100644 --- a/Foundry-IQ/1-Foundry-IQ-Unlocking-Knowledge-for-Agents/cookbook/foundry-iq-cookbook.ipynb +++ b/Foundry-IQ/1-Foundry-IQ-Unlocking-Knowledge-for-Agents/cookbook/foundry-iq-cookbook.ipynb @@ -68,7 +68,7 @@ "outputs": [], "source": [ "%%capture\n", - "%pip install -U azure-search-documents==11.7.0b2 azure-ai-projects azure-identity python-dotenv" + "%pip install -U azure-search-documents==12.1.0b1 azure-ai-projects azure-identity python-dotenv" ] }, { @@ -289,8 +289,8 @@ " KnowledgeBase,\n", " KnowledgeBaseAzureOpenAIModel,\n", " KnowledgeSourceReference,\n", - " KnowledgeRetrievalOutputMode,\n", ")\n", + "from azure.search.documents.knowledgebases.models import KnowledgeRetrievalOutputMode\n", "\n", "knowledge_base = KnowledgeBase(\n", " name=KNOWLEDGE_BASE_NAME,\n", @@ -609,6 +609,32 @@ "This is the same MCP endpoint that **any MCP-compatible client** can use — GitHub Copilot, Claude Desktop, VS Code, or your own applications." ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Troubleshooting the agent + MCP connection\n", + "\n", + "Foundry Agent Service can **mask** the underlying Azure AI Search error and surface a generic `tool_user_error` or `405 (Method Not Allowed)` during tool enumeration. These are almost always **auth/RBAC or configuration** issues, not transport bugs. If `responses.create(...)` fails:\n", + "\n", + "**1. Assign the required roles** on the Azure AI Search service to the **Foundry project's managed identity** (keyless auth):\n", + "\n", + "| Role | Assigned to | Purpose |\n", + "|---|---|---|\n", + "| `Search Index Data Reader` | Foundry project managed identity | Read index data during retrieval |\n", + "| `Search Service Contributor` | Foundry project managed identity | Resolve the knowledge base / MCP endpoint |\n", + "\n", + "If the knowledge base uses an LLM for planning/synthesis, also grant the **Search service's** managed identity the `Cognitive Services User` role on the Azure OpenAI / Foundry resource.\n", + "\n", + "**2. Keep both endpoints on the same project.** `FOUNDRY_PROJECT_ENDPOINT` and `FOUNDRY_PROJECT_RESOURCE_ID` must point to the **same** Foundry project, or the connection lookup fails with `Connection '...' not found`.\n", + "\n", + "**3. Use the base resource endpoint for Azure OpenAI.** `AOAI_ENDPOINT` should be `https://.openai.azure.com` — do **not** append `/openai/v1`, which causes a `404` from the model endpoint.\n", + "\n", + "**4. Isolate search vs. agent.** Query the knowledge base directly (the `retrieval_client.retrieve(...)` cell above, or the REST `retrieve` action). If the direct call succeeds, the problem is in how the agent authenticates to MCP (RBAC above). If it returns `401`, re-check the role assignments.\n", + "\n", + "> Make sure your search service has **RBAC enabled** (Settings → Keys → *Both* or *Role-based access control*).\n" + ] + }, { "cell_type": "markdown", "metadata": {}, diff --git a/Foundry-IQ/2-Foundry-IQ-Building-the-Data-Pipeline-with-Knowledge-Sources/cookbook/README.md b/Foundry-IQ/2-Foundry-IQ-Building-the-Data-Pipeline-with-Knowledge-Sources/cookbook/README.md index 966d888a..f5814e36 100644 --- a/Foundry-IQ/2-Foundry-IQ-Building-the-Data-Pipeline-with-Knowledge-Sources/cookbook/README.md +++ b/Foundry-IQ/2-Foundry-IQ-Building-the-Data-Pipeline-with-Knowledge-Sources/cookbook/README.md @@ -70,7 +70,7 @@ The [**Foundry IQ Cookbook**](./foundry-iq-cookbook.ipynb) walks you through bui ### Quick Start -1. Install dependencies: `pip install -U azure-search-documents==11.7.0b2 azure-identity python-dotenv` +1. Install dependencies: `pip install -U azure-search-documents==12.1.0b1 azure-identity python-dotenv` 2. Sign in to Azure: run `az login` in a terminal 3. Create a `.env` file with your endpoint values (see the notebook for details) 4. Open `foundry-iq-cookbook.ipynb` in VS Code and run the cells diff --git a/Foundry-IQ/2-Foundry-IQ-Building-the-Data-Pipeline-with-Knowledge-Sources/cookbook/foundry-iq-cookbook.ipynb b/Foundry-IQ/2-Foundry-IQ-Building-the-Data-Pipeline-with-Knowledge-Sources/cookbook/foundry-iq-cookbook.ipynb index c2e8d7ac..98ebac91 100644 --- a/Foundry-IQ/2-Foundry-IQ-Building-the-Data-Pipeline-with-Knowledge-Sources/cookbook/foundry-iq-cookbook.ipynb +++ b/Foundry-IQ/2-Foundry-IQ-Building-the-Data-Pipeline-with-Knowledge-Sources/cookbook/foundry-iq-cookbook.ipynb @@ -67,7 +67,7 @@ "outputs": [], "source": [ "%%capture\n", - "%pip install -U azure-search-documents==11.7.0b2 azure-identity python-dotenv" + "%pip install -U azure-search-documents==12.1.0b1 azure-identity python-dotenv" ] }, { @@ -443,8 +443,8 @@ " KnowledgeBase,\n", " KnowledgeBaseAzureOpenAIModel,\n", " KnowledgeSourceReference,\n", - " KnowledgeRetrievalOutputMode,\n", ")\n", + "from azure.search.documents.knowledgebases.models import KnowledgeRetrievalOutputMode\n", "\n", "# Build the list of sources (include Blob source only if configured)\n", "sources = [KnowledgeSourceReference(name=INDEXED_KNOWLEDGE_SOURCE_NAME)]\n", diff --git a/Foundry-IQ/3-Foundry-IQ-Querying-the-Multi-Source-AI-Knowledge-Bases/cookbook/README.md b/Foundry-IQ/3-Foundry-IQ-Querying-the-Multi-Source-AI-Knowledge-Bases/cookbook/README.md index 13ad69a3..ddcc7d39 100644 --- a/Foundry-IQ/3-Foundry-IQ-Querying-the-Multi-Source-AI-Knowledge-Bases/cookbook/README.md +++ b/Foundry-IQ/3-Foundry-IQ-Querying-the-Multi-Source-AI-Knowledge-Bases/cookbook/README.md @@ -67,7 +67,7 @@ The [**Foundry IQ Cookbook**](./foundry-iq-cookbook.ipynb) walks you through que ### Quick Start -1. Install dependencies: `pip install -U azure-search-documents==11.7.0b2 azure-identity python-dotenv` +1. Install dependencies: `pip install -U azure-search-documents==12.1.0b1 azure-identity python-dotenv` 2. Sign in to Azure: run `az login` in a terminal 3. Create a `.env` file with your endpoint values (see the notebook for details) 4. Open `foundry-iq-cookbook.ipynb` in VS Code and run the cells diff --git a/Foundry-IQ/3-Foundry-IQ-Querying-the-Multi-Source-AI-Knowledge-Bases/cookbook/foundry-iq-cookbook.ipynb b/Foundry-IQ/3-Foundry-IQ-Querying-the-Multi-Source-AI-Knowledge-Bases/cookbook/foundry-iq-cookbook.ipynb index d91f6f85..4310ee10 100644 --- a/Foundry-IQ/3-Foundry-IQ-Querying-the-Multi-Source-AI-Knowledge-Bases/cookbook/foundry-iq-cookbook.ipynb +++ b/Foundry-IQ/3-Foundry-IQ-Querying-the-Multi-Source-AI-Knowledge-Bases/cookbook/foundry-iq-cookbook.ipynb @@ -65,7 +65,7 @@ "outputs": [], "source": [ "%%capture\n", - "%pip install -U azure-search-documents==11.7.0b2 azure-identity python-dotenv" + "%pip install -U azure-search-documents==12.1.0b1 azure-identity python-dotenv" ] }, { @@ -294,8 +294,8 @@ " KnowledgeBase,\n", " KnowledgeBaseAzureOpenAIModel,\n", " KnowledgeSourceReference,\n", - " KnowledgeRetrievalOutputMode,\n", ")\n", + "from azure.search.documents.knowledgebases.models import KnowledgeRetrievalOutputMode\n", "\n", "knowledge_base = KnowledgeBase(\n", " name=KNOWLEDGE_BASE_NAME,\n", @@ -357,6 +357,7 @@ " KnowledgeBaseRetrievalRequest,\n", " KnowledgeBaseMessage,\n", " KnowledgeBaseMessageTextContent,\n", + " KnowledgeRetrievalSemanticIntent,\n", " KnowledgeRetrievalMinimalReasoningEffort,\n", " KnowledgeRetrievalLowReasoningEffort,\n", " KnowledgeRetrievalMediumReasoningEffort,\n", @@ -372,11 +373,8 @@ "# With minimal effort, we provide explicit search intents\n", "result_minimal = retrieval_client.retrieve(\n", " retrieval_request=KnowledgeBaseRetrievalRequest(\n", - " messages=[\n", - " KnowledgeBaseMessage(\n", - " role=\"user\",\n", - " content=[KnowledgeBaseMessageTextContent(text=\"What Zava paint is best for bathrooms?\")],\n", - " )\n", + " intents=[\n", + " KnowledgeRetrievalSemanticIntent(search=\"What Zava paint is best for bathrooms?\")\n", " ],\n", " include_activity=True,\n", " retrieval_reasoning_effort=KnowledgeRetrievalMinimalReasoningEffort(),\n", @@ -559,8 +557,15 @@ " (\"low\", KnowledgeRetrievalLowReasoningEffort()),\n", " (\"medium\", KnowledgeRetrievalMediumReasoningEffort()),\n", "]:\n", - " result = retrieval_client.retrieve(\n", - " retrieval_request=KnowledgeBaseRetrievalRequest(\n", + " # Minimal effort requires intents input; low/medium use conversational messages\n", + " if effort_name == \"minimal\":\n", + " request = KnowledgeBaseRetrievalRequest(\n", + " intents=[KnowledgeRetrievalSemanticIntent(search=comparison_query)],\n", + " include_activity=True,\n", + " retrieval_reasoning_effort=effort_level,\n", + " )\n", + " else:\n", + " request = KnowledgeBaseRetrievalRequest(\n", " messages=[\n", " KnowledgeBaseMessage(\n", " role=\"user\",\n", @@ -570,7 +575,7 @@ " include_activity=True,\n", " retrieval_reasoning_effort=effort_level,\n", " )\n", - " )\n", + " result = retrieval_client.retrieve(retrieval_request=request)\n", " results[effort_name] = result\n", "\n", "print(\"✅ All three effort levels retrieved\")"