diff --git a/03-Azure/01-04-AI/02_Inventory_Planning_Fabric/images/challenge-00-playground-what-can-you-do.png b/03-Azure/01-04-AI/02_Inventory_Planning_Fabric/images/challenge-00-playground-what-can-you-do.png index 726f21c90..b04e3f55e 100644 Binary files a/03-Azure/01-04-AI/02_Inventory_Planning_Fabric/images/challenge-00-playground-what-can-you-do.png and b/03-Azure/01-04-AI/02_Inventory_Planning_Fabric/images/challenge-00-playground-what-can-you-do.png differ diff --git a/03-Azure/01-04-AI/02_Inventory_Planning_Fabric/setup/Setup-InventoryDataAgent.ipynb b/03-Azure/01-04-AI/02_Inventory_Planning_Fabric/setup/Setup-InventoryDataAgent.ipynb index 9d464317a..e50b1a200 100644 --- a/03-Azure/01-04-AI/02_Inventory_Planning_Fabric/setup/Setup-InventoryDataAgent.ipynb +++ b/03-Azure/01-04-AI/02_Inventory_Planning_Fabric/setup/Setup-InventoryDataAgent.ipynb @@ -24,10 +24,10 @@ "metadata": {}, "outputs": [], "source": [ - "# Install both preview SDKs here, at the very top. %pip RESTARTS the Spark kernel and\n", - "# wipes every variable defined before it — so ALL installs must happen up front, and\n", - "# there must be NO later %pip cell (a second restart would wipe `agent`, etc.).\n", - "%pip install -q fabric-data-agent-sdk mcp\n" + "# Install the Fabric SDK and the current MCP 2.x client explicitly. Fabric runtimes do not\n", + "# guarantee that mcp is preinstalled, and %pip RESTARTS the Spark kernel. Keep this as the\n", + "# only package-install cell and rerun the notebook cells after the restart.\n", + "%pip install -q --upgrade fabric-data-agent-sdk \"mcp>=2,<3\"" ] }, { @@ -367,13 +367,13 @@ "outputs": [], "source": [ "# Smoke test -- query the PUBLISHED agent through its MCP endpoint.\n", - "# `mcp` is installed by the top cell (all %pip must be up front — it restarts the\n", - "# kernel). We resolve the agent id from the workspace, so this cell is robust even\n", - "# if run on its own, and we never fail the run on a transient MCP hiccup.\n", - "import asyncio, notebookutils\n", + "# The install cell pins the current MCP 2.x client. We use its high-level Client API\n", + "# with a configured HTTP client for Fabric bearer-token authentication.\n", + "import httpx2, notebookutils\n", "from fabric.dataagent.client import FabricDataAgentManagement\n", - "from mcp import ClientSession\n", - "from mcp.client.streamable_http import streamablehttp_client\n", + "from mcp import Client\n", + "from mcp.client.streamable_http import streamable_http_client\n", + "from mcp.types import TextContent\n", "\n", "workspace_id = notebookutils.runtime.context[\"currentWorkspaceId\"]\n", "mgmt = FabricDataAgentManagement(\"inventory-hack-agent\")\n", @@ -387,13 +387,18 @@ "async def ask_agent(question):\n", " token = notebookutils.credentials.getToken(\"https://api.fabric.microsoft.com\")\n", " headers = {\"Authorization\": f\"Bearer {token}\"}\n", - " async with streamablehttp_client(mcp_url, headers=headers) as (read, write, _):\n", - " async with ClientSession(read, write) as session:\n", - " await session.initialize()\n", - " tool = (await session.list_tools()).tools[0]\n", - " arg = next(iter(tool.inputSchema[\"properties\"]))\n", - " result = await session.call_tool(tool.name, {arg: question})\n", - " return \"\\n\".join(b.text for b in result.content if b.type == \"text\")\n", + " timeout = httpx2.Timeout(60.0, connect=30.0)\n", + " async with httpx2.AsyncClient(headers=headers, timeout=timeout) as http_client:\n", + " transport = streamable_http_client(mcp_url, http_client=http_client)\n", + " async with Client(transport, mode=\"legacy\") as client:\n", + " tools = await client.list_tools()\n", + " tool = tools.tools[0]\n", + " question_arg = next(iter(tool.input_schema[\"properties\"]))\n", + " result = await client.call_tool(tool.name, {question_arg: question})\n", + " return \"\\n\".join(\n", + " block.text for block in result.content\n", + " if isinstance(block, TextContent)\n", + " )\n", "\n", "# Fabric notebooks run inside an event loop already, so use top-level await instead\n", "# of asyncio.run() (which errors on a running loop). Never hard-fail the headless\n",