From 70d7808fa1e86c90e5addc184ec76730b362d42e Mon Sep 17 00:00:00 2001 From: George Ollis Date: Wed, 8 Jul 2026 16:48:36 +0100 Subject: [PATCH 01/17] Add Strands agent implementation with Azure OpenAI integration - Implemented main.py to handle responses using Strands Agents SDK. - Added tools for weather retrieval and environment variable debugging. - Integrated Azure OpenAI model with support for incremental token streaming. - Created requirements.txt for necessary dependencies including azure-ai-agentserver-responses and strands-agents. --- docs/labs-config.json | 22 + .../.gitignore | 6 + .../README.md | 97 ++ ...undry-hosted-agents-custom-framework.ipynb | 1429 +++++++++++++++++ .../clean-up-resources.ipynb | 110 ++ .../main.bicep | 255 +++ .../policy.xml | 19 + .../agents/pydantic-ai/.dockerignore | 26 + .../responses/agents/pydantic-ai/.gitignore | 5 + .../01_hosted_agent_pydantic_setup.ipynb | 187 +++ .../responses/agents/pydantic-ai/Dockerfile | 7 + .../responses/agents/pydantic-ai/README.md | 32 + .../responses/agents/pydantic-ai/image.png | Bin 0 -> 138258 bytes .../src/responses/agents/pydantic-ai/main.py | 183 +++ .../agents/pydantic-ai/requirements.txt | 6 + .../responses/agents/strands/.dockerignore | 26 + .../src/responses/agents/strands/.gitignore | 5 + .../01_hosted_agent_strands_setup.ipynb | 833 ++++++++++ .../src/responses/agents/strands/Dockerfile | 7 + .../src/responses/agents/strands/README.md | 32 + .../src/responses/agents/strands/example.env | 6 + .../src/responses/agents/strands/image.png | Bin 0 -> 141435 bytes .../src/responses/agents/strands/main.py | 279 ++++ .../responses/agents/strands/requirements.txt | 4 + modules/cognitive-services/v3/foundry.bicep | 1 + 25 files changed, 3577 insertions(+) create mode 100644 labs/ai-foundry-hosted-agents-custom-framework/.gitignore create mode 100644 labs/ai-foundry-hosted-agents-custom-framework/README.md create mode 100644 labs/ai-foundry-hosted-agents-custom-framework/ai-foundry-hosted-agents-custom-framework.ipynb create mode 100644 labs/ai-foundry-hosted-agents-custom-framework/clean-up-resources.ipynb create mode 100644 labs/ai-foundry-hosted-agents-custom-framework/main.bicep create mode 100644 labs/ai-foundry-hosted-agents-custom-framework/policy.xml create mode 100644 labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/pydantic-ai/.dockerignore create mode 100644 labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/pydantic-ai/.gitignore create mode 100644 labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/pydantic-ai/01_hosted_agent_pydantic_setup.ipynb create mode 100644 labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/pydantic-ai/Dockerfile create mode 100644 labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/pydantic-ai/README.md create mode 100644 labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/pydantic-ai/image.png create mode 100644 labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/pydantic-ai/main.py create mode 100644 labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/pydantic-ai/requirements.txt create mode 100644 labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/.dockerignore create mode 100644 labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/.gitignore create mode 100644 labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/01_hosted_agent_strands_setup.ipynb create mode 100644 labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/Dockerfile create mode 100644 labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/README.md create mode 100644 labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/example.env create mode 100644 labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/image.png create mode 100644 labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/main.py create mode 100644 labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/requirements.txt diff --git a/docs/labs-config.json b/docs/labs-config.json index 9eee7626..53554e99 100644 --- a/docs/labs-config.json +++ b/docs/labs-config.json @@ -85,6 +85,28 @@ "githubPath": "https://github.com/Azure-Samples/AI-Gateway/tree/main/labs/ai-foundry-hosted-agents", "lastCommitDate": "2026-03-02T11:38:30.603Z" }, + { + "id": "ai-foundry-hosted-agents-custom-framework", + "name": "AI Foundry Hosted Agents (Custom Frameworks)", + "architectureDiagram": "images/ai-foundry-hosted-agents.gif", + "categories": [ + "AI Agents" + ], + "services": [ + "Azure AI Foundry", + "Azure API Management", + "Azure Container Apps", + "MCP" + ], + "shortDescription": "Deploy AI Foundry Hosted Agents built with custom frameworks, including Pydantic AI and Strands.", + "detailedDescription": "This lab provides custom framework examples for AI Foundry Hosted Agents, showing how to package and deploy hosted agents built with Pydantic AI and Strands to Azure Container Apps. It includes a Bicep deployment for Azure API Management, Azure AI Foundry, and a GPT-5-Mini model deployment, plus end-to-end setup notebooks and Dockerfiles.", + "authors": [ + "nourshaker-msft" + ], + "tags": [], + "githubPath": "https://github.com/Azure-Samples/AI-Gateway/tree/main/labs/ai-foundry-hosted-agents-custom-framework", + "lastCommitDate": "2026-07-08T00:00:00.000Z" + }, { "id": "ai-foundry-model-gateway", "name": "AI Foundry Model Gateway", diff --git a/labs/ai-foundry-hosted-agents-custom-framework/.gitignore b/labs/ai-foundry-hosted-agents-custom-framework/.gitignore new file mode 100644 index 00000000..656c5a16 --- /dev/null +++ b/labs/ai-foundry-hosted-agents-custom-framework/.gitignore @@ -0,0 +1,6 @@ +.venv/ +__pycache__/ +*.pyc +.env +main.parameters.generated.json +foundry-user-object-ids.json \ No newline at end of file diff --git a/labs/ai-foundry-hosted-agents-custom-framework/README.md b/labs/ai-foundry-hosted-agents-custom-framework/README.md new file mode 100644 index 00000000..45585aa6 --- /dev/null +++ b/labs/ai-foundry-hosted-agents-custom-framework/README.md @@ -0,0 +1,97 @@ +--- +name: "AI Foundry Hosted Agents (Custom Frameworks)" +architectureDiagram: images/ai-foundry-hosted-agents.gif +categories: + - AI Agents +services: + - Azure AI Foundry + - Azure API Management + - Azure Container Apps + - MCP +shortDescription: Deploy AI Foundry Hosted Agents built with custom frameworks, including Pydantic AI and Strands. +detailedDescription: This lab provides custom framework examples for AI Foundry Hosted Agents, showing how to package and deploy hosted agents built with Pydantic AI and Strands to Azure Container Apps. It includes a Bicep deployment for Azure API Management, Azure AI Foundry, and a GPT-5-Mini model deployment, plus end-to-end setup notebooks and Dockerfiles. +authors: + - nourshaker-msft +tags: [] +--- + +# APIM ❤️ AI Foundry + +## AI Foundry Hosted Agents with Custom Frameworks + +This lab extends the Hosted Agents scenario with framework-specific examples so you can build agents using your preferred runtime while keeping a common deployment pattern. + +### Why run custom frameworks on Foundry Hosted Agents? + +1. Built-in observability, tracing, and monitoring. +Foundry provides a standard operational surface for agent runs, telemetry, and diagnostics so teams can troubleshoot faster and keep a consistent monitoring model across different agent runtimes. + +2. Agent Identity and RBAC by default. +Your runtime is registered as a Foundry Agent and gets an Agent Identity, enabling least-privilege access to downstream Azure resources (for example, storage, search, or APIs) through RBAC instead of embedded secrets. + +3. Foundry guardrails and governance. +Hosted agents can inherit platform safety controls and governance policies, helping you enforce security and compliance consistently even when the runtime framework is custom. + +4. Discovery through Agent365. +Publishing into the Foundry ecosystem makes agents easier to discover and reuse across teams, reducing duplicate implementations. + +5. Native evaluation and risk testing integration. +You can plug directly into Foundry evaluations, red teaming, and cost-estimation workflows to compare quality, safety, and spend using the same platform tooling. + +6. Control plane and platform operations. +Agents are managed as platform assets in the Foundry control plane, with operational benefits such as managed hosting lifecycle, scaling, and centralized administration. + +### When custom frameworks are a good fit + +- You need framework-specific capabilities (for example, Pydantic AI or Strands primitives) not available in a default runtime. +- You want framework flexibility without giving up Foundry governance and enterprise operations. +- You need to standardize deployment and operations across multiple agent implementations. + +## [Infrastructure deployment notebook](ai-foundry-hosted-agents-custom-framework.ipynb) + +Use this notebook first to deploy core infrastructure with Bicep: + +- Azure API Management (APIM) +- Microsoft Foundry (two foundry resources: models + hosted agents) +- GPT-5-Mini model deployment +- Azure Container Registry (ACR) for hosted agent images + +The deployment also configures: + +- ACR repository permissions for the hosted-agent Foundry resource (`Container Registry Repository Reader`) +- ACR repository permissions for the deploying user (`Container Registry Repository Writer` + `Container Registry Repository Catalog Lister`) +- Foundry User role assignments (`Azure AI User`) for configured user object IDs across all Foundry resources deployed by this lab +- Optional APIM proxy API for the Hosted Agent Responses endpoint, added after the hosted agent has been deployed and is running + +The deployment template is in [main.bicep](main.bicep). + +### Available samples + +- [Pydantic AI sample](src/responses/agents/pydantic-ai/README.md) +- [Strands sample](src/responses/agents/strands/README.md) + +### Prerequisites + +- [Python 3.12 or later version](https://www.python.org/) installed +- [VS Code](https://code.visualstudio.com/) installed with the [Jupyter notebook extension](https://marketplace.visualstudio.com/items?itemName=ms-toolsai.jupyter) enabled +- [uv](https://docs.astral.sh/uv/) - run `uv sync` from the repo root to install dependencies +- [An Azure Subscription](https://azure.microsoft.com/free/) with [Contributor](https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles/privileged#contributor) + [RBAC Administrator](https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles/privileged#role-based-access-control-administrator) or [Owner](https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles/privileged#owner) roles +- [Azure CLI](https://learn.microsoft.com/cli/azure/install-azure-cli) installed and [signed into your Azure subscription](https://learn.microsoft.com/cli/azure/authenticate-azure-cli-interactively) +- [Docker](https://www.docker.com/get-started/) installed and running (for building container images) + +### Get started + +1. Run the [infrastructure deployment notebook](ai-foundry-hosted-agents-custom-framework.ipynb). +2. Choose one of the sample frameworks above. +3. Open its setup notebook and run all steps. +4. Build and push the container image to your Azure Container Registry. +5. Deploy the hosted agent version in your Foundry project. +6. Set the hosted agent ID in the infra notebook config and re-run deployment to provision APIM fronting for the Responses API. + +### Related lab + +For the full end-to-end APIM + Foundry hosted agent architecture, see [AI Foundry Hosted Agents](../ai-foundry-hosted-agents/README.md). + +### Clean up resources + +Use the [clean-up-resources notebook](clean-up-resources.ipynb) to remove deployed resources when you are finished. diff --git a/labs/ai-foundry-hosted-agents-custom-framework/ai-foundry-hosted-agents-custom-framework.ipynb b/labs/ai-foundry-hosted-agents-custom-framework/ai-foundry-hosted-agents-custom-framework.ipynb new file mode 100644 index 00000000..24e84fa3 --- /dev/null +++ b/labs/ai-foundry-hosted-agents-custom-framework/ai-foundry-hosted-agents-custom-framework.ipynb @@ -0,0 +1,1429 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "db72bfd0", + "metadata": {}, + "source": [ + "# AI Foundry Hosted Agents (Custom Frameworks)\n", + "\n", + "This notebook deploys the shared lab infrastructure using `main.bicep`:\n", + "\n", + "- Azure API Management (APIM)\n", + "- Microsoft Foundry instances (One foundry instance hosting models + One found instance hosting agents)\n", + "- GPT-5-Mini model deployment\n", + "\n", + "## Why run custom frameworks on Foundry Hosted Agents?\n", + "\n", + "1. Built-in observability, tracing, and monitoring.\n", + "Foundry provides a standard operational surface for agent runs, telemetry, and diagnostics so teams can troubleshoot faster and keep a consistent monitoring model across different agent runtimes.\n", + "\n", + "2. Agent Identity and RBAC by default.\n", + "Your runtime is registered as a Foundry Agent and gets an Agent Identity, enabling least-privilege access to downstream Azure resources (for example, storage, search, or APIs) through RBAC instead of embedded secrets.\n", + "\n", + "3. Foundry guardrails and governance.\n", + "Hosted agents can inherit platform safety controls and governance policies, helping you enforce security and compliance consistently even when the runtime framework is custom.\n", + "\n", + "4. Discovery through Agent365.\n", + "Publishing into the Foundry ecosystem makes agents easier to discover and reuse across teams, reducing duplicate implementations.\n", + "\n", + "5. Native evaluation and risk testing integration.\n", + "You can plug directly into Foundry evaluations, red teaming, and cost-estimation workflows to compare quality, safety, and spend using the same platform tooling.\n", + "\n", + "6. Control plane and platform operations.\n", + "Agents are managed as platform assets in the Foundry control plane, with operational benefits such as managed hosting lifecycle, scaling, and centralized administration.\n", + "\n", + "## When custom frameworks are a good fit\n", + "\n", + "- You need framework-specific capabilities (for example, Pydantic AI or Strands primitives) not available in a default runtime.\n", + "- You want framework flexibility without giving up Foundry governance and enterprise operations.\n", + "- You need to standardize deployment and operations across multiple agent implementations.\n", + "\n", + "After deployment, continue with one framework-specific setup notebook:\n", + "\n", + "- `src/responses/agents/pydantic-ai/01_hosted_agent_pydantic_setup.ipynb`\n", + "- `src/responses/agents/strands/01_hosted_agent_strands_setup.ipynb`" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "99068750", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Lab directory: c:\\GitHub\\ai-gateway\\AI-Gateway\\labs\\ai-foundry-hosted-agents-custom-framework\n" + ] + } + ], + "source": [ + "import json\n", + "import os\n", + "import subprocess\n", + "from pathlib import Path\n", + "\n", + "def run(cmd):\n", + " print('\\n$ ' + ' '.join(cmd))\n", + " result = subprocess.run(cmd, capture_output=True, text=True)\n", + " if result.stdout:\n", + " print(result.stdout)\n", + " if result.returncode != 0:\n", + " if result.stderr:\n", + " print(result.stderr)\n", + " raise RuntimeError(f'Command failed: {result.returncode}')\n", + " return result\n", + "\n", + "lab_dir = Path.cwd()\n", + "if not (lab_dir / 'main.bicep').exists():\n", + " raise FileNotFoundError('Run this notebook from labs/ai-foundry-hosted-agents-custom-framework')\n", + "\n", + "print(f'Lab directory: {lab_dir}')" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "1c47a2ce", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Configuration ready. Set real values before running deployment.\n" + ] + } + ], + "source": [ + "# Update these values as needed\n", + "subscription_id = 'baba41cf-c01d-4a55-b6c5-ca494b802be5'\n", + "resource_group = 'rg-aigw-hosted-custom-framework'\n", + "location = 'swedencentral'\n", + "deployment_name = 'deploy-hosted-custom-framework'\n", + "\n", + "# Two Foundry resources:\n", + "# - index 0: model hosting\n", + "# - index 1: hosted-agent hosting\n", + "ai_services_config = [\n", + " {\n", + " 'name': 'foundry-models',\n", + " 'location': location,\n", + " 'priority': 1,\n", + " 'weight': 100\n", + " },\n", + " {\n", + " 'name': 'foundry-agents',\n", + " 'location': location,\n", + " 'priority': 1,\n", + " 'weight': 100\n", + " }\n", + "]\n", + "\n", + "# gpt-5-mini is available in this subscription/region and was deployed manually.\n", + "# Keep the version aligned with the manually deployed model.\n", + "models_config = [\n", + " {\n", + " 'aiservice': 'foundry-models',\n", + " 'name': 'gpt-5-mini',\n", + " 'publisher': 'OpenAI',\n", + " 'version': '2025-08-07',\n", + " 'sku': 'GlobalStandard',\n", + " 'capacity': 10\n", + " }\n", + "]\n", + "\n", + "apim_subscriptions = [\n", + " {\n", + " 'name': 'starter',\n", + " 'displayName': 'Starter',\n", + " 'scope': '/apis'\n", + " }\n", + "]\n", + "\n", + "# Deploy the hosted agent first. After it is running, set these values and rerun\n", + "# this notebook to add the APIM proxy in front of the Hosted Agent Responses API.\n", + "enable_hosted_agent_responses_api = False\n", + "hosted_agent_id = '' # set to your deployed hosted agent id to enable APIM proxy\n", + "\n", + "print('Configuration ready. Set real values before running deployment.')" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "91b2888b", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "$ cmd /c C:\\Program Files\\Microsoft SDKs\\Azure\\CLI2\\wbin\\az.cmd ad signed-in-user show --query id -o tsv\n", + "13f94c0d-8a51-492a-928b-59392c23c1ac\n", + "\n", + "Foundry user object IDs:\n", + "[\n", + " \"13f94c0d-8a51-492a-928b-59392c23c1ac\"\n", + "]\n", + "Saved to: c:\\GitHub\\ai-gateway\\AI-Gateway\\labs\\ai-foundry-hosted-agents-custom-framework\\foundry-user-object-ids.json\n" + ] + } + ], + "source": [ + "from pathlib import Path\n", + "import json\n", + "import shutil\n", + "\n", + "# Run Azure CLI lookups for Foundry user object IDs and save the results locally.\n", + "# Update the user_principal_names list with any users you want to grant Foundry User access.\n", + "user_principal_names = [\n", + " # 'user@contoso.com',\n", + "]\n", + "\n", + "az_cmd = shutil.which('az.cmd') or shutil.which('az')\n", + "if not az_cmd:\n", + " raise FileNotFoundError('Azure CLI was not found on PATH. Install Azure CLI or add az.cmd to PATH.')\n", + "\n", + "\n", + "def az_cli(args):\n", + " command = ['cmd', '/c', az_cmd, *args] if az_cmd.lower().endswith('.cmd') else [az_cmd, *args]\n", + " return run(command).stdout.strip()\n", + "\n", + "signed_in_user_id = az_cli(['ad', 'signed-in-user', 'show', '--query', 'id', '-o', 'tsv'])\n", + "user_object_ids = []\n", + "if signed_in_user_id:\n", + " user_object_ids.append(signed_in_user_id)\n", + "\n", + "for user_principal_name in user_principal_names:\n", + " user_id = az_cli(['ad', 'user', 'show', '--id', user_principal_name, '--query', 'id', '-o', 'tsv'])\n", + " if user_id:\n", + " user_object_ids.append(user_id)\n", + "\n", + "foundry_user_object_ids = list(dict.fromkeys(user_object_ids))\n", + "\n", + "output_file = lab_dir / 'foundry-user-object-ids.json'\n", + "output_file.write_text(json.dumps(foundry_user_object_ids, indent=2), encoding='utf-8')\n", + "\n", + "print('Foundry user object IDs:')\n", + "print(json.dumps(foundry_user_object_ids, indent=2))\n", + "print(f'Saved to: {output_file}')" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "3c1be18b", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "$ cmd /c C:\\Program Files\\Microsoft SDKs\\Azure\\CLI2\\wbin\\az.cmd account set --subscription baba41cf-c01d-4a55-b6c5-ca494b802be5\n", + "\n", + "$ cmd /c C:\\Program Files\\Microsoft SDKs\\Azure\\CLI2\\wbin\\az.cmd group create --name rg-aigw-hosted-custom-framework --location swedencentral\n", + "{\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework\",\n", + " \"location\": \"swedencentral\",\n", + " \"managedBy\": null,\n", + " \"name\": \"rg-aigw-hosted-custom-framework\",\n", + " \"properties\": {\n", + " \"provisioningState\": \"Succeeded\"\n", + " },\n", + " \"tags\": null,\n", + " \"type\": \"Microsoft.Resources/resourceGroups\"\n", + "}\n", + "\n", + "Wrote parameters: c:\\GitHub\\ai-gateway\\AI-Gateway\\labs\\ai-foundry-hosted-agents-custom-framework\\main.parameters.generated.json\n", + "\n", + "$ cmd /c C:\\Program Files\\Microsoft SDKs\\Azure\\CLI2\\wbin\\az.cmd bicep install\n", + "Bicep CLI is already installed at 'C:\\Users\\ollisgeorge\\.azure\\bin\\bicep.exe'. Skipping installation as no specific version was requested.\n", + "\n", + "\n", + "$ cmd /c C:\\Program Files\\Microsoft SDKs\\Azure\\CLI2\\wbin\\az.cmd deployment group validate --resource-group rg-aigw-hosted-custom-framework --template-file C:\\GitHub\\ai-gateway\\AI-Gateway\\labs\\ai-foundry-hosted-agents-custom-framework\\main.bicep --parameters @C:\\GitHub\\ai-gateway\\AI-Gateway\\labs\\ai-foundry-hosted-agents-custom-framework\\main.parameters.generated.json --only-show-errors\n", + "{\n", + " \"error\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/main\",\n", + " \"name\": \"main\",\n", + " \"properties\": {\n", + " \"correlationId\": \"d22fd605-8099-4276-a378-c5e2c45d988f\",\n", + " \"debugSetting\": null,\n", + " \"dependencies\": [\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrvu4ax6chjqjsk\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"acrvu4ax6chjqjsk\",\n", + " \"resourceType\": \"Microsoft.ContainerRegistry/registries\"\n", + " },\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/foundryModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"foundryModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrvu4ax6chjqjsk/providers/Microsoft.Authorization/roleAssignments/6801f057-9c94-548e-af97-b7aa48df6191\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"6801f057-9c94-548e-af97-b7aa48df6191\",\n", + " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", + " },\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrvu4ax6chjqjsk\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"acrvu4ax6chjqjsk\",\n", + " \"resourceType\": \"Microsoft.ContainerRegistry/registries\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrvu4ax6chjqjsk/providers/Microsoft.Authorization/roleAssignments/9723640a-c519-5fbd-8169-28d574b21f8f\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"9723640a-c519-5fbd-8169-28d574b21f8f\",\n", + " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", + " },\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrvu4ax6chjqjsk\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"acrvu4ax6chjqjsk\",\n", + " \"resourceType\": \"Microsoft.ContainerRegistry/registries\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrvu4ax6chjqjsk/providers/Microsoft.Authorization/roleAssignments/eb950c04-f5c5-5133-b32d-b544c7b7681c\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"eb950c04-f5c5-5133-b32d-b544c7b7681c\",\n", + " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", + " },\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/lawModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"lawModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/appInsightsModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"appInsightsModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " },\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/appInsightsModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"appInsightsModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " },\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/lawModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"lawModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/apimModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"apimModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " },\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/apimModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"apimModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " },\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/appInsightsModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"appInsightsModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/foundryModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"foundryModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " },\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/apimModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"apimModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " },\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/appInsightsModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"appInsightsModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " },\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/foundryModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"foundryModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/inferenceAPIModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"inferenceAPIModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " }\n", + " ],\n", + " \"diagnostics\": [\n", + " {\n", + " \"additionalInfo\": null,\n", + " \"code\": \"NestedDeploymentShortCircuited\",\n", + " \"level\": \"Warning\",\n", + " \"message\": \"A nested deployment got short-circuited and all its resources got skipped from validation. This is due to a nested template having a parameter that was not fully evaluated (e.g. contains a reference() function). Please see https://aka.ms/WhatIfEvalStopped for more guidance.\",\n", + " \"target\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/appInsightsModule\"\n", + " },\n", + " {\n", + " \"additionalInfo\": null,\n", + " \"code\": \"NestedDeploymentShortCircuited\",\n", + " \"level\": \"Warning\",\n", + " \"message\": \"A nested deployment got short-circuited and all its resources got skipped from validation. This is due to a nested template having a parameter that was not fully evaluated (e.g. contains a reference() function). Please see https://aka.ms/WhatIfEvalStopped for more guidance.\",\n", + " \"target\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/apimModule\"\n", + " },\n", + " {\n", + " \"additionalInfo\": null,\n", + " \"code\": \"NestedDeploymentShortCircuited\",\n", + " \"level\": \"Warning\",\n", + " \"message\": \"A nested deployment got short-circuited and all its resources got skipped from validation. This is due to a nested template having a parameter that was not fully evaluated (e.g. contains a reference() function). Please see https://aka.ms/WhatIfEvalStopped for more guidance.\",\n", + " \"target\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/foundryModule\"\n", + " },\n", + " {\n", + " \"additionalInfo\": null,\n", + " \"code\": \"NestedDeploymentShortCircuited\",\n", + " \"level\": \"Warning\",\n", + " \"message\": \"A nested deployment got short-circuited and all its resources got skipped from validation. This is due to a nested template having a parameter that was not fully evaluated (e.g. contains a reference() function). Please see https://aka.ms/WhatIfEvalStopped for more guidance.\",\n", + " \"target\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/inferenceAPIModule\"\n", + " }\n", + " ],\n", + " \"duration\": \"PT0S\",\n", + " \"error\": null,\n", + " \"extensions\": [],\n", + " \"mode\": \"Incremental\",\n", + " \"onErrorDeployment\": null,\n", + " \"outputResources\": null,\n", + " \"outputs\": null,\n", + " \"parameters\": {\n", + " \"aiServicesConfig\": {\n", + " \"type\": \"Array\",\n", + " \"value\": [\n", + " {\n", + " \"location\": \"swedencentral\",\n", + " \"name\": \"foundry-models\",\n", + " \"priority\": 1,\n", + " \"weight\": 100\n", + " },\n", + " {\n", + " \"location\": \"swedencentral\",\n", + " \"name\": \"foundry-agents\",\n", + " \"priority\": 1,\n", + " \"weight\": 100\n", + " }\n", + " ]\n", + " },\n", + " \"apimSku\": {\n", + " \"type\": \"String\",\n", + " \"value\": \"Basicv2\"\n", + " },\n", + " \"apimSubscriptionsConfig\": {\n", + " \"type\": \"Array\",\n", + " \"value\": [\n", + " {\n", + " \"displayName\": \"Starter\",\n", + " \"name\": \"starter\",\n", + " \"scope\": \"/apis\"\n", + " }\n", + " ]\n", + " },\n", + " \"enableHostedAgentResponsesApi\": {\n", + " \"type\": \"Bool\",\n", + " \"value\": false\n", + " },\n", + " \"foundryAgentAiServiceIndex\": {\n", + " \"type\": \"Int\",\n", + " \"value\": 1\n", + " },\n", + " \"foundryProjectName\": {\n", + " \"type\": \"String\",\n", + " \"value\": \"default\"\n", + " },\n", + " \"foundryUserObjectIds\": {\n", + " \"type\": \"Array\",\n", + " \"value\": [\n", + " \"13f94c0d-8a51-492a-928b-59392c23c1ac\"\n", + " ]\n", + " },\n", + " \"hostedAgentId\": {\n", + " \"type\": \"String\",\n", + " \"value\": \"\"\n", + " },\n", + " \"hostedAgentResponsesApiPath\": {\n", + " \"type\": \"String\",\n", + " \"value\": \"hosted-agent-responses\"\n", + " },\n", + " \"hostedAgentResponsesApiVersion\": {\n", + " \"type\": \"String\",\n", + " \"value\": \"2025-05-15-preview\"\n", + " },\n", + " \"inferenceAPIPath\": {\n", + " \"type\": \"String\",\n", + " \"value\": \"inference\"\n", + " },\n", + " \"inferenceAPIType\": {\n", + " \"type\": \"String\",\n", + " \"value\": \"AzureAI\"\n", + " },\n", + " \"modelsConfig\": {\n", + " \"type\": \"Array\",\n", + " \"value\": [\n", + " {\n", + " \"aiservice\": \"foundry-models\",\n", + " \"capacity\": 10,\n", + " \"name\": \"gpt-5-mini\",\n", + " \"publisher\": \"OpenAI\",\n", + " \"sku\": \"GlobalStandard\",\n", + " \"version\": \"2025-08-07\"\n", + " }\n", + " ]\n", + " }\n", + " },\n", + " \"parametersLink\": null,\n", + " \"providers\": [\n", + " {\n", + " \"id\": null,\n", + " \"namespace\": \"Microsoft.ContainerRegistry\",\n", + " \"providerAuthorizationConsentState\": null,\n", + " \"registrationPolicy\": null,\n", + " \"registrationState\": null,\n", + " \"resourceTypes\": [\n", + " {\n", + " \"aliases\": null,\n", + " \"apiProfiles\": null,\n", + " \"apiVersions\": null,\n", + " \"capabilities\": null,\n", + " \"defaultApiVersion\": null,\n", + " \"locationMappings\": null,\n", + " \"locations\": [\n", + " \"swedencentral\"\n", + " ],\n", + " \"properties\": null,\n", + " \"resourceType\": \"registries\",\n", + " \"zoneMappings\": null\n", + " }\n", + " ]\n", + " },\n", + " {\n", + " \"id\": null,\n", + " \"namespace\": \"Microsoft.Authorization\",\n", + " \"providerAuthorizationConsentState\": null,\n", + " \"registrationPolicy\": null,\n", + " \"registrationState\": null,\n", + " \"resourceTypes\": [\n", + " {\n", + " \"aliases\": null,\n", + " \"apiProfiles\": null,\n", + " \"apiVersions\": null,\n", + " \"capabilities\": null,\n", + " \"defaultApiVersion\": null,\n", + " \"locationMappings\": null,\n", + " \"locations\": [\n", + " null\n", + " ],\n", + " \"properties\": null,\n", + " \"resourceType\": \"roleAssignments\",\n", + " \"zoneMappings\": null\n", + " }\n", + " ]\n", + " },\n", + " {\n", + " \"id\": null,\n", + " \"namespace\": \"Microsoft.Resources\",\n", + " \"providerAuthorizationConsentState\": null,\n", + " \"registrationPolicy\": null,\n", + " \"registrationState\": null,\n", + " \"resourceTypes\": [\n", + " {\n", + " \"aliases\": null,\n", + " \"apiProfiles\": null,\n", + " \"apiVersions\": null,\n", + " \"capabilities\": null,\n", + " \"defaultApiVersion\": null,\n", + " \"locationMappings\": null,\n", + " \"locations\": [\n", + " null\n", + " ],\n", + " \"properties\": null,\n", + " \"resourceType\": \"deployments\",\n", + " \"zoneMappings\": null\n", + " }\n", + " ]\n", + " }\n", + " ],\n", + " \"provisioningState\": \"Succeeded\",\n", + " \"templateHash\": \"5327887757473726207\",\n", + " \"templateLink\": null,\n", + " \"timestamp\": \"2026-07-08T13:24:11.057134+00:00\",\n", + " \"validatedResources\": [\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.CognitiveServices/accounts/foundry-agents-vu4ax6chjqjsk/providers/Microsoft.Authorization/roleAssignments/b81335fb-f585-5a98-b1d3-b05ccfc27073\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceType\": null\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.CognitiveServices/accounts/foundry-models-vu4ax6chjqjsk/providers/Microsoft.Authorization/roleAssignments/219a9a8c-8372-5217-8a2e-f11f82a3b4b0\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceType\": null\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrvu4ax6chjqjsk\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceType\": null\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrvu4ax6chjqjsk/providers/Microsoft.Authorization/roleAssignments/6801f057-9c94-548e-af97-b7aa48df6191\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceType\": null\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrvu4ax6chjqjsk/providers/Microsoft.Authorization/roleAssignments/9723640a-c519-5fbd-8169-28d574b21f8f\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceType\": null\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrvu4ax6chjqjsk/providers/Microsoft.Authorization/roleAssignments/eb950c04-f5c5-5133-b32d-b544c7b7681c\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceType\": null\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.OperationalInsights/workspaces/workspace-vu4ax6chjqjsk\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceType\": null\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/apimModule\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceType\": null\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/appInsightsModule\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceType\": null\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/foundryModule\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceType\": null\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/inferenceAPIModule\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceType\": null\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/lawModule\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceType\": null\n", + " }\n", + " ],\n", + " \"validationLevel\": null\n", + " },\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"type\": \"Microsoft.Resources/deployments\"\n", + "}\n", + "\n", + "\n", + "$ cmd /c C:\\Program Files\\Microsoft SDKs\\Azure\\CLI2\\wbin\\az.cmd deployment group create --resource-group rg-aigw-hosted-custom-framework --name deploy-hosted-custom-framework --template-file C:\\GitHub\\ai-gateway\\AI-Gateway\\labs\\ai-foundry-hosted-agents-custom-framework\\main.bicep --parameters @C:\\GitHub\\ai-gateway\\AI-Gateway\\labs\\ai-foundry-hosted-agents-custom-framework\\main.parameters.generated.json --only-show-errors\n", + "{\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/deploy-hosted-custom-framework\",\n", + " \"location\": null,\n", + " \"name\": \"deploy-hosted-custom-framework\",\n", + " \"properties\": {\n", + " \"correlationId\": \"1d492275-6c20-49e0-88e7-ba8679def3c7\",\n", + " \"debugSetting\": null,\n", + " \"dependencies\": [\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrvu4ax6chjqjsk\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"acrvu4ax6chjqjsk\",\n", + " \"resourceType\": \"Microsoft.ContainerRegistry/registries\"\n", + " },\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/foundryModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"foundryModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrvu4ax6chjqjsk/providers/Microsoft.Authorization/roleAssignments/6801f057-9c94-548e-af97-b7aa48df6191\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"6801f057-9c94-548e-af97-b7aa48df6191\",\n", + " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", + " },\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrvu4ax6chjqjsk\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"acrvu4ax6chjqjsk\",\n", + " \"resourceType\": \"Microsoft.ContainerRegistry/registries\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrvu4ax6chjqjsk/providers/Microsoft.Authorization/roleAssignments/9723640a-c519-5fbd-8169-28d574b21f8f\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"9723640a-c519-5fbd-8169-28d574b21f8f\",\n", + " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", + " },\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrvu4ax6chjqjsk\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"acrvu4ax6chjqjsk\",\n", + " \"resourceType\": \"Microsoft.ContainerRegistry/registries\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrvu4ax6chjqjsk/providers/Microsoft.Authorization/roleAssignments/eb950c04-f5c5-5133-b32d-b544c7b7681c\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"eb950c04-f5c5-5133-b32d-b544c7b7681c\",\n", + " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", + " },\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/lawModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"lawModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/appInsightsModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"appInsightsModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " },\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/appInsightsModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"appInsightsModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " },\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/lawModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"lawModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/apimModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"apimModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " },\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/apimModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"apimModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " },\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/appInsightsModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"appInsightsModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/foundryModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"foundryModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " },\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/apimModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"apimModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " },\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/appInsightsModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"appInsightsModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " },\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/foundryModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"foundryModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/inferenceAPIModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"inferenceAPIModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " }\n", + " ],\n", + " \"diagnostics\": null,\n", + " \"duration\": \"PT2M9.8411308S\",\n", + " \"error\": null,\n", + " \"extensions\": [],\n", + " \"mode\": \"Incremental\",\n", + " \"onErrorDeployment\": null,\n", + " \"outputResources\": [\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ApiManagement/service/apim-vu4ax6chjqjsk\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceType\": \"Microsoft.ApiManagement/service\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ApiManagement/service/apim-vu4ax6chjqjsk/apis/inference-api\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceType\": \"Microsoft.ApiManagement/service/apis\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ApiManagement/service/apim-vu4ax6chjqjsk/apis/inference-api/diagnostics/applicationinsights\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceType\": \"Microsoft.ApiManagement/service/apis/diagnostics\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ApiManagement/service/apim-vu4ax6chjqjsk/apis/inference-api/diagnostics/azuremonitor\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceType\": \"Microsoft.ApiManagement/service/apis/diagnostics\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ApiManagement/service/apim-vu4ax6chjqjsk/apis/inference-api/policies/policy\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceType\": \"Microsoft.ApiManagement/service/apis/policies\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ApiManagement/service/apim-vu4ax6chjqjsk/backends/foundry-agents\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceType\": \"Microsoft.ApiManagement/service/backends\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ApiManagement/service/apim-vu4ax6chjqjsk/backends/foundry-models\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceType\": \"Microsoft.ApiManagement/service/backends\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ApiManagement/service/apim-vu4ax6chjqjsk/backends/inference-backend-pool\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceType\": \"Microsoft.ApiManagement/service/backends\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ApiManagement/service/apim-vu4ax6chjqjsk/loggers/appinsights-logger\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceType\": \"Microsoft.ApiManagement/service/loggers\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ApiManagement/service/apim-vu4ax6chjqjsk/loggers/azuremonitor\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceType\": \"Microsoft.ApiManagement/service/loggers\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ApiManagement/service/apim-vu4ax6chjqjsk/providers/Microsoft.Insights/diagnosticSettings/apimDiagnosticSettings\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceType\": \"Microsoft.Insights/diagnosticSettings\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ApiManagement/service/apim-vu4ax6chjqjsk/subscriptions/starter\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceType\": \"Microsoft.ApiManagement/service/subscriptions\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.CognitiveServices/accounts/foundry-agents-vu4ax6chjqjsk\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceType\": \"Microsoft.CognitiveServices/accounts\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.CognitiveServices/accounts/foundry-agents-vu4ax6chjqjsk/connections/foundry-agents-vu4ax6chjqjsk-appInsights-connection\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceType\": \"Microsoft.CognitiveServices/accounts/connections\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.CognitiveServices/accounts/foundry-agents-vu4ax6chjqjsk/projects/default-foundry-agents\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceType\": \"Microsoft.CognitiveServices/accounts/projects\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.CognitiveServices/accounts/foundry-agents-vu4ax6chjqjsk/providers/Microsoft.Authorization/roleAssignments/b81335fb-f585-5a98-b1d3-b05ccfc27073\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.CognitiveServices/accounts/foundry-agents-vu4ax6chjqjsk/providers/Microsoft.Authorization/roleAssignments/d45230ae-0cb5-50d7-89ec-f52d6e03a1eb\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.CognitiveServices/accounts/foundry-agents-vu4ax6chjqjsk/providers/Microsoft.Authorization/roleAssignments/ff4f129c-e3f6-5883-b38a-1c5bc316a76e\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.CognitiveServices/accounts/foundry-models-vu4ax6chjqjsk\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceType\": \"Microsoft.CognitiveServices/accounts\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.CognitiveServices/accounts/foundry-models-vu4ax6chjqjsk/connections/foundry-models-vu4ax6chjqjsk-appInsights-connection\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceType\": \"Microsoft.CognitiveServices/accounts/connections\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.CognitiveServices/accounts/foundry-models-vu4ax6chjqjsk/deployments/gpt-5-mini\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceType\": \"Microsoft.CognitiveServices/accounts/deployments\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.CognitiveServices/accounts/foundry-models-vu4ax6chjqjsk/projects/default-foundry-models\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceType\": \"Microsoft.CognitiveServices/accounts/projects\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.CognitiveServices/accounts/foundry-models-vu4ax6chjqjsk/providers/Microsoft.Authorization/roleAssignments/219a9a8c-8372-5217-8a2e-f11f82a3b4b0\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.CognitiveServices/accounts/foundry-models-vu4ax6chjqjsk/providers/Microsoft.Authorization/roleAssignments/9857ad42-3883-5922-9a5d-0ed64839c8db\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.CognitiveServices/accounts/foundry-models-vu4ax6chjqjsk/providers/Microsoft.Authorization/roleAssignments/ded6fc2f-cd1d-51cb-af6c-3562b9dcbf8c\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrvu4ax6chjqjsk\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceType\": \"Microsoft.ContainerRegistry/registries\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrvu4ax6chjqjsk/providers/Microsoft.Authorization/roleAssignments/6801f057-9c94-548e-af97-b7aa48df6191\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrvu4ax6chjqjsk/providers/Microsoft.Authorization/roleAssignments/9723640a-c519-5fbd-8169-28d574b21f8f\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrvu4ax6chjqjsk/providers/Microsoft.Authorization/roleAssignments/eb950c04-f5c5-5133-b32d-b544c7b7681c\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Insights/components/insights-vu4ax6chjqjsk\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceType\": \"Microsoft.Insights/components\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.OperationalInsights/workspaces/workspace-vu4ax6chjqjsk\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceType\": \"Microsoft.OperationalInsights/workspaces\"\n", + " }\n", + " ],\n", + " \"outputs\": {\n", + " \"aiGatewayUrl\": {\n", + " \"type\": \"String\",\n", + " \"value\": \"https://apim-vu4ax6chjqjsk.azure-api.net/inference\"\n", + " },\n", + " \"apimGatewayUrl\": {\n", + " \"type\": \"String\",\n", + " \"value\": \"https://apim-vu4ax6chjqjsk.azure-api.net\"\n", + " },\n", + " \"apimServiceId\": {\n", + " \"type\": \"String\",\n", + " \"value\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ApiManagement/service/apim-vu4ax6chjqjsk\"\n", + " },\n", + " \"apimSubscriptions\": {\n", + " \"type\": \"Array\",\n", + " \"value\": [\n", + " {\n", + " \"displayName\": \"Starter\",\n", + " \"key\": \"da1b83bcbd6e45f4b94501061e298591\",\n", + " \"name\": \"starter\"\n", + " }\n", + " ]\n", + " },\n", + " \"containerRegistryLoginServer\": {\n", + " \"type\": \"String\",\n", + " \"value\": \"acrvu4ax6chjqjsk.azurecr.io\"\n", + " },\n", + " \"containerRegistryName\": {\n", + " \"type\": \"String\",\n", + " \"value\": \"acrvu4ax6chjqjsk\"\n", + " },\n", + " \"foundryAgentAiServicesEndpoint\": {\n", + " \"type\": \"String\",\n", + " \"value\": \"https://foundry-agents-vu4ax6chjqjsk.cognitiveservices.azure.com/\"\n", + " },\n", + " \"foundryAgentProjectEndpoint\": {\n", + " \"type\": \"String\",\n", + " \"value\": \"https://foundry-agents-vu4ax6chjqjsk.services.ai.azure.com/api/projects/default-foundry-agents\"\n", + " },\n", + " \"foundryAiServicesEndpoint\": {\n", + " \"type\": \"String\",\n", + " \"value\": \"https://foundry-models-vu4ax6chjqjsk.cognitiveservices.azure.com/\"\n", + " },\n", + " \"foundryProjectEndpoint\": {\n", + " \"type\": \"String\",\n", + " \"value\": \"https://foundry-models-vu4ax6chjqjsk.services.ai.azure.com/api/projects/default-foundry-models\"\n", + " },\n", + " \"hostedAgentResponsesApimPath\": {\n", + " \"type\": \"String\",\n", + " \"value\": \"\"\n", + " },\n", + " \"logAnalyticsWorkspaceId\": {\n", + " \"type\": \"String\",\n", + " \"value\": \"56c0f43f-b689-49a2-b2c3-0a14b9a61ebb\"\n", + " }\n", + " },\n", + " \"parameters\": {\n", + " \"aiServicesConfig\": {\n", + " \"type\": \"Array\",\n", + " \"value\": [\n", + " {\n", + " \"location\": \"swedencentral\",\n", + " \"name\": \"foundry-models\",\n", + " \"priority\": 1,\n", + " \"weight\": 100\n", + " },\n", + " {\n", + " \"location\": \"swedencentral\",\n", + " \"name\": \"foundry-agents\",\n", + " \"priority\": 1,\n", + " \"weight\": 100\n", + " }\n", + " ]\n", + " },\n", + " \"apimSku\": {\n", + " \"type\": \"String\",\n", + " \"value\": \"Basicv2\"\n", + " },\n", + " \"apimSubscriptionsConfig\": {\n", + " \"type\": \"Array\",\n", + " \"value\": [\n", + " {\n", + " \"displayName\": \"Starter\",\n", + " \"name\": \"starter\",\n", + " \"scope\": \"/apis\"\n", + " }\n", + " ]\n", + " },\n", + " \"enableHostedAgentResponsesApi\": {\n", + " \"type\": \"Bool\",\n", + " \"value\": false\n", + " },\n", + " \"foundryAgentAiServiceIndex\": {\n", + " \"type\": \"Int\",\n", + " \"value\": 1\n", + " },\n", + " \"foundryProjectName\": {\n", + " \"type\": \"String\",\n", + " \"value\": \"default\"\n", + " },\n", + " \"foundryUserObjectIds\": {\n", + " \"type\": \"Array\",\n", + " \"value\": [\n", + " \"13f94c0d-8a51-492a-928b-59392c23c1ac\"\n", + " ]\n", + " },\n", + " \"hostedAgentId\": {\n", + " \"type\": \"String\",\n", + " \"value\": \"\"\n", + " },\n", + " \"hostedAgentResponsesApiPath\": {\n", + " \"type\": \"String\",\n", + " \"value\": \"hosted-agent-responses\"\n", + " },\n", + " \"hostedAgentResponsesApiVersion\": {\n", + " \"type\": \"String\",\n", + " \"value\": \"2025-05-15-preview\"\n", + " },\n", + " \"inferenceAPIPath\": {\n", + " \"type\": \"String\",\n", + " \"value\": \"inference\"\n", + " },\n", + " \"inferenceAPIType\": {\n", + " \"type\": \"String\",\n", + " \"value\": \"AzureAI\"\n", + " },\n", + " \"modelsConfig\": {\n", + " \"type\": \"Array\",\n", + " \"value\": [\n", + " {\n", + " \"aiservice\": \"foundry-models\",\n", + " \"capacity\": 10,\n", + " \"name\": \"gpt-5-mini\",\n", + " \"publisher\": \"OpenAI\",\n", + " \"sku\": \"GlobalStandard\",\n", + " \"version\": \"2025-08-07\"\n", + " }\n", + " ]\n", + " }\n", + " },\n", + " \"parametersLink\": null,\n", + " \"providers\": [\n", + " {\n", + " \"id\": null,\n", + " \"namespace\": \"Microsoft.ContainerRegistry\",\n", + " \"providerAuthorizationConsentState\": null,\n", + " \"registrationPolicy\": null,\n", + " \"registrationState\": null,\n", + " \"resourceTypes\": [\n", + " {\n", + " \"aliases\": null,\n", + " \"apiProfiles\": null,\n", + " \"apiVersions\": null,\n", + " \"capabilities\": null,\n", + " \"defaultApiVersion\": null,\n", + " \"locationMappings\": null,\n", + " \"locations\": [\n", + " \"swedencentral\"\n", + " ],\n", + " \"properties\": null,\n", + " \"resourceType\": \"registries\",\n", + " \"zoneMappings\": null\n", + " }\n", + " ]\n", + " },\n", + " {\n", + " \"id\": null,\n", + " \"namespace\": \"Microsoft.Authorization\",\n", + " \"providerAuthorizationConsentState\": null,\n", + " \"registrationPolicy\": null,\n", + " \"registrationState\": null,\n", + " \"resourceTypes\": [\n", + " {\n", + " \"aliases\": null,\n", + " \"apiProfiles\": null,\n", + " \"apiVersions\": null,\n", + " \"capabilities\": null,\n", + " \"defaultApiVersion\": null,\n", + " \"locationMappings\": null,\n", + " \"locations\": [\n", + " null\n", + " ],\n", + " \"properties\": null,\n", + " \"resourceType\": \"roleAssignments\",\n", + " \"zoneMappings\": null\n", + " }\n", + " ]\n", + " },\n", + " {\n", + " \"id\": null,\n", + " \"namespace\": \"Microsoft.Resources\",\n", + " \"providerAuthorizationConsentState\": null,\n", + " \"registrationPolicy\": null,\n", + " \"registrationState\": null,\n", + " \"resourceTypes\": [\n", + " {\n", + " \"aliases\": null,\n", + " \"apiProfiles\": null,\n", + " \"apiVersions\": null,\n", + " \"capabilities\": null,\n", + " \"defaultApiVersion\": null,\n", + " \"locationMappings\": null,\n", + " \"locations\": [\n", + " null\n", + " ],\n", + " \"properties\": null,\n", + " \"resourceType\": \"deployments\",\n", + " \"zoneMappings\": null\n", + " }\n", + " ]\n", + " }\n", + " ],\n", + " \"provisioningState\": \"Succeeded\",\n", + " \"templateHash\": \"5327887757473726207\",\n", + " \"templateLink\": null,\n", + " \"timestamp\": \"2026-07-08T13:26:39.315593+00:00\",\n", + " \"validatedResources\": null,\n", + " \"validationLevel\": null\n", + " },\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"tags\": null,\n", + " \"type\": \"Microsoft.Resources/deployments\"\n", + "}\n", + "\n" + ] + } + ], + "source": [ + "# Create resource group and deploy Bicep\n", + "# Ensure Azure CLI directory is available to subprocess calls in this kernel\n", + "az_dir = str(Path(az_cmd).parent)\n", + "if az_dir not in os.environ.get('PATH', ''):\n", + " os.environ['PATH'] = az_dir + os.pathsep + os.environ.get('PATH', '')\n", + "\n", + "def az_run(args):\n", + " command = ['cmd', '/c', az_cmd, *args] if az_cmd.lower().endswith('.cmd') else [az_cmd, *args]\n", + " return run(command)\n", + "\n", + "az_run(['account', 'set', '--subscription', subscription_id])\n", + "az_run(['group', 'create', '--name', resource_group, '--location', location])\n", + "\n", + "parameters_file = lab_dir / 'main.parameters.generated.json'\n", + "parameters = {\n", + " '$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#',\n", + " 'contentVersion': '1.0.0.0',\n", + " 'parameters': {\n", + " 'aiServicesConfig': {'value': ai_services_config},\n", + " 'modelsConfig': {'value': models_config},\n", + " 'apimSku': {'value': 'Basicv2'},\n", + " 'apimSubscriptionsConfig': {'value': apim_subscriptions},\n", + " 'inferenceAPIPath': {'value': 'inference'},\n", + " 'inferenceAPIType': {'value': 'AzureAI'},\n", + " 'foundryProjectName': {'value': 'default'},\n", + " 'foundryAgentAiServiceIndex': {'value': 1},\n", + " 'foundryUserObjectIds': {'value': foundry_user_object_ids},\n", + " 'enableHostedAgentResponsesApi': {'value': enable_hosted_agent_responses_api},\n", + " 'hostedAgentId': {'value': hosted_agent_id},\n", + " 'hostedAgentResponsesApiPath': {'value': 'hosted-agent-responses'},\n", + " 'hostedAgentResponsesApiVersion': {'value': '2025-05-15-preview'}\n", + " }\n", + "}\n", + "\n", + "parameters_file.write_text(json.dumps(parameters, indent=2), encoding='utf-8')\n", + "print(f'Wrote parameters: {parameters_file}')\n", + "\n", + "# Ensure Bicep is available, then validate before create\n", + "az_run(['bicep', 'install'])\n", + "\n", + "template_file = str((lab_dir / 'main.bicep').resolve())\n", + "parameters_arg = f\"@{parameters_file.resolve()}\"\n", + "\n", + "# Validate first, but do not stop the notebook on transient/CLI validation failures.\n", + "try:\n", + " az_run([\n", + " 'deployment', 'group', 'validate',\n", + " '--resource-group', resource_group,\n", + " '--template-file', template_file,\n", + " '--parameters', parameters_arg,\n", + " '--only-show-errors'\n", + " ])\n", + "except RuntimeError as ex:\n", + " print(f'Validation failed, continuing to deployment create step: {ex}')\n", + "\n", + "result = az_run([\n", + " 'deployment', 'group', 'create',\n", + " '--resource-group', resource_group,\n", + " '--name', deployment_name,\n", + " '--template-file', template_file,\n", + " '--parameters', parameters_arg,\n", + " '--only-show-errors'\n", + "])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a9f37375", + "metadata": {}, + "outputs": [], + "source": [ + "# Print key outputs\n", + "outputs = run([\n", + " 'az', 'deployment', 'group', 'show',\n", + " '--resource-group', resource_group,\n", + " '--name', deployment_name,\n", + " '--query', 'properties.outputs',\n", + " '-o', 'json'\n", + "]).stdout\n", + "print(json.dumps(json.loads(outputs), indent=2))" + ] + }, + { + "cell_type": "markdown", + "id": "d0249aaa", + "metadata": {}, + "source": [ + "## Next step\n", + "\n", + "1. Run this notebook once to deploy Foundry and APIM.\n", + "2. Use one of the framework notebooks under `src/responses/agents/` to build, push, and deploy the hosted agent.\n", + "3. Set `hosted_agent_id` and `enable_hosted_agent_responses_api=True` in the config cell.\n", + "4. Re-run this notebook to add the APIM front door for the Hosted Agent Responses API.\n", + "5. Call APIM at the `hostedAgentResponsesApimPath` output endpoint." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.10" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/labs/ai-foundry-hosted-agents-custom-framework/clean-up-resources.ipynb b/labs/ai-foundry-hosted-agents-custom-framework/clean-up-resources.ipynb new file mode 100644 index 00000000..6fe73c08 --- /dev/null +++ b/labs/ai-foundry-hosted-agents-custom-framework/clean-up-resources.ipynb @@ -0,0 +1,110 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "2feb47db", + "metadata": {}, + "source": [ + "# Clean Up Resources\n", + "\n", + "This notebook removes the resource group created for the `ai-foundry-hosted-agents-custom-framework` lab." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3ab6bfd0", + "metadata": {}, + "outputs": [], + "source": [ + "import shutil\n", + "import subprocess\n", + "import sys\n", + "\n", + "_az = (\n", + " shutil.which(\"az\")\n", + " or shutil.which(\"az.cmd\")\n", + " or r\"C:\\Program Files\\Microsoft SDKs\\Azure\\CLI2\\wbin\\az.CMD\"\n", + " )\n", + "\n", + "if not _az:\n", + " raise FileNotFoundError(\n", + " \"Azure CLI executable was not found. Install Azure CLI or add it to PATH.\"\n", + " )\n", + "\n", + "def run(cmd):\n", + " if cmd and cmd[0] == \"az\":\n", + " cmd = [_az] + cmd[1:]\n", + " print(\"\\n$ \" + \" \".join(cmd))\n", + " result = subprocess.run(cmd, capture_output=True, text=True)\n", + " if result.stdout:\n", + " print(result.stdout)\n", + " if result.returncode != 0:\n", + " if result.stderr:\n", + " print(result.stderr)\n", + " raise RuntimeError(f\"Command failed: {result.returncode}\")\n", + "\n", + "subscription_id = \"baba41cf-c01d-4a55-b6c5-ca494b802be5\"\n", + "resource_group = \"rg-aigw-hosted-custom-framework\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5083d437", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "$ az account set --subscription baba41cf-c01d-4a55-b6c5-ca494b802be5\n" + ] + }, + { + "ename": "FileNotFoundError", + "evalue": "[WinError 2] The system cannot find the file specified", + "output_type": "error", + "traceback": [ + "\u001b[31m---------------------------------------------------------------------------\u001b[39m", + "\u001b[31mFileNotFoundError\u001b[39m Traceback (most recent call last)", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[2]\u001b[39m\u001b[32m, line 2\u001b[39m\n\u001b[32m 1\u001b[39m \u001b[38;5;66;03m# Delete lab resources\u001b[39;00m\n\u001b[32m----> \u001b[39m\u001b[32m2\u001b[39m run([\u001b[33m'az'\u001b[39m, \u001b[33m'account'\u001b[39m, \u001b[33m'set'\u001b[39m, \u001b[33m'--subscription'\u001b[39m, subscription_id])\n\u001b[32m 3\u001b[39m run([\u001b[33m'az'\u001b[39m, \u001b[33m'group'\u001b[39m, \u001b[33m'delete'\u001b[39m, \u001b[33m'--name'\u001b[39m, resource_group, \u001b[33m'--yes'\u001b[39m, \u001b[33m'--no-wait'\u001b[39m])\n\u001b[32m 4\u001b[39m print(\u001b[33m'Deletion started. Use az group show to verify completion.'\u001b[39m)\n", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[1]\u001b[39m\u001b[32m, line 5\u001b[39m, in \u001b[36mrun\u001b[39m\u001b[34m(cmd)\u001b[39m\n\u001b[32m 3\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m run(cmd):\n\u001b[32m 4\u001b[39m print(\u001b[33m'\\n$ '\u001b[39m + \u001b[33m' '\u001b[39m.join(cmd))\n\u001b[32m----> \u001b[39m\u001b[32m5\u001b[39m result = subprocess.run(cmd, capture_output=\u001b[38;5;28;01mTrue\u001b[39;00m, text=\u001b[38;5;28;01mTrue\u001b[39;00m)\n\u001b[32m 6\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m result.stdout:\n\u001b[32m 7\u001b[39m print(result.stdout)\n\u001b[32m 8\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m result.returncode != \u001b[32m0\u001b[39m:\n", + "\u001b[36mFile \u001b[39m\u001b[32mc:\\Users\\ollisgeorge\\AppData\\Local\\Programs\\Python\\Python312-x64\\Lib\\subprocess.py:548\u001b[39m, in \u001b[36mrun\u001b[39m\u001b[34m(input, capture_output, timeout, check, *popenargs, **kwargs)\u001b[39m\n\u001b[32m 545\u001b[39m kwargs[\u001b[33m'\u001b[39m\u001b[33mstdout\u001b[39m\u001b[33m'\u001b[39m] = PIPE\n\u001b[32m 546\u001b[39m kwargs[\u001b[33m'\u001b[39m\u001b[33mstderr\u001b[39m\u001b[33m'\u001b[39m] = PIPE\n\u001b[32m--> \u001b[39m\u001b[32m548\u001b[39m \u001b[38;5;28;01mwith\u001b[39;00m \u001b[30;43mPopen\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43mpopenargs\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43mkwargs\u001b[39;49m\u001b[30;43m)\u001b[39;49m \u001b[38;5;28;01mas\u001b[39;00m process:\n\u001b[32m 549\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m 550\u001b[39m stdout, stderr = process.communicate(\u001b[38;5;28minput\u001b[39m, timeout=timeout)\n", + "\u001b[36mFile \u001b[39m\u001b[32mc:\\Users\\ollisgeorge\\AppData\\Local\\Programs\\Python\\Python312-x64\\Lib\\subprocess.py:1026\u001b[39m, in \u001b[36mPopen.__init__\u001b[39m\u001b[34m(self, args, bufsize, executable, stdin, stdout, stderr, preexec_fn, close_fds, shell, cwd, env, universal_newlines, startupinfo, creationflags, restore_signals, start_new_session, pass_fds, user, group, extra_groups, encoding, errors, text, umask, pipesize, process_group)\u001b[39m\n\u001b[32m 1022\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m.text_mode:\n\u001b[32m 1023\u001b[39m \u001b[38;5;28mself\u001b[39m.stderr = io.TextIOWrapper(\u001b[38;5;28mself\u001b[39m.stderr,\n\u001b[32m 1024\u001b[39m encoding=encoding, errors=errors)\n\u001b[32m-> \u001b[39m\u001b[32m1026\u001b[39m \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43m_execute_child\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43margs\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mexecutable\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mpreexec_fn\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mclose_fds\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 1027\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mpass_fds\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mcwd\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43menv\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 1028\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mstartupinfo\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mcreationflags\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mshell\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 1029\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mp2cread\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mp2cwrite\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 1030\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mc2pread\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mc2pwrite\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 1031\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43merrread\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43merrwrite\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 1032\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mrestore_signals\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 1033\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mgid\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mgids\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43muid\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mumask\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 1034\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mstart_new_session\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mprocess_group\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 1035\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m:\n\u001b[32m 1036\u001b[39m \u001b[38;5;66;03m# Cleanup if the child failed starting.\u001b[39;00m\n\u001b[32m 1037\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m f \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mfilter\u001b[39m(\u001b[38;5;28;01mNone\u001b[39;00m, (\u001b[38;5;28mself\u001b[39m.stdin, \u001b[38;5;28mself\u001b[39m.stdout, \u001b[38;5;28mself\u001b[39m.stderr)):\n", + "\u001b[36mFile \u001b[39m\u001b[32mc:\\Users\\ollisgeorge\\AppData\\Local\\Programs\\Python\\Python312-x64\\Lib\\subprocess.py:1538\u001b[39m, in \u001b[36mPopen._execute_child\u001b[39m\u001b[34m(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, unused_restore_signals, unused_gid, unused_gids, unused_uid, unused_umask, unused_start_new_session, unused_process_group)\u001b[39m\n\u001b[32m 1536\u001b[39m \u001b[38;5;66;03m# Start the process\u001b[39;00m\n\u001b[32m 1537\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m-> \u001b[39m\u001b[32m1538\u001b[39m hp, ht, pid, tid = \u001b[30;43m_winapi\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mCreateProcess\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43mexecutable\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43margs\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 1539\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43;03m# no special security\u001b[39;49;00m\n\u001b[32m 1540\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43;01mNone\u001b[39;49;00m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43;01mNone\u001b[39;49;00m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 1541\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mint\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43;01mnot\u001b[39;49;00m\u001b[30;43m \u001b[39;49m\u001b[30;43mclose_fds\u001b[39;49m\u001b[30;43m)\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 1542\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mcreationflags\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 1543\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43menv\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 1544\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mcwd\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 1545\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mstartupinfo\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 1546\u001b[39m \u001b[38;5;28;01mfinally\u001b[39;00m:\n\u001b[32m 1547\u001b[39m \u001b[38;5;66;03m# Child is launched. Close the parent's copy of those pipe\u001b[39;00m\n\u001b[32m 1548\u001b[39m \u001b[38;5;66;03m# handles that only the child should have open. You need\u001b[39;00m\n\u001b[32m (...)\u001b[39m\u001b[32m 1551\u001b[39m \u001b[38;5;66;03m# pipe will not close when the child process exits and the\u001b[39;00m\n\u001b[32m 1552\u001b[39m \u001b[38;5;66;03m# ReadFile will hang.\u001b[39;00m\n\u001b[32m 1553\u001b[39m \u001b[38;5;28mself\u001b[39m._close_pipe_fds(p2cread, p2cwrite,\n\u001b[32m 1554\u001b[39m c2pread, c2pwrite,\n\u001b[32m 1555\u001b[39m errread, errwrite)\n", + "\u001b[31mFileNotFoundError\u001b[39m: [WinError 2] The system cannot find the file specified" + ] + } + ], + "source": [ + "# Delete lab resources\n", + "run([\"az\", \"account\", \"set\", \"--subscription\", subscription_id])\n", + "run([\"az\", \"group\", \"delete\", \"--name\", resource_group, \"--yes\", \"--no-wait\"])\n", + "print(\"Deletion started. Use az group show to verify completion.\")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.10" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/labs/ai-foundry-hosted-agents-custom-framework/main.bicep b/labs/ai-foundry-hosted-agents-custom-framework/main.bicep new file mode 100644 index 00000000..a282bc84 --- /dev/null +++ b/labs/ai-foundry-hosted-agents-custom-framework/main.bicep @@ -0,0 +1,255 @@ +// ------------------ +// PARAMETERS +// ------------------ + +@description('Configuration array for AI Services. Each item needs name and location.') +param aiServicesConfig array = [] + +@description('Configuration array for model deployments.') +param modelsConfig array = [] + +@description('SKU for the API Management instance') +param apimSku string = 'Basicv2' + +@description('Configuration array for APIM subscriptions') +param apimSubscriptionsConfig array = [] + +@description('Path for the inference API exposed in APIM') +param inferenceAPIPath string = 'inference' + +@description('Type of inference API') +param inferenceAPIType string = 'AzureAI' + +@description('Name of the AI Foundry project') +param foundryProjectName string = 'default' + +@description('Index of the AI Services config entry that hosts the Foundry hosted agents (default: second entry).') +param foundryAgentAiServiceIndex int = 1 + +@description('Microsoft Entra object IDs to assign Foundry User (Azure AI User) across all Foundry resources in this deployment.') +param foundryUserObjectIds array = [] + +@description('Enable APIM proxy API for a deployed Hosted Agent Responses endpoint.') +param enableHostedAgentResponsesApi bool = false + +@description('Hosted Agent ID to proxy via APIM (required when enableHostedAgentResponsesApi=true).') +param hostedAgentId string = '' + +@description('APIM path for hosted agent responses API.') +param hostedAgentResponsesApiPath string = 'hosted-agent-responses' + +@description('Hosted Agent Responses API version appended by APIM policy.') +param hostedAgentResponsesApiVersion string = '2025-05-15-preview' + +// ------------------ +// VARIABLES +// ------------------ + +var resourceSuffix = uniqueString(subscription().id, resourceGroup().id) +var apiManagementName = 'apim-${resourceSuffix}' +var azureAIUserRoleDefinitionId = resourceId('Microsoft.Authorization/roleDefinitions', '53ca6127-db72-4b80-b1b0-d745d6d5456d') + +// ------------------ +// RESOURCES +// ------------------ + +// 1. Log Analytics Workspace +module lawModule '../../modules/operational-insights/v1/workspaces.bicep' = { + name: 'lawModule' +} + +// 2. Application Insights +module appInsightsModule '../../modules/monitor/v1/appinsights.bicep' = { + name: 'appInsightsModule' + params: { + lawId: lawModule.outputs.id + customMetricsOptedInType: 'WithDimensions' + } +} + +// 3. API Management +module apimModule '../../modules/apim/v3/apim.bicep' = { + name: 'apimModule' + params: { + apimSku: apimSku + apimSubscriptionsConfig: apimSubscriptionsConfig + lawId: lawModule.outputs.id + appInsightsId: appInsightsModule.outputs.id + appInsightsInstrumentationKey: appInsightsModule.outputs.instrumentationKey + } +} + +// 4. AI Foundry with model deployments (for example, gpt-5-mini) +module foundryModule '../../modules/cognitive-services/v3/foundry.bicep' = { + name: 'foundryModule' + params: { + aiServicesConfig: aiServicesConfig + modelsConfig: modelsConfig + apimPrincipalId: apimModule.outputs.principalId + foundryProjectName: foundryProjectName + appInsightsId: appInsightsModule.outputs.id + appInsightsInstrumentationKey: appInsightsModule.outputs.instrumentationKey + } +} + +// Foundry accounts created by the module, referenced here for RBAC assignments. +resource aiFoundryAccounts 'Microsoft.CognitiveServices/accounts@2025-06-01' existing = [for config in aiServicesConfig: { + name: '${config.name}-${resourceSuffix}' +}] + +// 5. APIM Inference API pointing to Foundry/AI Services +module inferenceAPIModule '../../modules/apim/v3/inference-api.bicep' = { + name: 'inferenceAPIModule' + params: { + policyXml: loadTextContent('policy.xml') + apimLoggerId: apimModule.outputs.loggerId + appInsightsId: appInsightsModule.outputs.id + appInsightsInstrumentationKey: appInsightsModule.outputs.instrumentationKey + aiServicesConfig: foundryModule.outputs.extendedAIServicesConfig + inferenceAPIType: inferenceAPIType + inferenceAPIPath: inferenceAPIPath + } +} + +// 6. Container Registry (for hosted agent images) +resource containerRegistry 'Microsoft.ContainerRegistry/registries@2023-11-01-preview' = { + name: 'acr${resourceSuffix}' + location: resourceGroup().location + sku: { + name: 'Basic' + } + properties: { + adminUserEnabled: true + anonymousPullEnabled: false + publicNetworkAccess: 'Enabled' + } +} + +// Assign Foundry User role for all provided users on the model-hosting Foundry resource. +resource modelFoundryUserRoleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for principalId in foundryUserObjectIds: { + name: guid(resourceGroup().id, aiFoundryAccounts[0].id, principalId, azureAIUserRoleDefinitionId) + scope: aiFoundryAccounts[0] + properties: { + roleDefinitionId: azureAIUserRoleDefinitionId + principalId: principalId + principalType: 'User' + } +}] + +// Assign Foundry User role for all provided users on the hosted-agent Foundry resource. +resource agentFoundryUserRoleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for principalId in foundryUserObjectIds: { + name: guid(resourceGroup().id, aiFoundryAccounts[foundryAgentAiServiceIndex].id, principalId, azureAIUserRoleDefinitionId) + scope: aiFoundryAccounts[foundryAgentAiServiceIndex] + properties: { + roleDefinitionId: azureAIUserRoleDefinitionId + principalId: principalId + principalType: 'User' + } +}] + +// Repository-level ACR roles (ABAC-enabled roles) +var acrRepositoryReaderRoleId = resourceId('Microsoft.Authorization/roleDefinitions', 'b93aa761-3e63-49ed-ac28-beffa264f7ac') +var acrRepositoryWriterRoleId = resourceId('Microsoft.Authorization/roleDefinitions', '2a1e307c-b015-4ebd-883e-5b7698a07328') +var acrRepositoryCatalogListerRoleId = resourceId('Microsoft.Authorization/roleDefinitions', 'bfdb9389-c9a5-478a-bb2f-ba9ca092c3c7') +var foundryAgentAccountName = '${aiServicesConfig[foundryAgentAiServiceIndex].name}-${resourceSuffix}' + +resource foundryAgentAcrRepositoryReaderRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid(resourceGroup().id, foundryAgentAccountName, acrRepositoryReaderRoleId) + scope: containerRegistry + properties: { + roleDefinitionId: acrRepositoryReaderRoleId + principalId: foundryModule.outputs.extendedAIServicesConfig[foundryAgentAiServiceIndex].principalId + principalType: 'ServicePrincipal' + } +} + +resource deployerAcrRepositoryWriterRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid(resourceGroup().id, deployer().objectId, containerRegistry.id, acrRepositoryWriterRoleId) + scope: containerRegistry + properties: { + roleDefinitionId: acrRepositoryWriterRoleId + principalId: deployer().objectId + } +} + +resource deployerAcrRepositoryCatalogListerRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid(resourceGroup().id, deployer().objectId, containerRegistry.id, acrRepositoryCatalogListerRoleId) + scope: containerRegistry + properties: { + roleDefinitionId: acrRepositoryCatalogListerRoleId + principalId: deployer().objectId + } +} + +// Existing APIM service reference for custom API resources. +resource apimService 'Microsoft.ApiManagement/service@2024-06-01-preview' existing = { + name: apiManagementName + dependsOn: [ + apimModule + ] +} + +// Proxy Hosted Agent Responses API through APIM once a hosted agent is deployed. +resource hostedAgentResponsesApi 'Microsoft.ApiManagement/service/apis@2024-06-01-preview' = if(enableHostedAgentResponsesApi && !empty(hostedAgentId)) { + name: 'hosted-agent-responses-api' + parent: apimService + properties: { + apiType: 'http' + description: 'Proxy for Azure AI Foundry Hosted Agent Responses API' + displayName: 'Hosted Agent Responses API' + path: hostedAgentResponsesApiPath + protocols: [ + 'https' + ] + serviceUrl: '${foundryModule.outputs.extendedAIServicesConfig[foundryAgentAiServiceIndex].foundryProjectEndpoint}/agents/${hostedAgentId}' + subscriptionKeyParameterNames: { + header: 'api-key' + query: 'api-key' + } + subscriptionRequired: true + type: 'http' + } +} + +resource hostedAgentResponsesOperation 'Microsoft.ApiManagement/service/apis/operations@2024-06-01-preview' = if(enableHostedAgentResponsesApi && !empty(hostedAgentId)) { + name: 'create-response' + parent: hostedAgentResponsesApi + properties: { + displayName: 'Create Hosted Agent Response' + method: 'POST' + urlTemplate: '/responses' + templateParameters: [] + responses: [ + { + statusCode: 200 + description: 'Successful response' + } + ] + } +} + +resource hostedAgentResponsesApiPolicy 'Microsoft.ApiManagement/service/apis/policies@2024-06-01-preview' = if(enableHostedAgentResponsesApi && !empty(hostedAgentId)) { + name: 'policy' + parent: hostedAgentResponsesApi + properties: { + format: 'rawxml' + value: '@("Bearer " + (string)context.Variables["managed-id-access-token"])${hostedAgentResponsesApiVersion}' + } +} + +// ------------------ +// OUTPUTS +// ------------------ + +output logAnalyticsWorkspaceId string = lawModule.outputs.customerId +output apimServiceId string = apimModule.outputs.id +output apimGatewayUrl string = apimModule.outputs.gatewayUrl +output apimSubscriptions array = apimModule.outputs.apimSubscriptions +output aiGatewayUrl string = '${apimModule.outputs.gatewayUrl}/${inferenceAPIPath}' +output foundryProjectEndpoint string = foundryModule.outputs.extendedAIServicesConfig[0].foundryProjectEndpoint +output foundryAiServicesEndpoint string = foundryModule.outputs.extendedAIServicesConfig[0].endpoint +output foundryAgentProjectEndpoint string = foundryModule.outputs.extendedAIServicesConfig[foundryAgentAiServiceIndex].foundryProjectEndpoint +output foundryAgentAiServicesEndpoint string = foundryModule.outputs.extendedAIServicesConfig[foundryAgentAiServiceIndex].endpoint +output containerRegistryName string = containerRegistry.name +output containerRegistryLoginServer string = containerRegistry.properties.loginServer +output hostedAgentResponsesApimPath string = enableHostedAgentResponsesApi && !empty(hostedAgentId) ? '${apimModule.outputs.gatewayUrl}/${hostedAgentResponsesApiPath}/responses' : '' diff --git a/labs/ai-foundry-hosted-agents-custom-framework/policy.xml b/labs/ai-foundry-hosted-agents-custom-framework/policy.xml new file mode 100644 index 00000000..b06e225f --- /dev/null +++ b/labs/ai-foundry-hosted-agents-custom-framework/policy.xml @@ -0,0 +1,19 @@ + + + + + + @("Bearer " + (string)context.Variables["managed-id-access-token"]) + + + + + + + + + + + + + diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/pydantic-ai/.dockerignore b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/pydantic-ai/.dockerignore new file mode 100644 index 00000000..1a7b9960 --- /dev/null +++ b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/pydantic-ai/.dockerignore @@ -0,0 +1,26 @@ +**/__pycache__/ +**/*.py[cod] +**/*.egg-info/ +.eggs/ + +# Virtual environments +.venv/ +venv/ +env/ + +# IDE settings +.vscode/ +.idea/ + +# Version control +.git/ +.gitignore + +# Docker files +.dockerignore + +# Docs +README.md + +# Local environment (never bake credentials into the image) +.env \ No newline at end of file diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/pydantic-ai/.gitignore b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/pydantic-ai/.gitignore new file mode 100644 index 00000000..ffdb3a31 --- /dev/null +++ b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/pydantic-ai/.gitignore @@ -0,0 +1,5 @@ +.venv/ +__pycache__/ +*.pyc +.env +agent_creation.py \ No newline at end of file diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/pydantic-ai/01_hosted_agent_pydantic_setup.ipynb b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/pydantic-ai/01_hosted_agent_pydantic_setup.ipynb new file mode 100644 index 00000000..70442702 --- /dev/null +++ b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/pydantic-ai/01_hosted_agent_pydantic_setup.ipynb @@ -0,0 +1,187 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "54d927d1", + "metadata": {}, + "source": [ + "# Pydantic AI Hosted Agent Setup\n", + "\n", + "This notebook helps you:\n", + "1. Build and push a container image for your Pydantic AI hosted agent code.\n", + "2. Create or update a hosted agent version from Python.\n", + "3. Grant Foundry role access to the hosted agent identity.\n", + "\n", + "## Prerequisites\n", + "- Your signed-in identity must have `Container Registry Repository Writer` on the target ACR repository (or equivalent push permission).\n", + "- The Azure Foundry project/resource identity must have pull access to the image in ACR (for example `Container Registry Repository Reader` or equivalent repository-level pull permission).\n", + "\n", + "Fill in all placeholder values before running code cells." + ] + }, + { + "cell_type": "markdown", + "id": "368f7a90", + "metadata": {}, + "source": [ + "## 1. Build And Push The Container Image\n", + "\n", + "This runs Azure Container Registry cloud build from the current pydantic-ai folder." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "733aa858", + "metadata": {}, + "outputs": [], + "source": [ + "# Set these placeholders\n", + "ACR_NAME = \"\"\n", + "IMAGE_NAME = \"\"\n", + "IMAGE_TAG = \"\"\n", + "\n", + "print(f\"ACR_NAME={ACR_NAME}\")\n", + "print(f\"IMAGE_NAME={IMAGE_NAME}\")\n", + "print(f\"IMAGE_TAG={IMAGE_TAG}\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0ee7f96c", + "metadata": {}, + "outputs": [], + "source": [ + "import subprocess\n", + "\n", + "build_cmd = [\n", + " \"az\", \"acr\", \"build\",\n", + " \"-t\", f\"{IMAGE_NAME}:{IMAGE_TAG}\",\n", + " \"-r\", ACR_NAME,\n", + " \"--source-acr-auth-id\", \"[caller]\",\n", + " \".\",\n", + "]\n", + "\n", + "print(\"Running:\", \" \".join(build_cmd))\n", + "subprocess.run(build_cmd, check=True)" + ] + }, + { + "cell_type": "markdown", + "id": "2614c4c5", + "metadata": {}, + "source": [ + "## 2. Create Hosted Agent Version\n", + "\n", + "Use this cell to register your hosted agent container image in Foundry.\n", + "\n", + "Install dependencies first if needed:\n", + "`pip install azure-ai-projects azure-identity`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2a7440bb", + "metadata": {}, + "outputs": [], + "source": [ + "from azure.ai.projects import AIProjectClient\n", + "from azure.ai.projects.models import (\n", + " HostedAgentDefinition,\n", + " ProtocolVersionRecord,\n", + " AgentProtocol,\n", + " ContainerConfiguration,\n", + ")\n", + "from azure.identity import DefaultAzureCredential\n", + "\n", + "# Placeholder values - update before running\n", + "PROJECT_ENDPOINT = \"https://.services.ai.azure.com/api/projects/\"\n", + "AGENT_NAME = \"\"\n", + "\n", + "ACR_LOGIN_SERVER = \".azurecr.io\"\n", + "IMAGE_NAME = \"\"\n", + "IMAGE_TAG = \"\"\n", + "IMAGE_URI = f\"{ACR_LOGIN_SERVER}/{IMAGE_NAME}:{IMAGE_TAG}\"\n", + "\n", + "# Environment variables passed to your containerized Pydantic AI app\n", + "AZURE_OPENAI_ENDPOINT = \"https://.openai.azure.com/\"\n", + "AZURE_OPENAI_API_VERSION = \"\"\n", + "AZURE_OPENAI_DEPLOYMENT = \"\"\n", + "\n", + "credential = DefaultAzureCredential()\n", + "project = AIProjectClient(\n", + " endpoint=PROJECT_ENDPOINT,\n", + " credential=credential,\n", + " allow_preview=True,\n", + ")\n", + "\n", + "agent = project.agents.create_version(\n", + " agent_name=AGENT_NAME,\n", + " definition=HostedAgentDefinition(\n", + " protocol_versions=[\n", + " ProtocolVersionRecord(protocol=AgentProtocol.RESPONSES, version=\"1.0.0\")\n", + " ],\n", + " cpu=\"1\",\n", + " memory=\"2Gi\",\n", + " container_configuration=ContainerConfiguration(image=IMAGE_URI),\n", + " environment_variables={\n", + " \"AZURE_OPENAI_ENDPOINT\": AZURE_OPENAI_ENDPOINT,\n", + " \"AZURE_OPENAI_API_VERSION\": AZURE_OPENAI_API_VERSION,\n", + " \"AZURE_OPENAI_DEPLOYMENT\": AZURE_OPENAI_DEPLOYMENT,\n", + " \"LOG_LEVEL\": \"INFO\",\n", + " },\n", + " ),\n", + ")\n", + "\n", + "print(f\"Agent created: {agent.name}, version: {agent.version}\")" + ] + }, + { + "cell_type": "markdown", + "id": "9633c110", + "metadata": {}, + "source": [ + "## 3. Grant Foundry User Role To The Hosted Agent Identity\n", + "\n", + "After the hosted agent version is created, Azure provisions an agent identity (service principal/object ID).\n", + "\n", + "Grant that identity the `Foundry User` role on your Foundry resource so it can access Foundry capabilities at runtime." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "91ce0d6e", + "metadata": {}, + "outputs": [], + "source": [ + "import subprocess\n", + "\n", + "# Placeholders - update these values\n", + "AGENT_IDENTITY_OBJECT_ID = \"\"\n", + "FOUNDRY_RESOURCE_ID = \"/subscriptions//resourceGroups//providers/Microsoft.CognitiveServices/accounts/\"\n", + "ROLE_NAME = \"Foundry User\"\n", + "\n", + "assign_cmd = [\n", + " \"az\", \"role\", \"assignment\", \"create\",\n", + " \"--assignee-object-id\", AGENT_IDENTITY_OBJECT_ID,\n", + " \"--assignee-principal-type\", \"ServicePrincipal\",\n", + " \"--role\", ROLE_NAME,\n", + " \"--scope\", FOUNDRY_RESOURCE_ID,\n", + "]\n", + "\n", + "print(\"Running:\", \" \".join(assign_cmd))\n", + "subprocess.run(assign_cmd, check=True)" + ] + } + ], + "metadata": { + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/pydantic-ai/Dockerfile b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/pydantic-ai/Dockerfile new file mode 100644 index 00000000..bf032f64 --- /dev/null +++ b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/pydantic-ai/Dockerfile @@ -0,0 +1,7 @@ +FROM python:3.12-slim +WORKDIR /app +COPY . user_agent/ +WORKDIR /app/user_agent +RUN if [ -f requirements.txt ]; then pip install -r requirements.txt; fi +EXPOSE 8088 +CMD ["python", "main.py"] \ No newline at end of file diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/pydantic-ai/README.md b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/pydantic-ai/README.md new file mode 100644 index 00000000..0fd74775 --- /dev/null +++ b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/pydantic-ai/README.md @@ -0,0 +1,32 @@ +# Pydantic AI Agent on Foundry Hosted Agents + +This sample code shows you how to run a Pydantic AI agent in Foundry Hosted Agents. + +![Pydantic AI Hosted Agent Sample](image.png) + +## What Is Included + +- `01_hosted_agent_pydantic_setup.ipynb`: End-to-end setup workbook. +- `main.py`: Pydantic AI agent server implementation (Responses protocol + tool calling + streaming). +- `Dockerfile`: Container definition for hosting the agent in Foundry Hosted Agents. +- `requirements.txt`: Python dependencies for your Pydantic AI runtime. + +## Get Started + +1. Open and run `01_hosted_agent_pydantic_setup.ipynb` from top to bottom. +2. Build and push the container image to your Azure Container Registry. +3. Create a hosted agent version in your Foundry project. +4. Grant required permissions (including Foundry role assignment for the hosted agent identity). +5. Test prompts against the deployed hosted agent. + +## Prerequisites + +- Azure subscription with access to Azure AI Foundry and Azure Container Registry. +- Permission to push images to the target ACR repository. +- Permission to assign RBAC roles on the Foundry resource scope. +- Python environment with the dependencies required by your Pydantic AI app. + +## Notes + +- Use Microsoft Entra ID / managed identity where possible, and avoid hard-coded API keys. +- Use the notebook placeholders to provide your own project, registry, and deployment values. diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/pydantic-ai/image.png b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/pydantic-ai/image.png new file mode 100644 index 0000000000000000000000000000000000000000..63cfd9bdd8653f7ff4c25d030640074613507f7f GIT binary patch literal 138258 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 r.openai.azure.com/ + AZURE_OPENAI_DEPLOYMENT deployment name, e.g. gpt-5-mini + AZURE_OPENAI_API_VERSION optional, defaults to 2024-12-01-preview + LOG_LEVEL optional, defaults to INFO + +Authentication: + + This app uses DefaultAzureCredential (Microsoft Entra ID), not API keys. + The runtime identity (user, service principal, or managed identity) must have + Azure OpenAI data-plane access (for example, the Cognitive Services OpenAI User role) + on the target Azure OpenAI resource. +""" + +import asyncio +import logging +import os +import random +from typing import Sequence + +from dotenv import load_dotenv +from openai import AsyncAzureOpenAI + +from pydantic_ai import Agent +from pydantic_ai.models.openai import OpenAIChatModel +from pydantic_ai.providers.openai import OpenAIProvider + +from azure.identity import DefaultAzureCredential, get_bearer_token_provider +from azure.ai.agentserver.responses import ( + CreateResponse, + ResponseContext, + ResponsesAgentServerHost, + TextResponse, +) +from azure.ai.agentserver.responses.models import ( + Item, + MessageContentInputTextContent, + MessageContentRefusalContent, + OutputMessageContentOutputTextContent, + get_content_expanded, +) + +load_dotenv() + +logging.basicConfig( + level=os.environ.get("LOG_LEVEL", "INFO"), + format="%(asctime)s %(levelname)-8s %(name)s: %(message)s", +) +logging.getLogger("httpx").setLevel(logging.WARNING) + +logger = logging.getLogger("pydantic_ai_responses_app") + +app = ResponsesAgentServerHost() + +_AGENT: Agent | None = None + + +def _message_text(item: Item) -> list[str]: + texts: list[str] = [] + for part in get_content_expanded(item): + if isinstance(part, (MessageContentInputTextContent, OutputMessageContentOutputTextContent)): + text = getattr(part, "text", None) + if text: + texts.append(text) + elif isinstance(part, MessageContentRefusalContent): + if part.refusal: + texts.append(f"[refused to answer: {part.refusal}]") + return texts + + +def _build_prompt(history: Sequence[Item], input_text: str) -> str: + history_lines: list[str] = [] + for item in history: + role = getattr(item, "role", None) + if role not in ("user", "assistant"): + continue + role_str = getattr(role, "value", role) + for text in _message_text(item): + history_lines.append(f"{role_str}: {text}") + + prompt_parts: list[str] = [] + if history_lines: + prompt_parts.append("Conversation so far:") + prompt_parts.extend(history_lines) + if input_text: + prompt_parts.append(f"user: {input_text}") + return "\n".join(prompt_parts) if prompt_parts else "Hello" + + +def build_agent() -> Agent: + global _AGENT + if _AGENT is None: + endpoint = os.environ["AZURE_OPENAI_ENDPOINT"] + deployment = os.environ.get("AZURE_OPENAI_DEPLOYMENT", "gpt-5-mini") + api_version = os.environ.get("AZURE_OPENAI_API_VERSION", "2024-12-01-preview") + + token_provider = get_bearer_token_provider( + DefaultAzureCredential(), + "https://cognitiveservices.azure.com/.default", + ) + + client = AsyncAzureOpenAI( + azure_endpoint=endpoint, + api_version=api_version, + azure_ad_token_provider=token_provider, + ) + + model = OpenAIChatModel( + deployment, + provider=OpenAIProvider(openai_client=client), + ) + + _AGENT = Agent( + model, + instructions=( + "You are a helpful assistant who can explain concepts, answer questions, and " + "reason through problems. You have access to two tools: get_weather for weather " + "questions and show_internal_environment_variables for debugging." + ), + ) + + @_AGENT.tool_plain + def get_weather(city: str) -> str: + temperature_c = random.randint(-5, 35) + logger.info("tool_call=get_weather city=%s result_c=%s", city, temperature_c) + return f"The current temperature in {city} is {temperature_c} deg C." + + @_AGENT.tool_plain + def show_internal_environment_variables() -> str: + return str(dict(os.environ)) + + return _AGENT + + +@app.response_handler +async def handler( + request: CreateResponse, + context: ResponseContext, + cancellation_signal: asyncio.Event, +) -> TextResponse: + input_text = await context.get_input_text() + history_items = await context.get_history() + + logger.info( + "response_id=%s input_chars=%d history_items=%d", + context.response_id, + len(input_text or ""), + len(history_items), + ) + + agent = build_agent() + prompt = _build_prompt(history_items, input_text or "") + + async def _generate_tokens(): + previous = "" + async with agent.run_stream(prompt) as run: + async for chunk in run.stream_text(): + if cancellation_signal.is_set(): + logger.warning("response_id=%s cancellation requested", context.response_id) + break + + if not isinstance(chunk, str) or not chunk: + continue + + # Convert cumulative stream_text output into incremental deltas. + if chunk.startswith(previous): + delta = chunk[len(previous) :] + else: + delta = chunk + + previous = chunk + if delta: + yield delta + + return TextResponse(context, request, text=_generate_tokens()) + + +if __name__ == "__main__": + app.run() diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/pydantic-ai/requirements.txt b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/pydantic-ai/requirements.txt new file mode 100644 index 00000000..f7656d40 --- /dev/null +++ b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/pydantic-ai/requirements.txt @@ -0,0 +1,6 @@ +azure-ai-agentserver-responses==1.0.0b8 +azure-ai-projects==2.3.0 +azure-identity>=1.20.0 +openai>=1.50.0 +pydantic-ai[openai]>=0.0.40 +python-dotenv>=1.0.0 diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/.dockerignore b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/.dockerignore new file mode 100644 index 00000000..1a7b9960 --- /dev/null +++ b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/.dockerignore @@ -0,0 +1,26 @@ +**/__pycache__/ +**/*.py[cod] +**/*.egg-info/ +.eggs/ + +# Virtual environments +.venv/ +venv/ +env/ + +# IDE settings +.vscode/ +.idea/ + +# Version control +.git/ +.gitignore + +# Docker files +.dockerignore + +# Docs +README.md + +# Local environment (never bake credentials into the image) +.env \ No newline at end of file diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/.gitignore b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/.gitignore new file mode 100644 index 00000000..ffdb3a31 --- /dev/null +++ b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/.gitignore @@ -0,0 +1,5 @@ +.venv/ +__pycache__/ +*.pyc +.env +agent_creation.py \ No newline at end of file diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/01_hosted_agent_strands_setup.ipynb b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/01_hosted_agent_strands_setup.ipynb new file mode 100644 index 00000000..f6daadda --- /dev/null +++ b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/01_hosted_agent_strands_setup.ipynb @@ -0,0 +1,833 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "c4955e40", + "metadata": {}, + "source": [ + "# Strands Hosted Agent Setup\n", + "\n", + "This notebook helps you:\n", + "1. Build and push a container image for your hosted agent code.\n", + "2. Create or update a hosted agent version from Python.\n", + "\n", + "## Prerequisites\n", + "- Docker Desktop running\n", + "- Docker authenticated to your ACR (`docker login .azurecr.io`)\n", + "- An authenticated Azure credential available for Step 2 (for example `az login`)\n", + "- Your signed-in identity has `Container Registry Repository Writer` on the target ACR repository (or equivalent push permission)\n", + "- The Microsoft Foundry project/resource identity has pull access to the image in ACR (for example `Container Registry Repository Reader` or equivalent repository-level pull permission)\n", + "\n", + "Fill in all placeholder values before running code cells." + ] + }, + { + "cell_type": "markdown", + "id": "2c5ee3f2", + "metadata": {}, + "source": [ + "## 1. Build And Push The Container Image\n", + "\n", + "This builds the image locally with Docker and pushes it to ACR.\n", + "Run this after completing the prerequisites above." + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "1cc7246e", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "ACR_NAME=acrvu4ax6chjqjsk\n", + "ACR_LOGIN_SERVER=acrvu4ax6chjqjsk.azurecr.io\n", + "IMAGE_NAME=strands-agent\n", + "IMAGE_TAG=1.0.0\n", + "IMAGE_URI=acrvu4ax6chjqjsk.azurecr.io/strands-agent:1.0.0\n" + ] + } + ], + "source": [ + "# Set these placeholders\n", + "ACR_NAME = \"acrvu4ax6chjqjsk\"\n", + "IMAGE_NAME = \"strands-agent\"\n", + "IMAGE_TAG = \"1.0.0\"\n", + "ACR_LOGIN_SERVER = f\"{ACR_NAME}.azurecr.io\"\n", + "IMAGE_URI = f\"{ACR_LOGIN_SERVER}/{IMAGE_NAME}:{IMAGE_TAG}\"\n", + "\n", + "print(f\"ACR_NAME={ACR_NAME}\")\n", + "print(f\"ACR_LOGIN_SERVER={ACR_LOGIN_SERVER}\")\n", + "print(f\"IMAGE_NAME={IMAGE_NAME}\")\n", + "print(f\"IMAGE_TAG={IMAGE_TAG}\")\n", + "print(f\"IMAGE_URI={IMAGE_URI}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "3126aa58", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running: docker build -t acrvu4ax6chjqjsk.azurecr.io/strands-agent:1.0.0 .\n", + "Running: docker push acrvu4ax6chjqjsk.azurecr.io/strands-agent:1.0.0\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "#0 building with \"desktop-linux\" instance using docker driver\n", + "\n", + "#1 [internal] load build definition from Dockerfile\n", + "#1 transferring dockerfile: 233B done\n", + "#1 DONE 0.0s\n", + "\n", + "#2 [internal] load metadata for docker.io/library/python:3.12-slim\n", + "#2 DONE 1.6s\n", + "\n", + "#3 [internal] load .dockerignore\n", + "#3 transferring context: 341B done\n", + "#3 DONE 0.0s\n", + "\n", + "#4 [internal] load build context\n", + "#4 transferring context: 68.30kB 0.0s done\n", + "#4 DONE 0.0s\n", + "\n", + "#5 [1/5] FROM docker.io/library/python:3.12-slim@sha256:423ed6ab25b1921a477529254bfeeabf5855151dc2c3141699a1bfc852199fbf\n", + "#5 resolve docker.io/library/python:3.12-slim@sha256:423ed6ab25b1921a477529254bfeeabf5855151dc2c3141699a1bfc852199fbf 0.0s done\n", + "#5 DONE 0.1s\n", + "\n", + "#5 [1/5] FROM docker.io/library/python:3.12-slim@sha256:423ed6ab25b1921a477529254bfeeabf5855151dc2c3141699a1bfc852199fbf\n", + "#5 sha256:b32430367bf08f32c23778909985ac645d1794f0aeef670aa796a50c8751527d 248B / 248B 0.1s done\n", + "#5 sha256:df79d931cd67092e2b8e48d8f6369922571efe4ee0f9af71636ce36600481492 0B / 12.11MB 0.3s\n", + "#5 sha256:aff2d9f8dc87f4c10bbb7f438f3a325169379776bdfad5c49e4be5acc3c2f192 0B / 1.29MB 0.2s\n", + "#5 sha256:e95a6c7ea7d49b37920899b023ecd0e32796c976c1748491f76cae53ba86d13a 0B / 29.79MB 0.2s\n", + "#5 sha256:df79d931cd67092e2b8e48d8f6369922571efe4ee0f9af71636ce36600481492 3.15MB / 12.11MB 0.5s\n", + "#5 sha256:df79d931cd67092e2b8e48d8f6369922571efe4ee0f9af71636ce36600481492 6.29MB / 12.11MB 0.6s\n", + "#5 sha256:df79d931cd67092e2b8e48d8f6369922571efe4ee0f9af71636ce36600481492 9.44MB / 12.11MB 0.8s\n", + "#5 sha256:aff2d9f8dc87f4c10bbb7f438f3a325169379776bdfad5c49e4be5acc3c2f192 1.29MB / 1.29MB 0.6s done\n", + "#5 sha256:df79d931cd67092e2b8e48d8f6369922571efe4ee0f9af71636ce36600481492 12.11MB / 12.11MB 0.9s done\n", + "#5 sha256:e95a6c7ea7d49b37920899b023ecd0e32796c976c1748491f76cae53ba86d13a 3.15MB / 29.79MB 0.8s\n", + "#5 sha256:e95a6c7ea7d49b37920899b023ecd0e32796c976c1748491f76cae53ba86d13a 9.44MB / 29.79MB 1.1s\n", + "#5 sha256:e95a6c7ea7d49b37920899b023ecd0e32796c976c1748491f76cae53ba86d13a 11.53MB / 29.79MB 1.2s\n", + "#5 sha256:e95a6c7ea7d49b37920899b023ecd0e32796c976c1748491f76cae53ba86d13a 14.68MB / 29.79MB 1.4s\n", + "#5 sha256:e95a6c7ea7d49b37920899b023ecd0e32796c976c1748491f76cae53ba86d13a 17.83MB / 29.79MB 1.5s\n", + "#5 sha256:e95a6c7ea7d49b37920899b023ecd0e32796c976c1748491f76cae53ba86d13a 19.92MB / 29.79MB 1.7s\n", + "#5 sha256:e95a6c7ea7d49b37920899b023ecd0e32796c976c1748491f76cae53ba86d13a 23.07MB / 29.79MB 1.8s\n", + "#5 sha256:e95a6c7ea7d49b37920899b023ecd0e32796c976c1748491f76cae53ba86d13a 27.26MB / 29.79MB 2.0s\n", + "#5 sha256:e95a6c7ea7d49b37920899b023ecd0e32796c976c1748491f76cae53ba86d13a 29.79MB / 29.79MB 2.1s\n", + "#5 sha256:e95a6c7ea7d49b37920899b023ecd0e32796c976c1748491f76cae53ba86d13a 29.79MB / 29.79MB 2.1s done\n", + "#5 extracting sha256:e95a6c7ea7d49b37920899b023ecd0e32796c976c1748491f76cae53ba86d13a\n", + "#5 extracting sha256:e95a6c7ea7d49b37920899b023ecd0e32796c976c1748491f76cae53ba86d13a 0.8s done\n", + "#5 DONE 3.0s\n", + "\n", + "#5 [1/5] FROM docker.io/library/python:3.12-slim@sha256:423ed6ab25b1921a477529254bfeeabf5855151dc2c3141699a1bfc852199fbf\n", + "#5 extracting sha256:aff2d9f8dc87f4c10bbb7f438f3a325169379776bdfad5c49e4be5acc3c2f192 0.1s done\n", + "#5 DONE 3.1s\n", + "\n", + "#5 [1/5] FROM docker.io/library/python:3.12-slim@sha256:423ed6ab25b1921a477529254bfeeabf5855151dc2c3141699a1bfc852199fbf\n", + "#5 extracting sha256:df79d931cd67092e2b8e48d8f6369922571efe4ee0f9af71636ce36600481492\n", + "#5 extracting sha256:df79d931cd67092e2b8e48d8f6369922571efe4ee0f9af71636ce36600481492 0.5s done\n", + "#5 DONE 3.6s\n", + "\n", + "#5 [1/5] FROM docker.io/library/python:3.12-slim@sha256:423ed6ab25b1921a477529254bfeeabf5855151dc2c3141699a1bfc852199fbf\n", + "#5 extracting sha256:b32430367bf08f32c23778909985ac645d1794f0aeef670aa796a50c8751527d 0.0s done\n", + "#5 DONE 3.6s\n", + "\n", + "#6 [2/5] WORKDIR /app\n", + "#6 DONE 0.2s\n", + "\n", + "#7 [3/5] COPY . user_agent/\n", + "#7 DONE 0.0s\n", + "\n", + "#8 [4/5] WORKDIR /app/user_agent\n", + "#8 DONE 0.0s\n", + "\n", + "#9 [5/5] RUN if [ -f requirements.txt ]; then pip install -r requirements.txt; fi\n", + "#9 15.53 Collecting azure-ai-agentserver-responses==1.0.0b8 (from -r requirements.txt (line 1))\n", + "#9 15.81 Downloading azure_ai_agentserver_responses-1.0.0b8-py3-none-any.whl.metadata (13 kB)\n", + "#9 16.09 Collecting strands-agents==1.45.0 (from strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 16.14 Downloading strands_agents-1.45.0-py3-none-any.whl.metadata (19 kB)\n", + "#9 16.69 Collecting python-dotenv (from -r requirements.txt (line 3))\n", + "#9 16.73 Downloading python_dotenv-1.2.2-py3-none-any.whl.metadata (27 kB)\n", + "#9 16.89 Collecting azure-ai-projects==2.3.0 (from -r requirements.txt (line 4))\n", + "#9 16.96 Downloading azure_ai_projects-2.3.0-py3-none-any.whl.metadata (64 kB)\n", + "#9 17.18 Collecting azure-ai-agentserver-core>=2.0.0b7 (from azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 17.24 Downloading azure_ai_agentserver_core-2.0.0b7-py3-none-any.whl.metadata (7.8 kB)\n", + "#9 17.52 Collecting azure-core>=1.30.0 (from azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 17.56 Downloading azure_core-1.41.0-py3-none-any.whl.metadata (49 kB)\n", + "#9 17.71 Collecting isodate>=0.6.1 (from azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 17.77 Downloading isodate-0.7.2-py3-none-any.whl.metadata (11 kB)\n", + "#9 23.23 Collecting aiohttp<4.0.0,>=3.10.0 (from azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 23.27 Downloading aiohttp-3.14.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (8.3 kB)\n", + "#9 28.83 Collecting boto3<2.0.0,>=1.26.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 28.87 Downloading boto3-1.43.42-py3-none-any.whl.metadata (6.6 kB)\n", + "#9 35.12 Collecting botocore<2.0.0,>=1.29.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 35.17 Downloading botocore-1.43.42-py3-none-any.whl.metadata (5.6 kB)\n", + "#9 35.39 Collecting docstring-parser<1.0,>=0.15 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 35.44 Downloading docstring_parser-0.18.0-py3-none-any.whl.metadata (3.5 kB)\n", + "#9 35.77 Collecting jsonschema<5.0.0,>=4.0.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 35.83 Downloading jsonschema-4.26.0-py3-none-any.whl.metadata (7.6 kB)\n", + "#9 36.18 Collecting mcp<2.0.0,>=1.23.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 36.22 Downloading mcp-1.28.1-py3-none-any.whl.metadata (9.4 kB)\n", + "#9 36.55 Collecting opentelemetry-api<2.0.0,>=1.30.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 36.58 Downloading opentelemetry_api-1.43.0-py3-none-any.whl.metadata (1.4 kB)\n", + "#9 36.87 Collecting opentelemetry-instrumentation-threading<1.00b0,>=0.51b0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 36.91 Downloading opentelemetry_instrumentation_threading-0.64b0-py3-none-any.whl.metadata (2.1 kB)\n", + "#9 37.16 Collecting opentelemetry-sdk<2.0.0,>=1.30.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 37.20 Downloading opentelemetry_sdk-1.43.0-py3-none-any.whl.metadata (1.7 kB)\n", + "#9 38.55 Collecting pydantic<3.0.0,>=2.4.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 38.59 Downloading pydantic-2.13.4-py3-none-any.whl.metadata (109 kB)\n", + "#9 39.12 Collecting pyyaml<7.0.0,>=6.0.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 39.17 Downloading pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (2.4 kB)\n", + "#9 39.43 Collecting typing-extensions<5.0.0,>=4.13.2 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 39.47 Downloading typing_extensions-4.16.0-py3-none-any.whl.metadata (3.3 kB)\n", + "#9 40.04 Collecting watchdog<7.0.0,>=6.0.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 40.08 Downloading watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl.metadata (44 kB)\n", + "#9 40.50 Collecting azure-identity>=1.15.0 (from azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", + "#9 40.54 Downloading azure_identity-1.25.3-py3-none-any.whl.metadata (91 kB)\n", + "#9 41.42 Collecting openai>=2.8.0 (from azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", + "#9 41.46 Downloading openai-2.44.0-py3-none-any.whl.metadata (34 kB)\n", + "#9 41.86 Collecting azure-storage-blob>=12.15.0 (from azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", + "#9 41.90 Downloading azure_storage_blob-12.30.0-py3-none-any.whl.metadata (26 kB)\n", + "#9 42.09 Collecting aws-bedrock-token-generator<2.0.0,>=1.1.0 (from strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 42.13 Downloading aws_bedrock_token_generator-1.1.0-py3-none-any.whl.metadata (7.5 kB)\n", + "#9 42.77 Collecting aiohappyeyeballs>=2.5.0 (from aiohttp<4.0.0,>=3.10.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 42.82 Downloading aiohappyeyeballs-2.7.1-py3-none-any.whl.metadata (5.9 kB)\n", + "#9 43.02 Collecting aiosignal>=1.4.0 (from aiohttp<4.0.0,>=3.10.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 43.06 Downloading aiosignal-1.4.0-py3-none-any.whl.metadata (3.7 kB)\n", + "#9 43.27 Collecting attrs>=17.3.0 (from aiohttp<4.0.0,>=3.10.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 43.32 Downloading attrs-26.1.0-py3-none-any.whl.metadata (8.8 kB)\n", + "#9 44.09 Collecting frozenlist>=1.1.1 (from aiohttp<4.0.0,>=3.10.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 44.14 Downloading frozenlist-1.8.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl.metadata (20 kB)\n", + "#9 46.71 Collecting multidict<7.0,>=4.5 (from aiohttp<4.0.0,>=3.10.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 46.76 Downloading multidict-6.7.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (5.3 kB)\n", + "#9 47.43 Collecting propcache>=0.2.0 (from aiohttp<4.0.0,>=3.10.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 47.48 Downloading propcache-0.5.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (16 kB)\n", + "#9 50.47 Collecting yarl<2.0,>=1.17.0 (from aiohttp<4.0.0,>=3.10.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 50.52 Downloading yarl-1.24.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (94 kB)\n", + "#9 54.05 Collecting starlette>=0.45.0 (from azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 54.09 Downloading starlette-1.3.1-py3-none-any.whl.metadata (6.4 kB)\n", + "#9 54.37 Collecting hypercorn>=0.17.0 (from azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 54.43 Downloading hypercorn-0.18.0-py3-none-any.whl.metadata (5.1 kB)\n", + "#9 54.92 Collecting microsoft-opentelemetry>=1.0.0 (from azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 54.99 Downloading microsoft_opentelemetry-1.3.5-py3-none-any.whl.metadata (23 kB)\n", + "#9 55.48 Collecting requests>=2.21.0 (from azure-core>=1.30.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 55.54 Downloading requests-2.34.2-py3-none-any.whl.metadata (4.8 kB)\n", + "#9 58.05 Collecting cryptography>=2.5 (from azure-identity>=1.15.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", + "#9 58.09 Downloading cryptography-49.0.0-cp311-abi3-manylinux_2_34_x86_64.whl.metadata (4.3 kB)\n", + "#9 58.37 Collecting msal>=1.35.1 (from azure-identity>=1.15.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", + "#9 58.41 Downloading msal-1.37.0-py3-none-any.whl.metadata (11 kB)\n", + "#9 58.59 Collecting msal-extensions>=1.2.0 (from azure-identity>=1.15.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", + "#9 58.63 Downloading msal_extensions-1.3.1-py3-none-any.whl.metadata (7.8 kB)\n", + "#9 62.15 Collecting jmespath<2.0.0,>=0.7.1 (from boto3<2.0.0,>=1.26.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 62.20 Downloading jmespath-1.1.0-py3-none-any.whl.metadata (7.6 kB)\n", + "#9 62.47 Collecting s3transfer<0.20.0,>=0.19.0 (from boto3<2.0.0,>=1.26.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 62.51 Downloading s3transfer-0.19.0-py3-none-any.whl.metadata (1.7 kB)\n", + "#9 62.83 Collecting python-dateutil<3.0.0,>=2.1 (from botocore<2.0.0,>=1.29.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 62.86 Downloading python_dateutil-2.9.0.post0-py2.py3-none-any.whl.metadata (8.4 kB)\n", + "#9 63.30 Collecting urllib3!=2.2.0,<3,>=1.25.4 (from botocore<2.0.0,>=1.29.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 63.34 Downloading urllib3-2.7.0-py3-none-any.whl.metadata (6.9 kB)\n", + "#9 63.60 Collecting jsonschema-specifications>=2023.03.6 (from jsonschema<5.0.0,>=4.0.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 63.64 Downloading jsonschema_specifications-2025.9.1-py3-none-any.whl.metadata (2.9 kB)\n", + "#9 63.95 Collecting referencing>=0.28.4 (from jsonschema<5.0.0,>=4.0.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 64.00 Downloading referencing-0.37.0-py3-none-any.whl.metadata (2.8 kB)\n", + "#9 66.98 Collecting rpds-py>=0.25.0 (from jsonschema<5.0.0,>=4.0.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 67.03 Downloading rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (4.1 kB)\n", + "#9 67.40 Collecting anyio>=4.5 (from mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 67.44 Downloading anyio-4.14.1-py3-none-any.whl.metadata (4.6 kB)\n", + "#9 67.58 Collecting httpx-sse>=0.4 (from mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 67.62 Downloading httpx_sse-0.4.3-py3-none-any.whl.metadata (9.7 kB)\n", + "#9 67.88 Collecting httpx<1.0.0,>=0.27.1 (from mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 67.93 Downloading httpx-0.28.1-py3-none-any.whl.metadata (7.1 kB)\n", + "#9 68.50 Collecting pydantic-settings>=2.5.2 (from mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 68.56 Downloading pydantic_settings-2.14.2-py3-none-any.whl.metadata (3.4 kB)\n", + "#9 69.12 Collecting pyjwt>=2.10.1 (from pyjwt[crypto]>=2.10.1->mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 69.15 Downloading pyjwt-2.13.0-py3-none-any.whl.metadata (3.4 kB)\n", + "#9 69.36 Collecting python-multipart>=0.0.9 (from mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 69.40 Downloading python_multipart-0.0.32-py3-none-any.whl.metadata (2.1 kB)\n", + "#9 69.71 Collecting sse-starlette>=1.6.1 (from mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 69.77 Downloading sse_starlette-3.4.5-py3-none-any.whl.metadata (15 kB)\n", + "#9 70.27 Collecting typing-inspection>=0.4.1 (from mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 70.32 Downloading typing_inspection-0.4.2-py3-none-any.whl.metadata (2.6 kB)\n", + "#9 70.72 Collecting uvicorn>=0.31.1 (from mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 70.75 Downloading uvicorn-0.51.0-py3-none-any.whl.metadata (6.6 kB)\n", + "#9 70.99 Collecting distro<2,>=1.7.0 (from openai>=2.8.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", + "#9 71.02 Downloading distro-1.9.0-py3-none-any.whl.metadata (6.8 kB)\n", + "#9 72.04 Collecting jiter<1,>=0.10.0 (from openai>=2.8.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", + "#9 72.10 Downloading jiter-0.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (5.2 kB)\n", + "#9 72.52 Collecting sniffio (from openai>=2.8.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", + "#9 72.58 Downloading sniffio-1.3.1-py3-none-any.whl.metadata (3.9 kB)\n", + "#9 73.01 Collecting tqdm>4 (from openai>=2.8.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", + "#9 73.05 Downloading tqdm-4.68.4-py3-none-any.whl.metadata (57 kB)\n", + "#9 73.90 Collecting opentelemetry-instrumentation==0.64b0 (from opentelemetry-instrumentation-threading<1.00b0,>=0.51b0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 73.95 Downloading opentelemetry_instrumentation-0.64b0-py3-none-any.whl.metadata (7.2 kB)\n", + "#9 76.53 Collecting wrapt<3.0.0,>=1.0.0 (from opentelemetry-instrumentation-threading<1.00b0,>=0.51b0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 76.59 Downloading wrapt-2.2.2-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl.metadata (7.4 kB)\n", + "#9 77.22 Collecting opentelemetry-semantic-conventions==0.64b0 (from opentelemetry-instrumentation==0.64b0->opentelemetry-instrumentation-threading<1.00b0,>=0.51b0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 77.27 Downloading opentelemetry_semantic_conventions-0.64b0-py3-none-any.whl.metadata (2.4 kB)\n", + "#9 77.49 Collecting packaging>=18.0 (from opentelemetry-instrumentation==0.64b0->opentelemetry-instrumentation-threading<1.00b0,>=0.51b0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 77.55 Downloading packaging-26.2-py3-none-any.whl.metadata (3.5 kB)\n", + "#9 77.90 Collecting annotated-types>=0.6.0 (from pydantic<3.0.0,>=2.4.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 77.98 Downloading annotated_types-0.7.0-py3-none-any.whl.metadata (15 kB)\n", + "#9 85.45 Collecting pydantic-core==2.46.4 (from pydantic<3.0.0,>=2.4.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 85.49 Downloading pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (6.6 kB)\n", + "#9 86.12 Collecting idna>=2.8 (from anyio>=4.5->mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 86.16 Downloading idna-3.18-py3-none-any.whl.metadata (6.1 kB)\n", + "#9 87.35 Collecting cffi>=2.0.0 (from cryptography>=2.5->azure-identity>=1.15.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", + "#9 87.41 Downloading cffi-2.1.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.metadata (2.5 kB)\n", + "#9 87.72 Collecting certifi (from httpx<1.0.0,>=0.27.1->mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 87.78 Downloading certifi-2026.6.17-py3-none-any.whl.metadata (2.5 kB)\n", + "#9 88.13 Collecting httpcore==1.* (from httpx<1.0.0,>=0.27.1->mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 88.17 Downloading httpcore-1.0.9-py3-none-any.whl.metadata (21 kB)\n", + "#9 88.39 Collecting h11>=0.16 (from httpcore==1.*->httpx<1.0.0,>=0.27.1->mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 88.44 Downloading h11-0.16.0-py3-none-any.whl.metadata (8.3 kB)\n", + "#9 88.70 Collecting h2>=4.3.0 (from hypercorn>=0.17.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 88.73 Downloading h2-4.3.0-py3-none-any.whl.metadata (5.1 kB)\n", + "#9 88.84 Collecting priority (from hypercorn>=0.17.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 88.89 Downloading priority-2.0.0-py3-none-any.whl.metadata (6.6 kB)\n", + "#9 89.00 Collecting wsproto>=0.14.0 (from hypercorn>=0.17.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 89.03 Downloading wsproto-1.3.2-py3-none-any.whl.metadata (5.2 kB)\n", + "#9 89.53 Collecting azure-core-tracing-opentelemetry~=1.0.0b11 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 89.56 Downloading azure_core_tracing_opentelemetry-1.0.0b13-py3-none-any.whl.metadata (11 kB)\n", + "#9 89.77 Collecting azure-monitor-opentelemetry-exporter~=1.0.0b54 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 89.85 Downloading azure_monitor_opentelemetry_exporter-1.0.0b55-py2.py3-none-any.whl.metadata (33 kB)\n", + "#9 90.33 Collecting opentelemetry-exporter-otlp-proto-http~=1.43.0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 90.39 Downloading opentelemetry_exporter_otlp_proto_http-1.43.0-py3-none-any.whl.metadata (2.4 kB)\n", + "#9 90.87 Collecting opentelemetry-instrumentation-django<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 90.92 Downloading opentelemetry_instrumentation_django-0.64b0-py3-none-any.whl.metadata (2.3 kB)\n", + "#9 91.14 Collecting opentelemetry-instrumentation-fastapi<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 91.21 Downloading opentelemetry_instrumentation_fastapi-0.64b0-py3-none-any.whl.metadata (2.2 kB)\n", + "#9 91.55 Collecting opentelemetry-instrumentation-flask<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 91.62 Downloading opentelemetry_instrumentation_flask-0.64b0-py3-none-any.whl.metadata (2.2 kB)\n", + "#9 91.88 Collecting opentelemetry-instrumentation-httpx<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 91.95 Downloading opentelemetry_instrumentation_httpx-0.64b0-py3-none-any.whl.metadata (7.3 kB)\n", + "#9 92.23 Collecting opentelemetry-instrumentation-psycopg2<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 92.30 Downloading opentelemetry_instrumentation_psycopg2-0.64b0-py3-none-any.whl.metadata (2.1 kB)\n", + "#9 92.61 Collecting opentelemetry-instrumentation-requests<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 92.66 Downloading opentelemetry_instrumentation_requests-0.64b0-py3-none-any.whl.metadata (2.6 kB)\n", + "#9 92.92 Collecting opentelemetry-instrumentation-urllib<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 92.96 Downloading opentelemetry_instrumentation_urllib-0.64b0-py3-none-any.whl.metadata (3.4 kB)\n", + "#9 93.26 Collecting opentelemetry-instrumentation-urllib3<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 93.33 Downloading opentelemetry_instrumentation_urllib3-0.64b0-py3-none-any.whl.metadata (4.2 kB)\n", + "#9 93.59 Collecting opentelemetry-instrumentation-logging<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 93.67 Downloading opentelemetry_instrumentation_logging-0.64b0-py3-none-any.whl.metadata (1.9 kB)\n", + "#9 93.78 Collecting opentelemetry-instrumentation-openai-agents-v2==0.1.0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 93.83 Downloading opentelemetry_instrumentation_openai_agents_v2-0.1.0-py3-none-any.whl.metadata (1.3 kB)\n", + "#9 93.97 Collecting opentelemetry-instrumentation-openai-v2==2.3b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 94.01 Downloading opentelemetry_instrumentation_openai_v2-2.3b0-py3-none-any.whl.metadata (5.2 kB)\n", + "#9 94.14 Collecting opentelemetry-resource-detector-azure<1.0.0,>=0.1.5 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 94.18 Downloading opentelemetry_resource_detector_azure-0.1.5-py3-none-any.whl.metadata (5.3 kB)\n", + "#9 94.33 Collecting wrapt<3.0.0,>=1.0.0 (from opentelemetry-instrumentation-threading<1.00b0,>=0.51b0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 94.39 Downloading wrapt-1.17.3-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl.metadata (6.4 kB)\n", + "#9 94.51 Collecting opentelemetry-util-genai==0.3b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 94.55 Downloading opentelemetry_util_genai-0.3b0-py3-none-any.whl.metadata (4.6 kB)\n", + "#9 97.72 Collecting six>=1.5 (from python-dateutil<3.0.0,>=2.1->botocore<2.0.0,>=1.29.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 97.76 Downloading six-1.17.0-py2.py3-none-any.whl.metadata (1.7 kB)\n", + "#9 99.37 Collecting charset_normalizer<4,>=2 (from requests>=2.21.0->azure-core>=1.30.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 99.42 Downloading charset_normalizer-3.4.9-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (41 kB)\n", + "#9 103.7 Collecting click>=7.0 (from uvicorn>=0.31.1->mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 103.8 Downloading click-8.4.2-py3-none-any.whl.metadata (2.6 kB)\n", + "#9 104.8 Collecting msrest>=0.6.10 (from azure-monitor-opentelemetry-exporter~=1.0.0b54->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 104.8 Downloading msrest-0.7.1-py3-none-any.whl.metadata (21 kB)\n", + "#9 105.7 Collecting psutil<8,>=5.9 (from azure-monitor-opentelemetry-exporter~=1.0.0b54->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 105.8 Downloading psutil-7.2.2-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl.metadata (22 kB)\n", + "#9 106.1 Collecting pycparser (from cffi>=2.0.0->cryptography>=2.5->azure-identity>=1.15.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", + "#9 106.1 Downloading pycparser-3.0-py3-none-any.whl.metadata (8.2 kB)\n", + "#9 106.5 Collecting hyperframe<7,>=6.1 (from h2>=4.3.0->hypercorn>=0.17.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 106.5 Downloading hyperframe-6.1.0-py3-none-any.whl.metadata (4.3 kB)\n", + "#9 106.7 Collecting hpack<5,>=4.1 (from h2>=4.3.0->hypercorn>=0.17.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 106.7 Downloading hpack-4.2.0-py3-none-any.whl.metadata (3.3 kB)\n", + "#9 107.2 Collecting googleapis-common-protos~=1.52 (from opentelemetry-exporter-otlp-proto-http~=1.43.0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 107.2 Downloading googleapis_common_protos-1.75.0-py3-none-any.whl.metadata (8.6 kB)\n", + "#9 107.5 Collecting opentelemetry-exporter-otlp-proto-common==1.43.0 (from opentelemetry-exporter-otlp-proto-http~=1.43.0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 107.5 Downloading opentelemetry_exporter_otlp_proto_common-1.43.0-py3-none-any.whl.metadata (1.8 kB)\n", + "#9 107.8 Collecting opentelemetry-proto==1.43.0 (from opentelemetry-exporter-otlp-proto-http~=1.43.0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 107.8 Downloading opentelemetry_proto-1.43.0-py3-none-any.whl.metadata (2.3 kB)\n", + "#9 109.9 Collecting protobuf<8.0,>=5.0 (from opentelemetry-proto==1.43.0->opentelemetry-exporter-otlp-proto-http~=1.43.0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 110.0 Downloading protobuf-7.35.1-cp310-abi3-manylinux2014_x86_64.whl.metadata (595 bytes)\n", + "#9 110.4 Collecting opentelemetry-instrumentation-wsgi==0.64b0 (from opentelemetry-instrumentation-django<0.65b0,>=0.64b0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 110.5 Downloading opentelemetry_instrumentation_wsgi-0.64b0-py3-none-any.whl.metadata (2.1 kB)\n", + "#9 110.8 Collecting opentelemetry-util-http==0.64b0 (from opentelemetry-instrumentation-django<0.65b0,>=0.64b0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 110.8 Downloading opentelemetry_util_http-0.64b0-py3-none-any.whl.metadata (2.6 kB)\n", + "#9 111.2 Collecting opentelemetry-instrumentation-asgi==0.64b0 (from opentelemetry-instrumentation-fastapi<0.65b0,>=0.64b0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 111.3 Downloading opentelemetry_instrumentation_asgi-0.64b0-py3-none-any.whl.metadata (2.0 kB)\n", + "#9 111.7 Collecting asgiref~=3.0 (from opentelemetry-instrumentation-asgi==0.64b0->opentelemetry-instrumentation-fastapi<0.65b0,>=0.64b0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 111.8 Downloading asgiref-3.11.1-py3-none-any.whl.metadata (9.3 kB)\n", + "#9 112.3 Collecting opentelemetry-instrumentation-dbapi==0.64b0 (from opentelemetry-instrumentation-psycopg2<0.65b0,>=0.64b0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 112.4 Downloading opentelemetry_instrumentation_dbapi-0.64b0-py3-none-any.whl.metadata (2.0 kB)\n", + "#9 113.8 Collecting requests-oauthlib>=0.5.0 (from msrest>=0.6.10->azure-monitor-opentelemetry-exporter~=1.0.0b54->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 113.9 Downloading requests_oauthlib-2.0.0-py2.py3-none-any.whl.metadata (11 kB)\n", + "#9 114.6 Collecting oauthlib>=3.0.0 (from requests-oauthlib>=0.5.0->msrest>=0.6.10->azure-monitor-opentelemetry-exporter~=1.0.0b54->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 114.6 Downloading oauthlib-3.3.1-py3-none-any.whl.metadata (7.9 kB)\n", + "#9 114.9 Downloading azure_ai_agentserver_responses-1.0.0b8-py3-none-any.whl (269 kB)\n", + "#9 115.0 Downloading strands_agents-1.45.0-py3-none-any.whl (579 kB)\n", + "#9 115.0 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 579.3/579.3 kB 12.0 MB/s eta 0:00:00\n", + "#9 115.1 Downloading azure_ai_projects-2.3.0-py3-none-any.whl (349 kB)\n", + "#9 115.2 Downloading python_dotenv-1.2.2-py3-none-any.whl (22 kB)\n", + "#9 115.3 Downloading aiohttp-3.14.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (1.8 MB)\n", + "#9 115.4 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.8/1.8 MB 16.4 MB/s eta 0:00:00\n", + "#9 115.5 Downloading aws_bedrock_token_generator-1.1.0-py3-none-any.whl (10 kB)\n", + "#9 115.5 Downloading azure_ai_agentserver_core-2.0.0b7-py3-none-any.whl (35 kB)\n", + "#9 115.6 Downloading azure_core-1.41.0-py3-none-any.whl (220 kB)\n", + "#9 115.7 Downloading azure_identity-1.25.3-py3-none-any.whl (192 kB)\n", + "#9 115.8 Downloading azure_storage_blob-12.30.0-py3-none-any.whl (435 kB)\n", + "#9 115.9 Downloading boto3-1.43.42-py3-none-any.whl (140 kB)\n", + "#9 116.0 Downloading botocore-1.43.42-py3-none-any.whl (15.4 MB)\n", + "#9 117.0 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 15.4/15.4 MB 15.7 MB/s eta 0:00:00\n", + "#9 117.0 Downloading docstring_parser-0.18.0-py3-none-any.whl (22 kB)\n", + "#9 117.1 Downloading isodate-0.7.2-py3-none-any.whl (22 kB)\n", + "#9 117.2 Downloading jsonschema-4.26.0-py3-none-any.whl (90 kB)\n", + "#9 117.4 Downloading mcp-1.28.1-py3-none-any.whl (222 kB)\n", + "#9 117.5 Downloading openai-2.44.0-py3-none-any.whl (1.4 MB)\n", + "#9 117.6 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.4/1.4 MB 13.4 MB/s eta 0:00:00\n", + "#9 117.6 Downloading opentelemetry_api-1.43.0-py3-none-any.whl (61 kB)\n", + "#9 117.7 Downloading opentelemetry_instrumentation_threading-0.64b0-py3-none-any.whl (8.5 kB)\n", + "#9 117.8 Downloading opentelemetry_instrumentation-0.64b0-py3-none-any.whl (35 kB)\n", + "#9 117.9 Downloading opentelemetry_semantic_conventions-0.64b0-py3-none-any.whl (203 kB)\n", + "#9 117.9 Downloading opentelemetry_sdk-1.43.0-py3-none-any.whl (178 kB)\n", + "#9 118.0 Downloading pydantic-2.13.4-py3-none-any.whl (472 kB)\n", + "#9 118.2 Downloading pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.1 MB)\n", + "#9 118.3 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2.1/2.1 MB 20.4 MB/s eta 0:00:00\n", + "#9 118.3 Downloading pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (807 kB)\n", + "#9 118.4 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 807.9/807.9 kB 12.8 MB/s eta 0:00:00\n", + "#9 118.5 Downloading typing_extensions-4.16.0-py3-none-any.whl (45 kB)\n", + "#9 118.6 Downloading watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl (79 kB)\n", + "#9 118.7 Downloading aiohappyeyeballs-2.7.1-py3-none-any.whl (15 kB)\n", + "#9 118.8 Downloading aiosignal-1.4.0-py3-none-any.whl (7.5 kB)\n", + "#9 118.9 Downloading annotated_types-0.7.0-py3-none-any.whl (13 kB)\n", + "#9 119.0 Downloading anyio-4.14.1-py3-none-any.whl (124 kB)\n", + "#9 119.1 Downloading attrs-26.1.0-py3-none-any.whl (67 kB)\n", + "#9 119.1 Downloading cryptography-49.0.0-cp311-abi3-manylinux_2_34_x86_64.whl (4.7 MB)\n", + "#9 119.4 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 4.7/4.7 MB 15.2 MB/s eta 0:00:00\n", + "#9 119.5 Downloading distro-1.9.0-py3-none-any.whl (20 kB)\n", + "#9 119.6 Downloading frozenlist-1.8.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl (242 kB)\n", + "#9 119.7 Downloading httpx-0.28.1-py3-none-any.whl (73 kB)\n", + "#9 119.7 Downloading httpcore-1.0.9-py3-none-any.whl (78 kB)\n", + "#9 119.8 Downloading httpx_sse-0.4.3-py3-none-any.whl (9.0 kB)\n", + "#9 119.9 Downloading hypercorn-0.18.0-py3-none-any.whl (61 kB)\n", + "#9 119.9 Downloading jiter-0.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (343 kB)\n", + "#9 120.1 Downloading jmespath-1.1.0-py3-none-any.whl (20 kB)\n", + "#9 120.1 Downloading jsonschema_specifications-2025.9.1-py3-none-any.whl (18 kB)\n", + "#9 120.2 Downloading microsoft_opentelemetry-1.3.5-py3-none-any.whl (208 kB)\n", + "#9 120.3 Downloading opentelemetry_instrumentation_openai_agents_v2-0.1.0-py3-none-any.whl (25 kB)\n", + "#9 120.4 Downloading opentelemetry_instrumentation_openai_v2-2.3b0-py3-none-any.whl (18 kB)\n", + "#9 120.5 Downloading opentelemetry_util_genai-0.3b0-py3-none-any.whl (28 kB)\n", + "#9 120.6 Downloading msal-1.37.0-py3-none-any.whl (123 kB)\n", + "#9 120.6 Downloading msal_extensions-1.3.1-py3-none-any.whl (20 kB)\n", + "#9 120.7 Downloading multidict-6.7.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (256 kB)\n", + "#9 120.8 Downloading propcache-0.5.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (61 kB)\n", + "#9 120.9 Downloading pydantic_settings-2.14.2-py3-none-any.whl (61 kB)\n", + "#9 120.9 Downloading pyjwt-2.13.0-py3-none-any.whl (31 kB)\n", + "#9 121.0 Downloading python_dateutil-2.9.0.post0-py2.py3-none-any.whl (229 kB)\n", + "#9 121.1 Downloading python_multipart-0.0.32-py3-none-any.whl (30 kB)\n", + "#9 121.2 Downloading referencing-0.37.0-py3-none-any.whl (26 kB)\n", + "#9 121.3 Downloading requests-2.34.2-py3-none-any.whl (73 kB)\n", + "#9 121.3 Downloading rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (366 kB)\n", + "#9 121.4 Downloading s3transfer-0.19.0-py3-none-any.whl (90 kB)\n", + "#9 121.5 Downloading sse_starlette-3.4.5-py3-none-any.whl (16 kB)\n", + "#9 121.6 Downloading starlette-1.3.1-py3-none-any.whl (73 kB)\n", + "#9 121.7 Downloading tqdm-4.68.4-py3-none-any.whl (676 kB)\n", + "#9 121.8 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 676.6/676.6 kB 13.2 MB/s eta 0:00:00\n", + "#9 121.8 Downloading typing_inspection-0.4.2-py3-none-any.whl (14 kB)\n", + "#9 121.9 Downloading urllib3-2.7.0-py3-none-any.whl (131 kB)\n", + "#9 122.0 Downloading uvicorn-0.51.0-py3-none-any.whl (73 kB)\n", + "#9 122.1 Downloading wrapt-1.17.3-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl (88 kB)\n", + "#9 122.2 Downloading yarl-1.24.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (105 kB)\n", + "#9 122.2 Downloading sniffio-1.3.1-py3-none-any.whl (10 kB)\n", + "#9 122.3 Downloading azure_core_tracing_opentelemetry-1.0.0b13-py3-none-any.whl (12 kB)\n", + "#9 122.3 Downloading azure_monitor_opentelemetry_exporter-1.0.0b55-py2.py3-none-any.whl (251 kB)\n", + "#9 122.4 Downloading certifi-2026.6.17-py3-none-any.whl (133 kB)\n", + "#9 122.5 Downloading cffi-2.1.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (221 kB)\n", + "#9 122.6 Downloading charset_normalizer-3.4.9-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (224 kB)\n", + "#9 122.7 Downloading click-8.4.2-py3-none-any.whl (119 kB)\n", + "#9 122.8 Downloading h11-0.16.0-py3-none-any.whl (37 kB)\n", + "#9 122.9 Downloading h2-4.3.0-py3-none-any.whl (61 kB)\n", + "#9 123.0 Downloading idna-3.18-py3-none-any.whl (65 kB)\n", + "#9 123.0 Downloading opentelemetry_exporter_otlp_proto_http-1.43.0-py3-none-any.whl (21 kB)\n", + "#9 123.1 Downloading opentelemetry_exporter_otlp_proto_common-1.43.0-py3-none-any.whl (17 kB)\n", + "#9 123.2 Downloading opentelemetry_proto-1.43.0-py3-none-any.whl (72 kB)\n", + "#9 123.2 Downloading opentelemetry_instrumentation_django-0.64b0-py3-none-any.whl (18 kB)\n", + "#9 123.3 Downloading opentelemetry_instrumentation_wsgi-0.64b0-py3-none-any.whl (13 kB)\n", + "#9 123.4 Downloading opentelemetry_util_http-0.64b0-py3-none-any.whl (8.2 kB)\n", + "#9 123.5 Downloading opentelemetry_instrumentation_fastapi-0.64b0-py3-none-any.whl (13 kB)\n", + "#9 123.6 Downloading opentelemetry_instrumentation_asgi-0.64b0-py3-none-any.whl (15 kB)\n", + "#9 123.7 Downloading opentelemetry_instrumentation_flask-0.64b0-py3-none-any.whl (15 kB)\n", + "#9 123.8 Downloading opentelemetry_instrumentation_httpx-0.64b0-py3-none-any.whl (16 kB)\n", + "#9 123.9 Downloading opentelemetry_instrumentation_logging-0.64b0-py3-none-any.whl (16 kB)\n", + "#9 123.9 Downloading opentelemetry_instrumentation_psycopg2-0.64b0-py3-none-any.whl (10 kB)\n", + "#9 124.0 Downloading opentelemetry_instrumentation_dbapi-0.64b0-py3-none-any.whl (14 kB)\n", + "#9 124.0 Downloading opentelemetry_instrumentation_requests-0.64b0-py3-none-any.whl (13 kB)\n", + "#9 124.1 Downloading opentelemetry_instrumentation_urllib-0.64b0-py3-none-any.whl (13 kB)\n", + "#9 124.2 Downloading opentelemetry_instrumentation_urllib3-0.64b0-py3-none-any.whl (13 kB)\n", + "#9 124.3 Downloading opentelemetry_resource_detector_azure-0.1.5-py3-none-any.whl (14 kB)\n", + "#9 124.4 Downloading packaging-26.2-py3-none-any.whl (100 kB)\n", + "#9 124.4 Downloading six-1.17.0-py2.py3-none-any.whl (11 kB)\n", + "#9 124.5 Downloading wsproto-1.3.2-py3-none-any.whl (24 kB)\n", + "#9 124.6 Downloading priority-2.0.0-py3-none-any.whl (8.9 kB)\n", + "#9 124.7 Downloading googleapis_common_protos-1.75.0-py3-none-any.whl (300 kB)\n", + "#9 124.8 Downloading hpack-4.2.0-py3-none-any.whl (34 kB)\n", + "#9 124.9 Downloading hyperframe-6.1.0-py3-none-any.whl (13 kB)\n", + "#9 125.0 Downloading msrest-0.7.1-py3-none-any.whl (85 kB)\n", + "#9 125.0 Downloading psutil-7.2.2-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl (155 kB)\n", + "#9 125.1 Downloading pycparser-3.0-py3-none-any.whl (48 kB)\n", + "#9 125.2 Downloading asgiref-3.11.1-py3-none-any.whl (24 kB)\n", + "#9 125.2 Downloading protobuf-7.35.1-cp310-abi3-manylinux2014_x86_64.whl (327 kB)\n", + "#9 125.3 Downloading requests_oauthlib-2.0.0-py2.py3-none-any.whl (24 kB)\n", + "#9 125.4 Downloading oauthlib-3.3.1-py3-none-any.whl (160 kB)\n", + "#9 129.1 Installing collected packages: wrapt, watchdog, urllib3, typing-extensions, tqdm, sniffio, six, rpds-py, pyyaml, python-multipart, python-dotenv, pyjwt, pycparser, psutil, protobuf, propcache, priority, packaging, opentelemetry-util-http, oauthlib, multidict, jmespath, jiter, isodate, idna, hyperframe, httpx-sse, hpack, h11, frozenlist, docstring-parser, distro, click, charset_normalizer, certifi, attrs, asgiref, annotated-types, aiohappyeyeballs, yarl, wsproto, uvicorn, typing-inspection, requests, referencing, python-dateutil, pydantic-core, opentelemetry-proto, opentelemetry-api, httpcore, h2, googleapis-common-protos, cffi, anyio, aiosignal, starlette, requests-oauthlib, pydantic, opentelemetry-semantic-conventions, opentelemetry-exporter-otlp-proto-common, jsonschema-specifications, hypercorn, httpx, cryptography, botocore, azure-core, aiohttp, sse-starlette, s3transfer, pydantic-settings, opentelemetry-sdk, opentelemetry-instrumentation, openai, msrest, jsonschema, azure-storage-blob, azure-core-tracing-opentelemetry, aws-bedrock-token-generator, opentelemetry-util-genai, opentelemetry-resource-detector-azure, opentelemetry-instrumentation-wsgi, opentelemetry-instrumentation-urllib3, opentelemetry-instrumentation-urllib, opentelemetry-instrumentation-threading, opentelemetry-instrumentation-requests, opentelemetry-instrumentation-openai-v2, opentelemetry-instrumentation-logging, opentelemetry-instrumentation-httpx, opentelemetry-instrumentation-dbapi, opentelemetry-instrumentation-asgi, opentelemetry-exporter-otlp-proto-http, msal, mcp, boto3, strands-agents, opentelemetry-instrumentation-psycopg2, opentelemetry-instrumentation-openai-agents-v2, opentelemetry-instrumentation-flask, opentelemetry-instrumentation-fastapi, opentelemetry-instrumentation-django, msal-extensions, azure-identity, azure-monitor-opentelemetry-exporter, azure-ai-projects, microsoft-opentelemetry, azure-ai-agentserver-core, azure-ai-agentserver-responses\n", + "#9 203.7 Successfully installed aiohappyeyeballs-2.7.1 aiohttp-3.14.1 aiosignal-1.4.0 annotated-types-0.7.0 anyio-4.14.1 asgiref-3.11.1 attrs-26.1.0 aws-bedrock-token-generator-1.1.0 azure-ai-agentserver-core-2.0.0b7 azure-ai-agentserver-responses-1.0.0b8 azure-ai-projects-2.3.0 azure-core-1.41.0 azure-core-tracing-opentelemetry-1.0.0b13 azure-identity-1.25.3 azure-monitor-opentelemetry-exporter-1.0.0b55 azure-storage-blob-12.30.0 boto3-1.43.42 botocore-1.43.42 certifi-2026.6.17 cffi-2.1.0 charset_normalizer-3.4.9 click-8.4.2 cryptography-49.0.0 distro-1.9.0 docstring-parser-0.18.0 frozenlist-1.8.0 googleapis-common-protos-1.75.0 h11-0.16.0 h2-4.3.0 hpack-4.2.0 httpcore-1.0.9 httpx-0.28.1 httpx-sse-0.4.3 hypercorn-0.18.0 hyperframe-6.1.0 idna-3.18 isodate-0.7.2 jiter-0.16.0 jmespath-1.1.0 jsonschema-4.26.0 jsonschema-specifications-2025.9.1 mcp-1.28.1 microsoft-opentelemetry-1.3.5 msal-1.37.0 msal-extensions-1.3.1 msrest-0.7.1 multidict-6.7.1 oauthlib-3.3.1 openai-2.44.0 opentelemetry-api-1.43.0 opentelemetry-exporter-otlp-proto-common-1.43.0 opentelemetry-exporter-otlp-proto-http-1.43.0 opentelemetry-instrumentation-0.64b0 opentelemetry-instrumentation-asgi-0.64b0 opentelemetry-instrumentation-dbapi-0.64b0 opentelemetry-instrumentation-django-0.64b0 opentelemetry-instrumentation-fastapi-0.64b0 opentelemetry-instrumentation-flask-0.64b0 opentelemetry-instrumentation-httpx-0.64b0 opentelemetry-instrumentation-logging-0.64b0 opentelemetry-instrumentation-openai-agents-v2-0.1.0 opentelemetry-instrumentation-openai-v2-2.3b0 opentelemetry-instrumentation-psycopg2-0.64b0 opentelemetry-instrumentation-requests-0.64b0 opentelemetry-instrumentation-threading-0.64b0 opentelemetry-instrumentation-urllib-0.64b0 opentelemetry-instrumentation-urllib3-0.64b0 opentelemetry-instrumentation-wsgi-0.64b0 opentelemetry-proto-1.43.0 opentelemetry-resource-detector-azure-0.1.5 opentelemetry-sdk-1.43.0 opentelemetry-semantic-conventions-0.64b0 opentelemetry-util-genai-0.3b0 opentelemetry-util-http-0.64b0 packaging-26.2 priority-2.0.0 propcache-0.5.2 protobuf-7.35.1 psutil-7.2.2 pycparser-3.0 pydantic-2.13.4 pydantic-core-2.46.4 pydantic-settings-2.14.2 pyjwt-2.13.0 python-dateutil-2.9.0.post0 python-dotenv-1.2.2 python-multipart-0.0.32 pyyaml-6.0.3 referencing-0.37.0 requests-2.34.2 requests-oauthlib-2.0.0 rpds-py-2026.6.3 s3transfer-0.19.0 six-1.17.0 sniffio-1.3.1 sse-starlette-3.4.5 starlette-1.3.1 strands-agents-1.45.0 tqdm-4.68.4 typing-extensions-4.16.0 typing-inspection-0.4.2 urllib3-2.7.0 uvicorn-0.51.0 watchdog-6.0.0 wrapt-1.17.3 wsproto-1.3.2 yarl-1.24.2\n", + "#9 203.7 WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager, possibly rendering your system unusable. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv. Use the --root-user-action option if you know what you are doing and want to suppress this warning.\n", + "#9 204.5 \n", + "#9 204.5 [notice] A new release of pip is available: 25.0.1 -> 26.1.2\n", + "#9 204.5 [notice] To update, run: pip install --upgrade pip\n", + "#9 DONE 205.9s\n", + "\n", + "#10 exporting to image\n", + "#10 exporting layers\n", + "#10 exporting layers 5.9s done\n", + "#10 exporting manifest sha256:35f0f217ae600a88d65c2ab51371e147d615913decd5e6499de584b97fd2187e\n", + "#10 exporting manifest sha256:35f0f217ae600a88d65c2ab51371e147d615913decd5e6499de584b97fd2187e 0.0s done\n", + "#10 exporting config sha256:076bd17831d575d16d30100abb9881e88216dbb08a343202fe5a677538ff6489 0.0s done\n", + "#10 exporting attestation manifest sha256:f1b15d9ff6ed0b2cad5b215b4686340fdf2dd1427290f53852be1a055bc3ce4e 0.0s done\n", + "#10 exporting manifest list sha256:416112ec1036a05de70379fd53150ef164f287caeb5adf23668f0b6daff10a95 0.0s done\n", + "#10 naming to acrvu4ax6chjqjsk.azurecr.io/strands-agent:1.0.0 done\n", + "#10 DONE 6.0s\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The push refers to repository [acrvu4ax6chjqjsk.azurecr.io/strands-agent]\n", + "5448f2dea2bc: Waiting\n", + "9fe7005554a0: Waiting\n", + "4f4fb700ef54: Waiting\n", + "df79d931cd67: Waiting\n", + "e95a6c7ea7d4: Waiting\n", + "b32430367bf0: Waiting\n", + "6ad5ff264d4d: Waiting\n", + "b12bbba8f9a6: Waiting\n", + "aff2d9f8dc87: Waiting\n", + "4f4fb700ef54: Waiting\n", + "df79d931cd67: Waiting\n", + "e95a6c7ea7d4: Waiting\n", + "b32430367bf0: Waiting\n", + "6ad5ff264d4d: Waiting\n", + "b12bbba8f9a6: Waiting\n", + "aff2d9f8dc87: Waiting\n", + "5448f2dea2bc: Waiting\n", + "9fe7005554a0: Waiting\n", + "6ad5ff264d4d: Waiting\n", + "b12bbba8f9a6: Waiting\n", + "aff2d9f8dc87: Waiting\n", + "5448f2dea2bc: Waiting\n", + "9fe7005554a0: Waiting\n", + "4f4fb700ef54: Waiting\n", + "df79d931cd67: Waiting\n", + "e95a6c7ea7d4: Waiting\n", + "b32430367bf0: Waiting\n", + "df79d931cd67: Waiting\n", + "e95a6c7ea7d4: Waiting\n", + "b32430367bf0: Waiting\n", + "6ad5ff264d4d: Waiting\n", + "b12bbba8f9a6: Waiting\n", + "aff2d9f8dc87: Waiting\n", + "5448f2dea2bc: Waiting\n", + "9fe7005554a0: Waiting\n", + "4f4fb700ef54: Waiting\n", + "6ad5ff264d4d: Waiting\n", + "b12bbba8f9a6: Waiting\n", + "aff2d9f8dc87: Waiting\n", + "5448f2dea2bc: Waiting\n", + "9fe7005554a0: Waiting\n", + "4f4fb700ef54: Waiting\n", + "df79d931cd67: Waiting\n", + "e95a6c7ea7d4: Waiting\n", + "b32430367bf0: Waiting\n", + "6ad5ff264d4d: Waiting\n", + "b12bbba8f9a6: Waiting\n", + "aff2d9f8dc87: Waiting\n", + "5448f2dea2bc: Waiting\n", + "9fe7005554a0: Waiting\n", + "4f4fb700ef54: Waiting\n", + "df79d931cd67: Layer already exists\n", + "e95a6c7ea7d4: Waiting\n", + "b32430367bf0: Waiting\n", + "b12bbba8f9a6: Waiting\n", + "aff2d9f8dc87: Waiting\n", + "9fe7005554a0: Waiting\n", + "4f4fb700ef54: Layer already exists\n", + "e95a6c7ea7d4: Waiting\n", + "b32430367bf0: Waiting\n", + "6ad5ff264d4d: Waiting\n", + "aff2d9f8dc87: Layer already exists\n", + "e95a6c7ea7d4: Waiting\n", + "b32430367bf0: Layer already exists\n", + "5448f2dea2bc: Pushed\n", + "6ad5ff264d4d: Pushed\n", + "9fe7005554a0: Pushed\n", + "e95a6c7ea7d4: Pushed\n", + "b12bbba8f9a6: Pushed\n", + "1.0.0: digest: sha256:416112ec1036a05de70379fd53150ef164f287caeb5adf23668f0b6daff10a95 size: 856\n", + "Docker build and push completed successfully.\n" + ] + } + ], + "source": [ + "# Use Docker directly from the notebook\n", + "print(f\"Running: docker build -t {IMAGE_URI} .\")\n", + "!docker build -t {IMAGE_URI} --platform linux/amd64 .\n", + "\n", + "print(f\"Running: docker push {IMAGE_URI}\")\n", + "!docker push {IMAGE_URI}\n", + "\n", + "print(\"Docker build and push completed successfully.\")" + ] + }, + { + "cell_type": "markdown", + "id": "20f53916", + "metadata": {}, + "source": [ + "## 2. Create Hosted Agent Version\n", + "\n", + "This cell mirrors the logic from agent_creation.py with placeholder values only.\n", + "\n", + "Model authentication for this Strands agent is APIM api-key based (not managed identity).\n", + "Use the APIM inference endpoint for model calls, and ensure that API is wired to backend `foundry-models`.\n", + "`foundry-agents` is for the hosted agent Responses API/proxy, not the model inference API used by this runtime.\n", + "\n", + "Install dependencies first if needed:\n", + "`pip install azure-ai-projects azure-identity`" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "cca00471", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Collecting azure-ai-projects==2.3.0\n", + " Using cached azure_ai_projects-2.3.0-py3-none-any.whl.metadata (64 kB)\n", + "Collecting isodate>=0.6.1 (from azure-ai-projects==2.3.0)\n", + " Using cached isodate-0.7.2-py3-none-any.whl.metadata (11 kB)\n", + "Collecting azure-core>=1.37.0 (from azure-ai-projects==2.3.0)\n", + " Using cached azure_core-1.41.0-py3-none-any.whl.metadata (49 kB)\n", + "Requirement already satisfied: typing-extensions>=4.11 in c:\\users\\ollisgeorge\\appdata\\roaming\\python\\python312\\site-packages (from azure-ai-projects==2.3.0) (4.16.0)\n", + "Collecting azure-identity>=1.15.0 (from azure-ai-projects==2.3.0)\n", + " Using cached azure_identity-1.25.3-py3-none-any.whl.metadata (91 kB)\n", + "Collecting openai>=2.8.0 (from azure-ai-projects==2.3.0)\n", + " Using cached openai-2.44.0-py3-none-any.whl.metadata (34 kB)\n", + "Collecting azure-storage-blob>=12.15.0 (from azure-ai-projects==2.3.0)\n", + " Using cached azure_storage_blob-12.30.0-py3-none-any.whl.metadata (26 kB)\n", + "Collecting requests>=2.21.0 (from azure-core>=1.37.0->azure-ai-projects==2.3.0)\n", + " Using cached requests-2.34.2-py3-none-any.whl.metadata (4.8 kB)\n", + "Collecting cryptography>=2.5 (from azure-identity>=1.15.0->azure-ai-projects==2.3.0)\n", + " Using cached cryptography-49.0.0-cp311-abi3-win_amd64.whl.metadata (4.3 kB)\n", + "Collecting msal>=1.35.1 (from azure-identity>=1.15.0->azure-ai-projects==2.3.0)\n", + " Using cached msal-1.37.0-py3-none-any.whl.metadata (11 kB)\n", + "Collecting msal-extensions>=1.2.0 (from azure-identity>=1.15.0->azure-ai-projects==2.3.0)\n", + " Using cached msal_extensions-1.3.1-py3-none-any.whl.metadata (7.8 kB)\n", + "Collecting anyio<5,>=3.5.0 (from openai>=2.8.0->azure-ai-projects==2.3.0)\n", + " Using cached anyio-4.14.1-py3-none-any.whl.metadata (4.6 kB)\n", + "Collecting distro<2,>=1.7.0 (from openai>=2.8.0->azure-ai-projects==2.3.0)\n", + " Using cached distro-1.9.0-py3-none-any.whl.metadata (6.8 kB)\n", + "Collecting httpx<1,>=0.23.0 (from openai>=2.8.0->azure-ai-projects==2.3.0)\n", + " Using cached httpx-0.28.1-py3-none-any.whl.metadata (7.1 kB)\n", + "Collecting jiter<1,>=0.10.0 (from openai>=2.8.0->azure-ai-projects==2.3.0)\n", + " Using cached jiter-0.16.0-cp312-cp312-win_amd64.whl.metadata (5.3 kB)\n", + "Collecting pydantic<3,>=1.9.0 (from openai>=2.8.0->azure-ai-projects==2.3.0)\n", + " Using cached pydantic-2.13.4-py3-none-any.whl.metadata (109 kB)\n", + "Collecting sniffio (from openai>=2.8.0->azure-ai-projects==2.3.0)\n", + " Using cached sniffio-1.3.1-py3-none-any.whl.metadata (3.9 kB)\n", + "Collecting tqdm>4 (from openai>=2.8.0->azure-ai-projects==2.3.0)\n", + " Using cached tqdm-4.68.4-py3-none-any.whl.metadata (57 kB)\n", + "Collecting idna>=2.8 (from anyio<5,>=3.5.0->openai>=2.8.0->azure-ai-projects==2.3.0)\n", + " Using cached idna-3.18-py3-none-any.whl.metadata (6.1 kB)\n", + "Collecting cffi>=2.0.0 (from cryptography>=2.5->azure-identity>=1.15.0->azure-ai-projects==2.3.0)\n", + " Using cached cffi-2.1.0-cp312-cp312-win_amd64.whl.metadata (2.6 kB)\n", + "Collecting certifi (from httpx<1,>=0.23.0->openai>=2.8.0->azure-ai-projects==2.3.0)\n", + " Using cached certifi-2026.6.17-py3-none-any.whl.metadata (2.5 kB)\n", + "Collecting httpcore==1.* (from httpx<1,>=0.23.0->openai>=2.8.0->azure-ai-projects==2.3.0)\n", + " Using cached httpcore-1.0.9-py3-none-any.whl.metadata (21 kB)\n", + "Collecting h11>=0.16 (from httpcore==1.*->httpx<1,>=0.23.0->openai>=2.8.0->azure-ai-projects==2.3.0)\n", + " Using cached h11-0.16.0-py3-none-any.whl.metadata (8.3 kB)\n", + "Collecting PyJWT<3,>=1.0.0 (from PyJWT[crypto]<3,>=1.0.0->msal>=1.35.1->azure-identity>=1.15.0->azure-ai-projects==2.3.0)\n", + " Using cached pyjwt-2.13.0-py3-none-any.whl.metadata (3.4 kB)\n", + "Collecting annotated-types>=0.6.0 (from pydantic<3,>=1.9.0->openai>=2.8.0->azure-ai-projects==2.3.0)\n", + " Using cached annotated_types-0.7.0-py3-none-any.whl.metadata (15 kB)\n", + "Collecting pydantic-core==2.46.4 (from pydantic<3,>=1.9.0->openai>=2.8.0->azure-ai-projects==2.3.0)\n", + " Using cached pydantic_core-2.46.4-cp312-cp312-win_amd64.whl.metadata (6.7 kB)\n", + "Collecting typing-inspection>=0.4.2 (from pydantic<3,>=1.9.0->openai>=2.8.0->azure-ai-projects==2.3.0)\n", + " Using cached typing_inspection-0.4.2-py3-none-any.whl.metadata (2.6 kB)\n", + "Collecting charset_normalizer<4,>=2 (from requests>=2.21.0->azure-core>=1.37.0->azure-ai-projects==2.3.0)\n", + " Using cached charset_normalizer-3.4.9-cp312-cp312-win_amd64.whl.metadata (42 kB)\n", + "Collecting urllib3<3,>=1.26 (from requests>=2.21.0->azure-core>=1.37.0->azure-ai-projects==2.3.0)\n", + " Using cached urllib3-2.7.0-py3-none-any.whl.metadata (6.9 kB)\n", + "Requirement already satisfied: colorama in c:\\users\\ollisgeorge\\appdata\\roaming\\python\\python312\\site-packages (from tqdm>4->openai>=2.8.0->azure-ai-projects==2.3.0) (0.4.6)\n", + "Collecting pycparser (from cffi>=2.0.0->cryptography>=2.5->azure-identity>=1.15.0->azure-ai-projects==2.3.0)\n", + " Using cached pycparser-3.0-py3-none-any.whl.metadata (8.2 kB)\n", + "Using cached azure_ai_projects-2.3.0-py3-none-any.whl (349 kB)\n", + "Using cached azure_core-1.41.0-py3-none-any.whl (220 kB)\n", + "Using cached azure_identity-1.25.3-py3-none-any.whl (192 kB)\n", + "Using cached azure_storage_blob-12.30.0-py3-none-any.whl (435 kB)\n", + "Using cached isodate-0.7.2-py3-none-any.whl (22 kB)\n", + "Using cached openai-2.44.0-py3-none-any.whl (1.4 MB)\n", + "Using cached anyio-4.14.1-py3-none-any.whl (124 kB)\n", + "Using cached cryptography-49.0.0-cp311-abi3-win_amd64.whl (3.8 MB)\n", + "Using cached distro-1.9.0-py3-none-any.whl (20 kB)\n", + "Using cached httpx-0.28.1-py3-none-any.whl (73 kB)\n", + "Using cached httpcore-1.0.9-py3-none-any.whl (78 kB)\n", + "Using cached jiter-0.16.0-cp312-cp312-win_amd64.whl (196 kB)\n", + "Using cached msal-1.37.0-py3-none-any.whl (123 kB)\n", + "Using cached msal_extensions-1.3.1-py3-none-any.whl (20 kB)\n", + "Using cached pydantic-2.13.4-py3-none-any.whl (472 kB)\n", + "Using cached pydantic_core-2.46.4-cp312-cp312-win_amd64.whl (2.1 MB)\n", + "Using cached requests-2.34.2-py3-none-any.whl (73 kB)\n", + "Using cached tqdm-4.68.4-py3-none-any.whl (676 kB)\n", + "Using cached sniffio-1.3.1-py3-none-any.whl (10 kB)\n", + "Using cached annotated_types-0.7.0-py3-none-any.whl (13 kB)\n", + "Using cached certifi-2026.6.17-py3-none-any.whl (133 kB)\n", + "Using cached cffi-2.1.0-cp312-cp312-win_amd64.whl (185 kB)\n", + "Using cached charset_normalizer-3.4.9-cp312-cp312-win_amd64.whl (162 kB)\n", + "Using cached idna-3.18-py3-none-any.whl (65 kB)\n", + "Using cached pyjwt-2.13.0-py3-none-any.whl (31 kB)\n", + "Using cached typing_inspection-0.4.2-py3-none-any.whl (14 kB)\n", + "Using cached urllib3-2.7.0-py3-none-any.whl (131 kB)\n", + "Using cached h11-0.16.0-py3-none-any.whl (37 kB)\n", + "Using cached pycparser-3.0-py3-none-any.whl (48 kB)\n", + "Installing collected packages: urllib3, typing-inspection, tqdm, sniffio, PyJWT, pydantic-core, pycparser, jiter, isodate, idna, h11, distro, charset_normalizer, certifi, annotated-types, requests, pydantic, httpcore, cffi, anyio, httpx, cryptography, azure-core, openai, azure-storage-blob, msal, msal-extensions, azure-identity, azure-ai-projects\n", + "Successfully installed PyJWT-2.13.0 annotated-types-0.7.0 anyio-4.14.1 azure-ai-projects-2.3.0 azure-core-1.41.0 azure-identity-1.25.3 azure-storage-blob-12.30.0 certifi-2026.6.17 cffi-2.1.0 charset_normalizer-3.4.9 cryptography-49.0.0 distro-1.9.0 h11-0.16.0 httpcore-1.0.9 httpx-0.28.1 idna-3.18 isodate-0.7.2 jiter-0.16.0 msal-1.37.0 msal-extensions-1.3.1 openai-2.44.0 pycparser-3.0 pydantic-2.13.4 pydantic-core-2.46.4 requests-2.34.2 sniffio-1.3.1 tqdm-4.68.4 typing-inspection-0.4.2 urllib3-2.7.0\n", + "Note: you may need to restart the kernel to use updated packages.\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + " WARNING: The script tqdm.exe is installed in 'c:\\Users\\ollisgeorge\\AppData\\Local\\Programs\\Python\\Python312-x64\\Scripts' which is not on PATH.\n", + " Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.\n", + " WARNING: The script idna.exe is installed in 'c:\\Users\\ollisgeorge\\AppData\\Local\\Programs\\Python\\Python312-x64\\Scripts' which is not on PATH.\n", + " Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.\n", + " WARNING: The script distro.exe is installed in 'c:\\Users\\ollisgeorge\\AppData\\Local\\Programs\\Python\\Python312-x64\\Scripts' which is not on PATH.\n", + " Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.\n", + " WARNING: The script normalizer.exe is installed in 'c:\\Users\\ollisgeorge\\AppData\\Local\\Programs\\Python\\Python312-x64\\Scripts' which is not on PATH.\n", + " Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.\n", + " WARNING: The script cffi-gen-src.exe is installed in 'c:\\Users\\ollisgeorge\\AppData\\Local\\Programs\\Python\\Python312-x64\\Scripts' which is not on PATH.\n", + " Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.\n", + " WARNING: The script httpx.exe is installed in 'c:\\Users\\ollisgeorge\\AppData\\Local\\Programs\\Python\\Python312-x64\\Scripts' which is not on PATH.\n", + " Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.\n", + "\n", + "[notice] A new release of pip is available: 25.0.1 -> 26.1.2\n", + "[notice] To update, run: python.exe -m pip install --upgrade pip\n" + ] + } + ], + "source": [ + "pip install azure-ai-projects==2.3.0" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "89e98ee4", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "acrvu4ax6chjqjsk.azurecr.io/strands-agent:1.0.0\n", + "Agent created: strands-1222121, version: 2\n" + ] + } + ], + "source": [ + "from azure.ai.projects import AIProjectClient\n", + "from azure.ai.projects.models import (\n", + " HostedAgentDefinition,\n", + " ProtocolVersionRecord,\n", + " AgentEndpointProtocol,\n", + " ContainerConfiguration,\n", + " )\n", + "from azure.identity import DefaultAzureCredential\n", + "\n", + "# Placeholder values - update before running\n", + "PROJECT_ENDPOINT = \"https://foundry-agents-vu4ax6chjqjsk.services.ai.azure.com/api/projects/default-foundry-agents\"\n", + "AGENT_NAME = \"strands-1222121\"\n", + "\n", + "# APIM inference endpoint for model calls.\n", + "# IMPORTANT: this APIM API must route to backend 'foundry-models'.\n", + "# Backend 'foundry-agents' is for hosted agent Responses API/proxy only.\n", + "AZURE_OPENAI_ENDPOINT = \"https://apim-vu4ax6chjqjsk.azure-api.net/inference/models\"\n", + "AZURE_OPENAI_API_VERSION = \"2024-05-01-preview\"\n", + "AZURE_OPENAI_DEPLOYMENT = \"gpt-5-mini\"\n", + "APIM_SUBSCRIPTION_KEY = \"da1b83bcbd6e45f4b94501061e298591\"\n", + "\n", + "print(IMAGE_URI)\n", + "\n", + "credential = DefaultAzureCredential()\n", + "project = AIProjectClient(\n", + " endpoint=PROJECT_ENDPOINT,\n", + " credential=credential,\n", + " allow_preview=True,\n", + " )\n", + "\n", + "agent = project.agents.create_version(\n", + " agent_name=AGENT_NAME,\n", + " definition=HostedAgentDefinition(\n", + " protocol_versions=[\n", + " ProtocolVersionRecord(protocol=AgentEndpointProtocol.RESPONSES, version=\"1.0.0\")\n", + " ],\n", + " cpu=\"1\",\n", + " memory=\"2Gi\",\n", + " container_configuration=ContainerConfiguration(image=IMAGE_URI),\n", + " environment_variables={\n", + " \"AZURE_OPENAI_ENDPOINT\": AZURE_OPENAI_ENDPOINT,\n", + " \"AZURE_OPENAI_API_VERSION\": AZURE_OPENAI_API_VERSION,\n", + " \"AZURE_OPENAI_DEPLOYMENT\": AZURE_OPENAI_DEPLOYMENT,\n", + " \"APIM_SUBSCRIPTION_KEY\": APIM_SUBSCRIPTION_KEY,\n", + " \"LOG_LEVEL\": \"INFO\",\n", + " \"STRANDS_LOG_LEVEL\": \"INFO\",\n", + " },\n", + " ),\n", + " )\n", + "\n", + "print(f\"Agent created: {agent.name}, version: {agent.version}\")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.10" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/Dockerfile b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/Dockerfile new file mode 100644 index 00000000..bf032f64 --- /dev/null +++ b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/Dockerfile @@ -0,0 +1,7 @@ +FROM python:3.12-slim +WORKDIR /app +COPY . user_agent/ +WORKDIR /app/user_agent +RUN if [ -f requirements.txt ]; then pip install -r requirements.txt; fi +EXPOSE 8088 +CMD ["python", "main.py"] \ No newline at end of file diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/README.md b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/README.md new file mode 100644 index 00000000..fef9d054 --- /dev/null +++ b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/README.md @@ -0,0 +1,32 @@ +# Strands Agent on Foundry Hosted Agents + +This sample code shows you how to run a Strands agent in Foundry Hosted Agents. + +![Strands Hosted Agent Sample](image.png) + +## What Is Included + +- `main.py`: Strands agent server implementation (Responses protocol) with tool calling and streaming. +- `Dockerfile`: Container definition for hosting the agent in Foundry Hosted Agents. +- `01_hosted_agent_strands_setup.ipynb`: End-to-end setup workbook. +- `requirements.txt`: Python dependencies. + +## Get Started + +1. Open and run `01_hosted_agent_strands_setup.ipynb` from top to bottom. +2. Build and push the container image to your Azure Container Registry. +3. Create a hosted agent version in your Foundry project. +4. Grant required permissions (including Foundry role assignment for the hosted agent identity). +5. Test prompts against the deployed hosted agent. + +## Prerequisites + +- Azure subscription with access to Microsoft Foundry and Azure Container Registry. +- Permission to push images to the target ACR repository. +- Permission to assign RBAC roles on the Foundry resource scope. +- Python environment with the dependencies in `requirements.txt`. + +## Notes + +- This sample is configured for identity-based auth patterns (no hard-coded OpenAI API key in `main.py`). +- Use the notebook placeholders to provide your own project, registry, and deployment values. diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/example.env b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/example.env new file mode 100644 index 00000000..d7135309 --- /dev/null +++ b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/example.env @@ -0,0 +1,6 @@ +AZURE_OPENAI_ENDPOINT=https://XXXXXXXXX.azure-api.net/inference/models +AZURE_OPENAI_DEPLOYMENT=gpt-5-mini +AZURE_OPENAI_API_VERSION=2024-05-01-preview +LOG_LEVEL=INFO +STRANDS_LOG_LEVEL=INFO +APIM_SUBSCRIPTION_KEY=XXXXXXXXX \ No newline at end of file diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/image.png b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/image.png new file mode 100644 index 0000000000000000000000000000000000000000..c1280167b3c652b63f737ed0aa1df6c843f5c39a GIT binary patch literal 141435 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 literal 0 HcmV?d00001 diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/main.py b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/main.py new file mode 100644 index 00000000..cb60c729 --- /dev/null +++ b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/main.py @@ -0,0 +1,279 @@ +"""Azure AI Agent Server (Responses protocol), +embedding the Strands Agents SDK as the agent framework. + +Requires the following environment variables (see .env): + + AZURE_OPENAI_ENDPOINT APIM base URL (recommended): + https://.azure-api.net/inference/models + or full chat-completions URL: + https://.azure-api.net/inference/models/chat/completions?api-version=2024-05-01-preview + AZURE_OPENAI_DEPLOYMENT model name sent as the chat-completions "model" field + AZURE_OPENAI_API_KEY required API key used for model calls (or OPENAI_API_KEY) + AZURE_OPENAI_API_VERSION optional, defaults to 2024-05-01-preview + APIM_SUBSCRIPTION_KEY optional; when set, sent as api-key + LOG_LEVEL optional, defaults to INFO + STRANDS_LOG_LEVEL optional, defaults to INFO (Strands SDK's own logger) + +Authentication: + + This app uses API key authentication for model calls. + It does not use managed identity for OpenAI chat-completions requests. + +Supports server-side function calling (the "Get Weather" tool and the +"show_internal_environment_variables" debug tool below, both implemented +with ``@tool`` and executed automatically by the Strands agent loop), +incremental token streaming of the model's answer (via +``agent.stream_async()``, piped into ``TextResponse`` as +``response.output_text.delta`` SSE events), image input (input_image content +parts, as inline data: URLs), and multi-turn conversation tracking (via the +Responses protocol's conversation_id / previous_response_id chaining, +surfaced through ResponseContext.get_history() and pre-loaded into the +Strands agent's message history). +""" + +import asyncio +import logging +import os +import random +from typing import Sequence + +from dotenv import load_dotenv +from openai import AsyncOpenAI + +from strands import Agent, tool +from strands.agent.conversation_manager import SlidingWindowConversationManager +from strands.models.openai import OpenAIModel +from strands.types.content import ContentBlock, Messages + +from azure.ai.agentserver.responses import ( + CreateResponse, + ResponseContext, + ResponsesAgentServerHost, + TextResponse, + data_url, +) +from azure.ai.agentserver.responses.models import ( + Item, + ItemMessage, + MessageContentInputImageContent, + MessageContentInputTextContent, + MessageContentRefusalContent, + OutputMessageContentOutputTextContent, + get_content_expanded, +) + +load_dotenv() + +# --- Logging ----------------------------------------------------------- +# A single basicConfig call surfaces logs from our own app logger, the +# Responses hosting layer, and the Strands SDK's agent loop / tool +# invocations, since they all log through the standard `logging` module. +logging.basicConfig( + level=os.environ.get("LOG_LEVEL", "INFO"), + format="%(asctime)s %(levelname)-8s %(name)s: %(message)s", +) +logging.getLogger("httpx").setLevel(logging.WARNING) # quiet noisy per-request HTTP logs +logging.getLogger("strands").setLevel(os.environ.get("STRANDS_LOG_LEVEL", "INFO")) + +logger = logging.getLogger("strands_responses_app") + +app = ResponsesAgentServerHost() + + +@tool +def show_internal_environment_variables() -> str: + """Return the internal environment variables that the Strands agent sees, for debugging.""" + env_vars = {k: v for k, v in os.environ.items()} + return f"{env_vars}" + +@tool +def get_weather(city: str) -> str: + """Get the current weather (temperature) for the given city. + + Args: + city: The city to look up the weather for. + """ + temperature_c = random.randint(-5, 35) + logger.info("tool_call=get_weather city=%s result_c=%s", city, temperature_c) + return f"The current temperature in {city} is {temperature_c}\u00b0C." + + +_MODEL: OpenAIModel | None = None + + +def build_model() -> OpenAIModel: + global _MODEL + if _MODEL is None: + endpoint = os.environ["AZURE_OPENAI_ENDPOINT"] + deployment = os.environ.get("AZURE_OPENAI_DEPLOYMENT", "gpt-5-mini") + api_key = ( + os.environ.get("AZURE_OPENAI_API_KEY") + or os.environ.get("OPENAI_API_KEY") + or os.environ.get("APIM_SUBSCRIPTION_KEY") + ) + if not api_key: + raise RuntimeError( + "Missing API key. Set AZURE_OPENAI_API_KEY (or OPENAI_API_KEY / APIM_SUBSCRIPTION_KEY)." + ) + + api_version = os.environ.get("AZURE_OPENAI_API_VERSION", "2024-05-01-preview") + base_url = endpoint.split("?", 1)[0].rstrip("/") + if base_url.endswith("/chat/completions"): + base_url = base_url[: -len("/chat/completions")] + + client = AsyncOpenAI( + base_url=base_url, + api_key=api_key, + default_query={"api-version": api_version}, + default_headers={"api-key": api_key}, + ) + + _MODEL = OpenAIModel(client=client, model_id=deployment) + return _MODEL + + +def _message_text(item: Item) -> list[str]: + """Extract plain text parts from an item's content, handling both the + typed ``list[MessageContent]`` form and the API's plain-string shorthand + (``get_content_expanded`` normalizes either into a list). Refusals are + included too — an assistant declining to answer is still meaningful + conversation context for the model to see on the next turn. + """ + texts = [] + for part in get_content_expanded(item): + if isinstance(part, (MessageContentInputTextContent, OutputMessageContentOutputTextContent)): + text = getattr(part, "text", None) + if text: + texts.append(text) + elif isinstance(part, MessageContentRefusalContent): + if part.refusal: + texts.append(f"[refused to answer: {part.refusal}]") + return texts + + +def _history_messages(history: Sequence[Item]) -> Messages: + """Convert prior conversation turns (from ResponseContext.get_history()) into + Strands ``Messages`` so the agent starts with full multi-turn context already + loaded into its conversation history.""" + messages: Messages = [] + for item in history: + role = getattr(item, "role", None) + if role not in ("user", "assistant"): + continue + texts = _message_text(item) + if texts: + role_str = getattr(role, "value", role) + messages.append({"role": role_str, "content": [{"text": text} for text in texts]}) + return messages + + +def _extract_image_blocks(items: Sequence[Item]) -> list[ContentBlock]: + """Pull input images out of the request's input items as Strands ContentBlocks. + + Only inline base64 ``data:`` URLs are supported, since Strands content + blocks carry raw image bytes rather than remote URLs. + """ + blocks: list[ContentBlock] = [] + for item in items: + if not isinstance(item, ItemMessage): + continue + for part in item.content or []: + if not isinstance(part, MessageContentInputImageContent): + continue + url = part.image_url + if not url: + continue + if data_url.is_data_url(url): + media_type = data_url.get_media_type(url) or "image/png" + image_format = media_type.split("/", 1)[-1] or "png" + raw_bytes = data_url.decode_bytes(url) + blocks.append({"image": {"format": image_format, "source": {"bytes": raw_bytes}}}) + else: + logger.warning("Skipping remote image URL; Strands requires inline image bytes: %s", url) + return blocks + + +def build_agent(history: Messages) -> Agent: + """Wire up a Strands agent with the weather tool, the Azure OpenAI model, + and prior conversation history pre-loaded so multi-turn context is + preserved across requests.""" + return Agent( + model=build_model(), + tools=[get_weather, show_internal_environment_variables], + system_prompt=( + "You are a helpful assistant who can explain concepts, answer questions, and " + "reason through problems. You have access to two tools - a weather tool that can provide the current " + "temperature when asked about weather or temperature in a specific place and a tool that can show the internal environment variables that the Strands agent sees, for debugging. " + ), + messages=list(history), + conversation_manager=SlidingWindowConversationManager(window_size=20), + callback_handler=None, + ) + + +@app.response_handler +async def handler( + request: CreateResponse, + context: ResponseContext, + cancellation_signal: asyncio.Event, +) -> TextResponse: + """Run a Strands agent against the request's input text/images and prior + conversation turns, with server-side function/tool calling support. + + Streams the model's answer token-by-token as it's generated (via Strands' + ``agent.stream_async()``), so the caller sees incremental + ``response.output_text.delta`` SSE events instead of waiting for the full + answer before anything is returned. + """ + input_items = await context.get_input_items() + input_text = await context.get_input_text() + history_items = await context.get_history() + + logger.info( + "response_id=%s input_chars=%d history_items=%d", + context.response_id, + len(input_text or ""), + len(history_items), + ) + + history_messages = _history_messages(history_items) + image_blocks = _extract_image_blocks(input_items) + + agent = build_agent(history_messages) + + content: list[ContentBlock] = [{"text": input_text}] if input_text else [] + content.extend(image_blocks) + + async def _generate_tokens(): + # Bridge the host's cooperative cancellation signal to the agent's own + # cancel() so a client disconnect/timeout stops in-flight model/tool calls. + async def _watch_cancellation() -> None: + await cancellation_signal.wait() + logger.warning("response_id=%s cancellation requested; stopping agent", context.response_id) + agent.cancel() + + watcher = asyncio.create_task(_watch_cancellation()) + try: + async for event in agent.stream_async(content or None): + text = event.get("data") + if isinstance(text, str) and text: + yield text + + result = event.get("result") + if result is not None: + logger.info( + "response_id=%s stop_reason=%s", + context.response_id, + result.stop_reason, + ) + except Exception: + logger.exception("response_id=%s agent invocation failed", context.response_id) + raise + finally: + watcher.cancel() + + return TextResponse(context, request, text=_generate_tokens()) + + +if __name__ == "__main__": + app.run() diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/requirements.txt b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/requirements.txt new file mode 100644 index 00000000..f6dc3847 --- /dev/null +++ b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/requirements.txt @@ -0,0 +1,4 @@ +azure-ai-agentserver-responses==1.0.0b8 +strands-agents[openai]==1.45.0 +python-dotenv +azure-ai-projects==2.3.0 diff --git a/modules/cognitive-services/v3/foundry.bicep b/modules/cognitive-services/v3/foundry.bicep index f50b4e0f..cb7bbe9a 100644 --- a/modules/cognitive-services/v3/foundry.bicep +++ b/modules/cognitive-services/v3/foundry.bicep @@ -161,6 +161,7 @@ output extendedAIServicesConfig array = [for (config, i) in aiServicesConfig: { cognitiveService: cognitiveServices[i] cognitiveServiceName: cognitiveServices[i].name cognitiveServicesId: cognitiveServices[i].id + principalId: cognitiveServices[i].identity.principalId endpoint: cognitiveServices[i].properties.endpoint foundryProjectEndpoint: 'https://${cognitiveServices[i].name}.services.ai.azure.com/api/projects/${aiProject[i].name}' }] From 139ff848eb5785458e0ea13532beee78348fd5ef Mon Sep 17 00:00:00 2001 From: George Ollis Date: Wed, 8 Jul 2026 19:15:06 +0100 Subject: [PATCH 02/17] Refactor code structure for improved readability and maintainability --- .../README.md | 15 +- ...undry-hosted-agents-custom-framework.ipynb | 930 ++++------- .../clean-up-resources.ipynb | 24 +- .../main.bicep | 39 +- .../01_hosted_agent_strands_setup.ipynb | 1371 ++++++++++------- 5 files changed, 1157 insertions(+), 1222 deletions(-) diff --git a/labs/ai-foundry-hosted-agents-custom-framework/README.md b/labs/ai-foundry-hosted-agents-custom-framework/README.md index 45585aa6..712e528c 100644 --- a/labs/ai-foundry-hosted-agents-custom-framework/README.md +++ b/labs/ai-foundry-hosted-agents-custom-framework/README.md @@ -4,14 +4,15 @@ architectureDiagram: images/ai-foundry-hosted-agents.gif categories: - AI Agents services: - - Azure AI Foundry + - Microsoft Foundry + - Hosted Agents - Azure API Management - - Azure Container Apps - - MCP + - Container Registry shortDescription: Deploy AI Foundry Hosted Agents built with custom frameworks, including Pydantic AI and Strands. detailedDescription: This lab provides custom framework examples for AI Foundry Hosted Agents, showing how to package and deploy hosted agents built with Pydantic AI and Strands to Azure Container Apps. It includes a Bicep deployment for Azure API Management, Azure AI Foundry, and a GPT-5-Mini model deployment, plus end-to-end setup notebooks and Dockerfiles. authors: - nourshaker-msft + - georgeollis tags: [] --- @@ -58,9 +59,9 @@ Use this notebook first to deploy core infrastructure with Bicep: The deployment also configures: -- ACR repository permissions for the hosted-agent Foundry resource (`Container Registry Repository Reader`) +- ACR repository permissions for the hosted-agent Foundry resource and its project identity (`Container Registry Repository Reader`) - ACR repository permissions for the deploying user (`Container Registry Repository Writer` + `Container Registry Repository Catalog Lister`) -- Foundry User role assignments (`Azure AI User`) for configured user object IDs across all Foundry resources deployed by this lab +- Foundry User role assignments (`Foundry User`) for configured user object IDs across all Foundry resources deployed by this lab - Optional APIM proxy API for the Hosted Agent Responses endpoint, added after the hosted agent has been deployed and is running The deployment template is in [main.bicep](main.bicep). @@ -88,10 +89,6 @@ The deployment template is in [main.bicep](main.bicep). 5. Deploy the hosted agent version in your Foundry project. 6. Set the hosted agent ID in the infra notebook config and re-run deployment to provision APIM fronting for the Responses API. -### Related lab - -For the full end-to-end APIM + Foundry hosted agent architecture, see [AI Foundry Hosted Agents](../ai-foundry-hosted-agents/README.md). - ### Clean up resources Use the [clean-up-resources notebook](clean-up-resources.ipynb) to remove deployed resources when you are finished. diff --git a/labs/ai-foundry-hosted-agents-custom-framework/ai-foundry-hosted-agents-custom-framework.ipynb b/labs/ai-foundry-hosted-agents-custom-framework/ai-foundry-hosted-agents-custom-framework.ipynb index 24e84fa3..be885a14 100644 --- a/labs/ai-foundry-hosted-agents-custom-framework/ai-foundry-hosted-agents-custom-framework.ipynb +++ b/labs/ai-foundry-hosted-agents-custom-framework/ai-foundry-hosted-agents-custom-framework.ipynb @@ -5,7 +5,7 @@ "id": "db72bfd0", "metadata": {}, "source": [ - "# AI Foundry Hosted Agents (Custom Frameworks)\n", + "# Microsoft Foundry Hosted Agents (Custom Frameworks)\n", "\n", "This notebook deploys the shared lab infrastructure using `main.bicep`:\n", "\n", @@ -47,7 +47,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 6, "id": "99068750", "metadata": {}, "outputs": [ @@ -85,7 +85,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 1, "id": "1c47a2ce", "metadata": {}, "outputs": [ @@ -99,7 +99,7 @@ ], "source": [ "# Update these values as needed\n", - "subscription_id = 'baba41cf-c01d-4a55-b6c5-ca494b802be5'\n", + "subscription_id = '9be21359-7b5a-4ccd-b0c7-24c97acd7d0c'\n", "resource_group = 'rg-aigw-hosted-custom-framework'\n", "location = 'swedencentral'\n", "deployment_name = 'deploy-hosted-custom-framework'\n", @@ -145,15 +145,15 @@ "\n", "# Deploy the hosted agent first. After it is running, set these values and rerun\n", "# this notebook to add the APIM proxy in front of the Hosted Agent Responses API.\n", - "enable_hosted_agent_responses_api = False\n", - "hosted_agent_id = '' # set to your deployed hosted agent id to enable APIM proxy\n", + "enable_hosted_agent_responses_api = True\n", + "hosted_agent_id = 'strands-agent:3' # set to your deployed hosted agent id to enable APIM proxy\n", "\n", "print('Configuration ready. Set real values before running deployment.')" ] }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 7, "id": "91b2888b", "metadata": {}, "outputs": [ @@ -215,7 +215,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 9, "id": "3c1be18b", "metadata": {}, "outputs": [ @@ -224,11 +224,11 @@ "output_type": "stream", "text": [ "\n", - "$ cmd /c C:\\Program Files\\Microsoft SDKs\\Azure\\CLI2\\wbin\\az.cmd account set --subscription baba41cf-c01d-4a55-b6c5-ca494b802be5\n", + "$ cmd /c C:\\Program Files\\Microsoft SDKs\\Azure\\CLI2\\wbin\\az.cmd account set --subscription 9be21359-7b5a-4ccd-b0c7-24c97acd7d0c\n", "\n", "$ cmd /c C:\\Program Files\\Microsoft SDKs\\Azure\\CLI2\\wbin\\az.cmd group create --name rg-aigw-hosted-custom-framework --location swedencentral\n", "{\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework\",\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework\",\n", " \"location\": \"swedencentral\",\n", " \"managedBy\": null,\n", " \"name\": \"rg-aigw-hosted-custom-framework\",\n", @@ -248,70 +248,158 @@ "$ cmd /c C:\\Program Files\\Microsoft SDKs\\Azure\\CLI2\\wbin\\az.cmd deployment group validate --resource-group rg-aigw-hosted-custom-framework --template-file C:\\GitHub\\ai-gateway\\AI-Gateway\\labs\\ai-foundry-hosted-agents-custom-framework\\main.bicep --parameters @C:\\GitHub\\ai-gateway\\AI-Gateway\\labs\\ai-foundry-hosted-agents-custom-framework\\main.parameters.generated.json --only-show-errors\n", "{\n", " \"error\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/main\",\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/main\",\n", " \"name\": \"main\",\n", " \"properties\": {\n", - " \"correlationId\": \"d22fd605-8099-4276-a378-c5e2c45d988f\",\n", + " \"correlationId\": \"8474ac3c-4c54-4861-bfd3-f9816f7a13f2\",\n", " \"debugSetting\": null,\n", " \"dependencies\": [\n", " {\n", " \"dependsOn\": [\n", " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrvu4ax6chjqjsk\",\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrxhep4wovroziu\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"acrxhep4wovroziu\",\n", + " \"resourceType\": \"Microsoft.ContainerRegistry/registries\"\n", + " },\n", + " {\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/foundryModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"foundryModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrxhep4wovroziu/providers/Microsoft.Authorization/roleAssignments/9fdae2e2-758a-52c5-a9f4-bbe68deee382\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"9fdae2e2-758a-52c5-a9f4-bbe68deee382\",\n", + " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", + " },\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrxhep4wovroziu\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"acrxhep4wovroziu\",\n", + " \"resourceType\": \"Microsoft.ContainerRegistry/registries\"\n", + " },\n", + " {\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/foundryModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"foundryModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrxhep4wovroziu/providers/Microsoft.Authorization/roleAssignments/d978b2df-d75d-526b-9743-60720d2c081c\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"d978b2df-d75d-526b-9743-60720d2c081c\",\n", + " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", + " },\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrxhep4wovroziu\",\n", " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"acrvu4ax6chjqjsk\",\n", + " \"resourceName\": \"acrxhep4wovroziu\",\n", " \"resourceType\": \"Microsoft.ContainerRegistry/registries\"\n", " },\n", " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/foundryModule\",\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/foundryModule\",\n", " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", " \"resourceName\": \"foundryModule\",\n", " \"resourceType\": \"Microsoft.Resources/deployments\"\n", " }\n", " ],\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrvu4ax6chjqjsk/providers/Microsoft.Authorization/roleAssignments/6801f057-9c94-548e-af97-b7aa48df6191\",\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrxhep4wovroziu/providers/Microsoft.Authorization/roleAssignments/63983143-77d9-582c-b53c-793fefd1bd93\",\n", " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"6801f057-9c94-548e-af97-b7aa48df6191\",\n", + " \"resourceName\": \"63983143-77d9-582c-b53c-793fefd1bd93\",\n", " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", " },\n", " {\n", " \"dependsOn\": [\n", " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrvu4ax6chjqjsk\",\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrxhep4wovroziu\",\n", " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"acrvu4ax6chjqjsk\",\n", + " \"resourceName\": \"acrxhep4wovroziu\",\n", " \"resourceType\": \"Microsoft.ContainerRegistry/registries\"\n", " }\n", " ],\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrvu4ax6chjqjsk/providers/Microsoft.Authorization/roleAssignments/9723640a-c519-5fbd-8169-28d574b21f8f\",\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrxhep4wovroziu/providers/Microsoft.Authorization/roleAssignments/b0406c01-b2e5-5a38-8735-416921bc283e\",\n", " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"9723640a-c519-5fbd-8169-28d574b21f8f\",\n", + " \"resourceName\": \"b0406c01-b2e5-5a38-8735-416921bc283e\",\n", " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", " },\n", " {\n", " \"dependsOn\": [\n", " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrvu4ax6chjqjsk\",\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrxhep4wovroziu\",\n", " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"acrvu4ax6chjqjsk\",\n", + " \"resourceName\": \"acrxhep4wovroziu\",\n", " \"resourceType\": \"Microsoft.ContainerRegistry/registries\"\n", " }\n", " ],\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrvu4ax6chjqjsk/providers/Microsoft.Authorization/roleAssignments/eb950c04-f5c5-5133-b32d-b544c7b7681c\",\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrxhep4wovroziu/providers/Microsoft.Authorization/roleAssignments/c3a8ec22-2dde-50ce-a21a-2adcc18a175f\",\n", " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"eb950c04-f5c5-5133-b32d-b544c7b7681c\",\n", + " \"resourceName\": \"c3a8ec22-2dde-50ce-a21a-2adcc18a175f\",\n", " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", " },\n", " {\n", " \"dependsOn\": [\n", " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/lawModule\",\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/apimModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"apimModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " },\n", + " {\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/foundryModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"foundryModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ApiManagement/service/apim-xhep4wovroziu/apis/hosted-agent-responses-api\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"apim-xhep4wovroziu/hosted-agent-responses-api\",\n", + " \"resourceType\": \"Microsoft.ApiManagement/service/apis\"\n", + " },\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ApiManagement/service/apim-xhep4wovroziu/apis/hosted-agent-responses-api\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"apim-xhep4wovroziu/hosted-agent-responses-api\",\n", + " \"resourceType\": \"Microsoft.ApiManagement/service/apis\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ApiManagement/service/apim-xhep4wovroziu/apis/hosted-agent-responses-api/operations/create-response\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"apim-xhep4wovroziu/hosted-agent-responses-api/create-response\",\n", + " \"resourceType\": \"Microsoft.ApiManagement/service/apis/operations\"\n", + " },\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ApiManagement/service/apim-xhep4wovroziu/apis/hosted-agent-responses-api\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"apim-xhep4wovroziu/hosted-agent-responses-api\",\n", + " \"resourceType\": \"Microsoft.ApiManagement/service/apis\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ApiManagement/service/apim-xhep4wovroziu/apis/hosted-agent-responses-api/policies/policy\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"apim-xhep4wovroziu/hosted-agent-responses-api/policy\",\n", + " \"resourceType\": \"Microsoft.ApiManagement/service/apis/policies\"\n", + " },\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/lawModule\",\n", " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", " \"resourceName\": \"lawModule\",\n", " \"resourceType\": \"Microsoft.Resources/deployments\"\n", " }\n", " ],\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/appInsightsModule\",\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/appInsightsModule\",\n", " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", " \"resourceName\": \"appInsightsModule\",\n", " \"resourceType\": \"Microsoft.Resources/deployments\"\n", @@ -319,19 +407,19 @@ " {\n", " \"dependsOn\": [\n", " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/appInsightsModule\",\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/appInsightsModule\",\n", " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", " \"resourceName\": \"appInsightsModule\",\n", " \"resourceType\": \"Microsoft.Resources/deployments\"\n", " },\n", " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/lawModule\",\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/lawModule\",\n", " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", " \"resourceName\": \"lawModule\",\n", " \"resourceType\": \"Microsoft.Resources/deployments\"\n", " }\n", " ],\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/apimModule\",\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/apimModule\",\n", " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", " \"resourceName\": \"apimModule\",\n", " \"resourceType\": \"Microsoft.Resources/deployments\"\n", @@ -339,19 +427,19 @@ " {\n", " \"dependsOn\": [\n", " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/apimModule\",\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/apimModule\",\n", " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", " \"resourceName\": \"apimModule\",\n", " \"resourceType\": \"Microsoft.Resources/deployments\"\n", " },\n", " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/appInsightsModule\",\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/appInsightsModule\",\n", " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", " \"resourceName\": \"appInsightsModule\",\n", " \"resourceType\": \"Microsoft.Resources/deployments\"\n", " }\n", " ],\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/foundryModule\",\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/foundryModule\",\n", " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", " \"resourceName\": \"foundryModule\",\n", " \"resourceType\": \"Microsoft.Resources/deployments\"\n", @@ -359,28 +447,56 @@ " {\n", " \"dependsOn\": [\n", " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/apimModule\",\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/apimModule\",\n", " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", " \"resourceName\": \"apimModule\",\n", " \"resourceType\": \"Microsoft.Resources/deployments\"\n", " },\n", " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/appInsightsModule\",\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/appInsightsModule\",\n", " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", " \"resourceName\": \"appInsightsModule\",\n", " \"resourceType\": \"Microsoft.Resources/deployments\"\n", " },\n", " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/foundryModule\",\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/foundryModule\",\n", " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", " \"resourceName\": \"foundryModule\",\n", " \"resourceType\": \"Microsoft.Resources/deployments\"\n", " }\n", " ],\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/inferenceAPIModule\",\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/inferenceAPIModule\",\n", " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", " \"resourceName\": \"inferenceAPIModule\",\n", " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " },\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/foundryModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"foundryModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.CognitiveServices/accounts/foundry-models-xhep4wovroziu/providers/Microsoft.Authorization/roleAssignments/dc422f45-552b-5b34-9880-e664b7afe0aa\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"dc422f45-552b-5b34-9880-e664b7afe0aa\",\n", + " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", + " },\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/foundryModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"foundryModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.CognitiveServices/accounts/foundry-agents-xhep4wovroziu/providers/Microsoft.Authorization/roleAssignments/c4d31936-032e-5bdb-b9d3-a12891127593\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", + " \"resourceName\": \"c4d31936-032e-5bdb-b9d3-a12891127593\",\n", + " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", " }\n", " ],\n", " \"diagnostics\": [\n", @@ -389,28 +505,28 @@ " \"code\": \"NestedDeploymentShortCircuited\",\n", " \"level\": \"Warning\",\n", " \"message\": \"A nested deployment got short-circuited and all its resources got skipped from validation. This is due to a nested template having a parameter that was not fully evaluated (e.g. contains a reference() function). Please see https://aka.ms/WhatIfEvalStopped for more guidance.\",\n", - " \"target\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/appInsightsModule\"\n", + " \"target\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/appInsightsModule\"\n", " },\n", " {\n", " \"additionalInfo\": null,\n", " \"code\": \"NestedDeploymentShortCircuited\",\n", " \"level\": \"Warning\",\n", " \"message\": \"A nested deployment got short-circuited and all its resources got skipped from validation. This is due to a nested template having a parameter that was not fully evaluated (e.g. contains a reference() function). Please see https://aka.ms/WhatIfEvalStopped for more guidance.\",\n", - " \"target\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/apimModule\"\n", + " \"target\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/apimModule\"\n", " },\n", " {\n", " \"additionalInfo\": null,\n", " \"code\": \"NestedDeploymentShortCircuited\",\n", " \"level\": \"Warning\",\n", " \"message\": \"A nested deployment got short-circuited and all its resources got skipped from validation. This is due to a nested template having a parameter that was not fully evaluated (e.g. contains a reference() function). Please see https://aka.ms/WhatIfEvalStopped for more guidance.\",\n", - " \"target\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/foundryModule\"\n", + " \"target\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/foundryModule\"\n", " },\n", " {\n", " \"additionalInfo\": null,\n", " \"code\": \"NestedDeploymentShortCircuited\",\n", " \"level\": \"Warning\",\n", " \"message\": \"A nested deployment got short-circuited and all its resources got skipped from validation. This is due to a nested template having a parameter that was not fully evaluated (e.g. contains a reference() function). Please see https://aka.ms/WhatIfEvalStopped for more guidance.\",\n", - " \"target\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/inferenceAPIModule\"\n", + " \"target\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/inferenceAPIModule\"\n", " }\n", " ],\n", " \"duration\": \"PT0S\",\n", @@ -454,7 +570,7 @@ " },\n", " \"enableHostedAgentResponsesApi\": {\n", " \"type\": \"Bool\",\n", - " \"value\": false\n", + " \"value\": true\n", " },\n", " \"foundryAgentAiServiceIndex\": {\n", " \"type\": \"Int\",\n", @@ -472,7 +588,7 @@ " },\n", " \"hostedAgentId\": {\n", " \"type\": \"String\",\n", - " \"value\": \"\"\n", + " \"value\": \"strands-agent:3\"\n", " },\n", " \"hostedAgentResponsesApiPath\": {\n", " \"type\": \"String\",\n", @@ -554,6 +670,57 @@ " },\n", " {\n", " \"id\": null,\n", + " \"namespace\": \"Microsoft.ApiManagement\",\n", + " \"providerAuthorizationConsentState\": null,\n", + " \"registrationPolicy\": null,\n", + " \"registrationState\": null,\n", + " \"resourceTypes\": [\n", + " {\n", + " \"aliases\": null,\n", + " \"apiProfiles\": null,\n", + " \"apiVersions\": null,\n", + " \"capabilities\": null,\n", + " \"defaultApiVersion\": null,\n", + " \"locationMappings\": null,\n", + " \"locations\": [\n", + " null\n", + " ],\n", + " \"properties\": null,\n", + " \"resourceType\": \"service/apis\",\n", + " \"zoneMappings\": null\n", + " },\n", + " {\n", + " \"aliases\": null,\n", + " \"apiProfiles\": null,\n", + " \"apiVersions\": null,\n", + " \"capabilities\": null,\n", + " \"defaultApiVersion\": null,\n", + " \"locationMappings\": null,\n", + " \"locations\": [\n", + " null\n", + " ],\n", + " \"properties\": null,\n", + " \"resourceType\": \"service/apis/operations\",\n", + " \"zoneMappings\": null\n", + " },\n", + " {\n", + " \"aliases\": null,\n", + " \"apiProfiles\": null,\n", + " \"apiVersions\": null,\n", + " \"capabilities\": null,\n", + " \"defaultApiVersion\": null,\n", + " \"locationMappings\": null,\n", + " \"locations\": [\n", + " null\n", + " ],\n", + " \"properties\": null,\n", + " \"resourceType\": \"service/apis/policies\",\n", + " \"zoneMappings\": null\n", + " }\n", + " ]\n", + " },\n", + " {\n", + " \"id\": null,\n", " \"namespace\": \"Microsoft.Resources\",\n", " \"providerAuthorizationConsentState\": null,\n", " \"registrationPolicy\": null,\n", @@ -577,14 +744,14 @@ " }\n", " ],\n", " \"provisioningState\": \"Succeeded\",\n", - " \"templateHash\": \"5327887757473726207\",\n", + " \"templateHash\": \"12337644779082219195\",\n", " \"templateLink\": null,\n", - " \"timestamp\": \"2026-07-08T13:24:11.057134+00:00\",\n", + " \"timestamp\": \"2026-07-08T17:46:38.824042+00:00\",\n", " \"validatedResources\": [\n", " {\n", " \"apiVersion\": null,\n", " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.CognitiveServices/accounts/foundry-agents-vu4ax6chjqjsk/providers/Microsoft.Authorization/roleAssignments/b81335fb-f585-5a98-b1d3-b05ccfc27073\",\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ApiManagement/service/apim-xhep4wovroziu/apis/hosted-agent-responses-api\",\n", " \"identifiers\": null,\n", " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", " \"resourceType\": null\n", @@ -592,7 +759,7 @@ " {\n", " \"apiVersion\": null,\n", " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.CognitiveServices/accounts/foundry-models-vu4ax6chjqjsk/providers/Microsoft.Authorization/roleAssignments/219a9a8c-8372-5217-8a2e-f11f82a3b4b0\",\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ApiManagement/service/apim-xhep4wovroziu/apis/hosted-agent-responses-api/operations/create-response\",\n", " \"identifiers\": null,\n", " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", " \"resourceType\": null\n", @@ -600,7 +767,7 @@ " {\n", " \"apiVersion\": null,\n", " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrvu4ax6chjqjsk\",\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ApiManagement/service/apim-xhep4wovroziu/apis/hosted-agent-responses-api/policies/policy\",\n", " \"identifiers\": null,\n", " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", " \"resourceType\": null\n", @@ -608,7 +775,7 @@ " {\n", " \"apiVersion\": null,\n", " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrvu4ax6chjqjsk/providers/Microsoft.Authorization/roleAssignments/6801f057-9c94-548e-af97-b7aa48df6191\",\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.CognitiveServices/accounts/foundry-agents-xhep4wovroziu/providers/Microsoft.Authorization/roleAssignments/c4d31936-032e-5bdb-b9d3-a12891127593\",\n", " \"identifiers\": null,\n", " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", " \"resourceType\": null\n", @@ -616,7 +783,7 @@ " {\n", " \"apiVersion\": null,\n", " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrvu4ax6chjqjsk/providers/Microsoft.Authorization/roleAssignments/9723640a-c519-5fbd-8169-28d574b21f8f\",\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.CognitiveServices/accounts/foundry-models-xhep4wovroziu/providers/Microsoft.Authorization/roleAssignments/dc422f45-552b-5b34-9880-e664b7afe0aa\",\n", " \"identifiers\": null,\n", " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", " \"resourceType\": null\n", @@ -624,7 +791,7 @@ " {\n", " \"apiVersion\": null,\n", " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrvu4ax6chjqjsk/providers/Microsoft.Authorization/roleAssignments/eb950c04-f5c5-5133-b32d-b544c7b7681c\",\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrxhep4wovroziu\",\n", " \"identifiers\": null,\n", " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", " \"resourceType\": null\n", @@ -632,7 +799,7 @@ " {\n", " \"apiVersion\": null,\n", " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.OperationalInsights/workspaces/workspace-vu4ax6chjqjsk\",\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrxhep4wovroziu/providers/Microsoft.Authorization/roleAssignments/63983143-77d9-582c-b53c-793fefd1bd93\",\n", " \"identifiers\": null,\n", " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", " \"resourceType\": null\n", @@ -640,7 +807,7 @@ " {\n", " \"apiVersion\": null,\n", " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/apimModule\",\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrxhep4wovroziu/providers/Microsoft.Authorization/roleAssignments/9fdae2e2-758a-52c5-a9f4-bbe68deee382\",\n", " \"identifiers\": null,\n", " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", " \"resourceType\": null\n", @@ -648,7 +815,7 @@ " {\n", " \"apiVersion\": null,\n", " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/appInsightsModule\",\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrxhep4wovroziu/providers/Microsoft.Authorization/roleAssignments/b0406c01-b2e5-5a38-8735-416921bc283e\",\n", " \"identifiers\": null,\n", " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", " \"resourceType\": null\n", @@ -656,7 +823,7 @@ " {\n", " \"apiVersion\": null,\n", " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/foundryModule\",\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrxhep4wovroziu/providers/Microsoft.Authorization/roleAssignments/c3a8ec22-2dde-50ce-a21a-2adcc18a175f\",\n", " \"identifiers\": null,\n", " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", " \"resourceType\": null\n", @@ -664,7 +831,7 @@ " {\n", " \"apiVersion\": null,\n", " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/inferenceAPIModule\",\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrxhep4wovroziu/providers/Microsoft.Authorization/roleAssignments/d978b2df-d75d-526b-9743-60720d2c081c\",\n", " \"identifiers\": null,\n", " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", " \"resourceType\": null\n", @@ -672,643 +839,84 @@ " {\n", " \"apiVersion\": null,\n", " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/lawModule\",\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.OperationalInsights/workspaces/workspace-xhep4wovroziu\",\n", " \"identifiers\": null,\n", " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", " \"resourceType\": null\n", - " }\n", - " ],\n", - " \"validationLevel\": null\n", - " },\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"type\": \"Microsoft.Resources/deployments\"\n", - "}\n", - "\n", - "\n", - "$ cmd /c C:\\Program Files\\Microsoft SDKs\\Azure\\CLI2\\wbin\\az.cmd deployment group create --resource-group rg-aigw-hosted-custom-framework --name deploy-hosted-custom-framework --template-file C:\\GitHub\\ai-gateway\\AI-Gateway\\labs\\ai-foundry-hosted-agents-custom-framework\\main.bicep --parameters @C:\\GitHub\\ai-gateway\\AI-Gateway\\labs\\ai-foundry-hosted-agents-custom-framework\\main.parameters.generated.json --only-show-errors\n", - "{\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/deploy-hosted-custom-framework\",\n", - " \"location\": null,\n", - " \"name\": \"deploy-hosted-custom-framework\",\n", - " \"properties\": {\n", - " \"correlationId\": \"1d492275-6c20-49e0-88e7-ba8679def3c7\",\n", - " \"debugSetting\": null,\n", - " \"dependencies\": [\n", - " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrvu4ax6chjqjsk\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"acrvu4ax6chjqjsk\",\n", - " \"resourceType\": \"Microsoft.ContainerRegistry/registries\"\n", - " },\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/foundryModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"foundryModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrvu4ax6chjqjsk/providers/Microsoft.Authorization/roleAssignments/6801f057-9c94-548e-af97-b7aa48df6191\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"6801f057-9c94-548e-af97-b7aa48df6191\",\n", - " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", - " },\n", - " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrvu4ax6chjqjsk\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"acrvu4ax6chjqjsk\",\n", - " \"resourceType\": \"Microsoft.ContainerRegistry/registries\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrvu4ax6chjqjsk/providers/Microsoft.Authorization/roleAssignments/9723640a-c519-5fbd-8169-28d574b21f8f\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"9723640a-c519-5fbd-8169-28d574b21f8f\",\n", - " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", " },\n", " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrvu4ax6chjqjsk\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"acrvu4ax6chjqjsk\",\n", - " \"resourceType\": \"Microsoft.ContainerRegistry/registries\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrvu4ax6chjqjsk/providers/Microsoft.Authorization/roleAssignments/eb950c04-f5c5-5133-b32d-b544c7b7681c\",\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/apimModule\",\n", + " \"identifiers\": null,\n", " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"eb950c04-f5c5-5133-b32d-b544c7b7681c\",\n", - " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", + " \"resourceType\": null\n", " },\n", " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/lawModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"lawModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/appInsightsModule\",\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/appInsightsModule\",\n", + " \"identifiers\": null,\n", " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"appInsightsModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " \"resourceType\": null\n", " },\n", " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/appInsightsModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"appInsightsModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " },\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/lawModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"lawModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/apimModule\",\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/foundryModule\",\n", + " \"identifiers\": null,\n", " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"apimModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " \"resourceType\": null\n", " },\n", " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/apimModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"apimModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " },\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/appInsightsModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"appInsightsModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/foundryModule\",\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/inferenceAPIModule\",\n", + " \"identifiers\": null,\n", " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"foundryModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " \"resourceType\": null\n", " },\n", " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/apimModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"apimModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " },\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/appInsightsModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"appInsightsModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " },\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/foundryModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"foundryModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/inferenceAPIModule\",\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/lawModule\",\n", + " \"identifiers\": null,\n", " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"inferenceAPIModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " \"resourceType\": null\n", " }\n", " ],\n", - " \"diagnostics\": null,\n", - " \"duration\": \"PT2M9.8411308S\",\n", - " \"error\": null,\n", - " \"extensions\": [],\n", - " \"mode\": \"Incremental\",\n", - " \"onErrorDeployment\": null,\n", - " \"outputResources\": [\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ApiManagement/service/apim-vu4ax6chjqjsk\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceType\": \"Microsoft.ApiManagement/service\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ApiManagement/service/apim-vu4ax6chjqjsk/apis/inference-api\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceType\": \"Microsoft.ApiManagement/service/apis\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ApiManagement/service/apim-vu4ax6chjqjsk/apis/inference-api/diagnostics/applicationinsights\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceType\": \"Microsoft.ApiManagement/service/apis/diagnostics\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ApiManagement/service/apim-vu4ax6chjqjsk/apis/inference-api/diagnostics/azuremonitor\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceType\": \"Microsoft.ApiManagement/service/apis/diagnostics\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ApiManagement/service/apim-vu4ax6chjqjsk/apis/inference-api/policies/policy\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceType\": \"Microsoft.ApiManagement/service/apis/policies\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ApiManagement/service/apim-vu4ax6chjqjsk/backends/foundry-agents\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceType\": \"Microsoft.ApiManagement/service/backends\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ApiManagement/service/apim-vu4ax6chjqjsk/backends/foundry-models\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceType\": \"Microsoft.ApiManagement/service/backends\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ApiManagement/service/apim-vu4ax6chjqjsk/backends/inference-backend-pool\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceType\": \"Microsoft.ApiManagement/service/backends\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ApiManagement/service/apim-vu4ax6chjqjsk/loggers/appinsights-logger\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceType\": \"Microsoft.ApiManagement/service/loggers\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ApiManagement/service/apim-vu4ax6chjqjsk/loggers/azuremonitor\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceType\": \"Microsoft.ApiManagement/service/loggers\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ApiManagement/service/apim-vu4ax6chjqjsk/providers/Microsoft.Insights/diagnosticSettings/apimDiagnosticSettings\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceType\": \"Microsoft.Insights/diagnosticSettings\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ApiManagement/service/apim-vu4ax6chjqjsk/subscriptions/starter\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceType\": \"Microsoft.ApiManagement/service/subscriptions\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.CognitiveServices/accounts/foundry-agents-vu4ax6chjqjsk\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceType\": \"Microsoft.CognitiveServices/accounts\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.CognitiveServices/accounts/foundry-agents-vu4ax6chjqjsk/connections/foundry-agents-vu4ax6chjqjsk-appInsights-connection\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceType\": \"Microsoft.CognitiveServices/accounts/connections\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.CognitiveServices/accounts/foundry-agents-vu4ax6chjqjsk/projects/default-foundry-agents\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceType\": \"Microsoft.CognitiveServices/accounts/projects\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.CognitiveServices/accounts/foundry-agents-vu4ax6chjqjsk/providers/Microsoft.Authorization/roleAssignments/b81335fb-f585-5a98-b1d3-b05ccfc27073\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.CognitiveServices/accounts/foundry-agents-vu4ax6chjqjsk/providers/Microsoft.Authorization/roleAssignments/d45230ae-0cb5-50d7-89ec-f52d6e03a1eb\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.CognitiveServices/accounts/foundry-agents-vu4ax6chjqjsk/providers/Microsoft.Authorization/roleAssignments/ff4f129c-e3f6-5883-b38a-1c5bc316a76e\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.CognitiveServices/accounts/foundry-models-vu4ax6chjqjsk\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceType\": \"Microsoft.CognitiveServices/accounts\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.CognitiveServices/accounts/foundry-models-vu4ax6chjqjsk/connections/foundry-models-vu4ax6chjqjsk-appInsights-connection\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceType\": \"Microsoft.CognitiveServices/accounts/connections\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.CognitiveServices/accounts/foundry-models-vu4ax6chjqjsk/deployments/gpt-5-mini\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceType\": \"Microsoft.CognitiveServices/accounts/deployments\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.CognitiveServices/accounts/foundry-models-vu4ax6chjqjsk/projects/default-foundry-models\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceType\": \"Microsoft.CognitiveServices/accounts/projects\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.CognitiveServices/accounts/foundry-models-vu4ax6chjqjsk/providers/Microsoft.Authorization/roleAssignments/219a9a8c-8372-5217-8a2e-f11f82a3b4b0\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.CognitiveServices/accounts/foundry-models-vu4ax6chjqjsk/providers/Microsoft.Authorization/roleAssignments/9857ad42-3883-5922-9a5d-0ed64839c8db\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.CognitiveServices/accounts/foundry-models-vu4ax6chjqjsk/providers/Microsoft.Authorization/roleAssignments/ded6fc2f-cd1d-51cb-af6c-3562b9dcbf8c\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrvu4ax6chjqjsk\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceType\": \"Microsoft.ContainerRegistry/registries\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrvu4ax6chjqjsk/providers/Microsoft.Authorization/roleAssignments/6801f057-9c94-548e-af97-b7aa48df6191\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrvu4ax6chjqjsk/providers/Microsoft.Authorization/roleAssignments/9723640a-c519-5fbd-8169-28d574b21f8f\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrvu4ax6chjqjsk/providers/Microsoft.Authorization/roleAssignments/eb950c04-f5c5-5133-b32d-b544c7b7681c\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Insights/components/insights-vu4ax6chjqjsk\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceType\": \"Microsoft.Insights/components\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.OperationalInsights/workspaces/workspace-vu4ax6chjqjsk\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceType\": \"Microsoft.OperationalInsights/workspaces\"\n", - " }\n", - " ],\n", - " \"outputs\": {\n", - " \"aiGatewayUrl\": {\n", - " \"type\": \"String\",\n", - " \"value\": \"https://apim-vu4ax6chjqjsk.azure-api.net/inference\"\n", - " },\n", - " \"apimGatewayUrl\": {\n", - " \"type\": \"String\",\n", - " \"value\": \"https://apim-vu4ax6chjqjsk.azure-api.net\"\n", - " },\n", - " \"apimServiceId\": {\n", - " \"type\": \"String\",\n", - " \"value\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ApiManagement/service/apim-vu4ax6chjqjsk\"\n", - " },\n", - " \"apimSubscriptions\": {\n", - " \"type\": \"Array\",\n", - " \"value\": [\n", - " {\n", - " \"displayName\": \"Starter\",\n", - " \"key\": \"da1b83bcbd6e45f4b94501061e298591\",\n", - " \"name\": \"starter\"\n", - " }\n", - " ]\n", - " },\n", - " \"containerRegistryLoginServer\": {\n", - " \"type\": \"String\",\n", - " \"value\": \"acrvu4ax6chjqjsk.azurecr.io\"\n", - " },\n", - " \"containerRegistryName\": {\n", - " \"type\": \"String\",\n", - " \"value\": \"acrvu4ax6chjqjsk\"\n", - " },\n", - " \"foundryAgentAiServicesEndpoint\": {\n", - " \"type\": \"String\",\n", - " \"value\": \"https://foundry-agents-vu4ax6chjqjsk.cognitiveservices.azure.com/\"\n", - " },\n", - " \"foundryAgentProjectEndpoint\": {\n", - " \"type\": \"String\",\n", - " \"value\": \"https://foundry-agents-vu4ax6chjqjsk.services.ai.azure.com/api/projects/default-foundry-agents\"\n", - " },\n", - " \"foundryAiServicesEndpoint\": {\n", - " \"type\": \"String\",\n", - " \"value\": \"https://foundry-models-vu4ax6chjqjsk.cognitiveservices.azure.com/\"\n", - " },\n", - " \"foundryProjectEndpoint\": {\n", - " \"type\": \"String\",\n", - " \"value\": \"https://foundry-models-vu4ax6chjqjsk.services.ai.azure.com/api/projects/default-foundry-models\"\n", - " },\n", - " \"hostedAgentResponsesApimPath\": {\n", - " \"type\": \"String\",\n", - " \"value\": \"\"\n", - " },\n", - " \"logAnalyticsWorkspaceId\": {\n", - " \"type\": \"String\",\n", - " \"value\": \"56c0f43f-b689-49a2-b2c3-0a14b9a61ebb\"\n", - " }\n", - " },\n", - " \"parameters\": {\n", - " \"aiServicesConfig\": {\n", - " \"type\": \"Array\",\n", - " \"value\": [\n", - " {\n", - " \"location\": \"swedencentral\",\n", - " \"name\": \"foundry-models\",\n", - " \"priority\": 1,\n", - " \"weight\": 100\n", - " },\n", - " {\n", - " \"location\": \"swedencentral\",\n", - " \"name\": \"foundry-agents\",\n", - " \"priority\": 1,\n", - " \"weight\": 100\n", - " }\n", - " ]\n", - " },\n", - " \"apimSku\": {\n", - " \"type\": \"String\",\n", - " \"value\": \"Basicv2\"\n", - " },\n", - " \"apimSubscriptionsConfig\": {\n", - " \"type\": \"Array\",\n", - " \"value\": [\n", - " {\n", - " \"displayName\": \"Starter\",\n", - " \"name\": \"starter\",\n", - " \"scope\": \"/apis\"\n", - " }\n", - " ]\n", - " },\n", - " \"enableHostedAgentResponsesApi\": {\n", - " \"type\": \"Bool\",\n", - " \"value\": false\n", - " },\n", - " \"foundryAgentAiServiceIndex\": {\n", - " \"type\": \"Int\",\n", - " \"value\": 1\n", - " },\n", - " \"foundryProjectName\": {\n", - " \"type\": \"String\",\n", - " \"value\": \"default\"\n", - " },\n", - " \"foundryUserObjectIds\": {\n", - " \"type\": \"Array\",\n", - " \"value\": [\n", - " \"13f94c0d-8a51-492a-928b-59392c23c1ac\"\n", - " ]\n", - " },\n", - " \"hostedAgentId\": {\n", - " \"type\": \"String\",\n", - " \"value\": \"\"\n", - " },\n", - " \"hostedAgentResponsesApiPath\": {\n", - " \"type\": \"String\",\n", - " \"value\": \"hosted-agent-responses\"\n", - " },\n", - " \"hostedAgentResponsesApiVersion\": {\n", - " \"type\": \"String\",\n", - " \"value\": \"2025-05-15-preview\"\n", - " },\n", - " \"inferenceAPIPath\": {\n", - " \"type\": \"String\",\n", - " \"value\": \"inference\"\n", - " },\n", - " \"inferenceAPIType\": {\n", - " \"type\": \"String\",\n", - " \"value\": \"AzureAI\"\n", - " },\n", - " \"modelsConfig\": {\n", - " \"type\": \"Array\",\n", - " \"value\": [\n", - " {\n", - " \"aiservice\": \"foundry-models\",\n", - " \"capacity\": 10,\n", - " \"name\": \"gpt-5-mini\",\n", - " \"publisher\": \"OpenAI\",\n", - " \"sku\": \"GlobalStandard\",\n", - " \"version\": \"2025-08-07\"\n", - " }\n", - " ]\n", - " }\n", - " },\n", - " \"parametersLink\": null,\n", - " \"providers\": [\n", - " {\n", - " \"id\": null,\n", - " \"namespace\": \"Microsoft.ContainerRegistry\",\n", - " \"providerAuthorizationConsentState\": null,\n", - " \"registrationPolicy\": null,\n", - " \"registrationState\": null,\n", - " \"resourceTypes\": [\n", - " {\n", - " \"aliases\": null,\n", - " \"apiProfiles\": null,\n", - " \"apiVersions\": null,\n", - " \"capabilities\": null,\n", - " \"defaultApiVersion\": null,\n", - " \"locationMappings\": null,\n", - " \"locations\": [\n", - " \"swedencentral\"\n", - " ],\n", - " \"properties\": null,\n", - " \"resourceType\": \"registries\",\n", - " \"zoneMappings\": null\n", - " }\n", - " ]\n", - " },\n", - " {\n", - " \"id\": null,\n", - " \"namespace\": \"Microsoft.Authorization\",\n", - " \"providerAuthorizationConsentState\": null,\n", - " \"registrationPolicy\": null,\n", - " \"registrationState\": null,\n", - " \"resourceTypes\": [\n", - " {\n", - " \"aliases\": null,\n", - " \"apiProfiles\": null,\n", - " \"apiVersions\": null,\n", - " \"capabilities\": null,\n", - " \"defaultApiVersion\": null,\n", - " \"locationMappings\": null,\n", - " \"locations\": [\n", - " null\n", - " ],\n", - " \"properties\": null,\n", - " \"resourceType\": \"roleAssignments\",\n", - " \"zoneMappings\": null\n", - " }\n", - " ]\n", - " },\n", - " {\n", - " \"id\": null,\n", - " \"namespace\": \"Microsoft.Resources\",\n", - " \"providerAuthorizationConsentState\": null,\n", - " \"registrationPolicy\": null,\n", - " \"registrationState\": null,\n", - " \"resourceTypes\": [\n", - " {\n", - " \"aliases\": null,\n", - " \"apiProfiles\": null,\n", - " \"apiVersions\": null,\n", - " \"capabilities\": null,\n", - " \"defaultApiVersion\": null,\n", - " \"locationMappings\": null,\n", - " \"locations\": [\n", - " null\n", - " ],\n", - " \"properties\": null,\n", - " \"resourceType\": \"deployments\",\n", - " \"zoneMappings\": null\n", - " }\n", - " ]\n", - " }\n", - " ],\n", - " \"provisioningState\": \"Succeeded\",\n", - " \"templateHash\": \"5327887757473726207\",\n", - " \"templateLink\": null,\n", - " \"timestamp\": \"2026-07-08T13:26:39.315593+00:00\",\n", - " \"validatedResources\": null,\n", " \"validationLevel\": null\n", " },\n", " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"tags\": null,\n", " \"type\": \"Microsoft.Resources/deployments\"\n", "}\n", + "\n", + "\n", + "$ cmd /c C:\\Program Files\\Microsoft SDKs\\Azure\\CLI2\\wbin\\az.cmd deployment group create --resource-group rg-aigw-hosted-custom-framework --name deploy-hosted-custom-framework --template-file C:\\GitHub\\ai-gateway\\AI-Gateway\\labs\\ai-foundry-hosted-agents-custom-framework\\main.bicep --parameters @C:\\GitHub\\ai-gateway\\AI-Gateway\\labs\\ai-foundry-hosted-agents-custom-framework\\main.parameters.generated.json --only-show-errors\n", + "ERROR: {\"status\":\"Failed\",\"error\":{\"code\":\"DeploymentFailed\",\"target\":\"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/deploy-hosted-custom-framework\",\"message\":\"At least one resource deployment operation failed. Please list deployment operations for details. Please see https://aka.ms/arm-deployment-operations for usage details.\",\"details\":[{\"code\":\"RoleAssignmentExists\",\"message\":\"The role assignment already exists. The ID of the existing role assignment is 3ee88ca04a0f46ada7dc792f08d82442.\"},{\"code\":\"RoleAssignmentExists\",\"message\":\"The role assignment already exists. The ID of the existing role assignment is 80356ae269865962a1f930f33d06915b.\"},{\"code\":\"RoleAssignmentExists\",\"message\":\"The role assignment already exists. The ID of the existing role assignment is 625cdc99b9c45912836d1d68a740fbb5.\"}]}}\n", "\n" ] + }, + { + "ename": "RuntimeError", + "evalue": "Command failed: 1", + "output_type": "error", + "traceback": [ + "\u001b[31m---------------------------------------------------------------------------\u001b[39m", + "\u001b[31mRuntimeError\u001b[39m Traceback (most recent call last)", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[9]\u001b[39m\u001b[32m, line 59\u001b[39m\n\u001b[32m 55\u001b[39m ])\n\u001b[32m 56\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m RuntimeError \u001b[38;5;28;01mas\u001b[39;00m ex:\n\u001b[32m 57\u001b[39m print(f'Validation failed, continuing to deployment create step: {ex}')\n\u001b[32m 58\u001b[39m \n\u001b[32m---> \u001b[39m\u001b[32m59\u001b[39m result = az_run([\n\u001b[32m 60\u001b[39m \u001b[33m'deployment'\u001b[39m, \u001b[33m'group'\u001b[39m, \u001b[33m'create'\u001b[39m,\n\u001b[32m 61\u001b[39m \u001b[33m'--resource-group'\u001b[39m, resource_group,\n\u001b[32m 62\u001b[39m \u001b[33m'--name'\u001b[39m, deployment_name,\n", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[9]\u001b[39m\u001b[32m, line 12\u001b[39m, in \u001b[36maz_run\u001b[39m\u001b[34m(args)\u001b[39m\n\u001b[32m 10\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m az_run(args):\n\u001b[32m 11\u001b[39m command = [\u001b[33m'cmd'\u001b[39m, \u001b[33m'/c'\u001b[39m, az_cmd, *args] \u001b[38;5;28;01mif\u001b[39;00m az_cmd.lower().endswith(\u001b[33m'.cmd'\u001b[39m) \u001b[38;5;28;01melse\u001b[39;00m [az_cmd, *args]\n\u001b[32m---> \u001b[39m\u001b[32m12\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m run(command)\n", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[6]\u001b[39m\u001b[32m, line 14\u001b[39m, in \u001b[36mrun\u001b[39m\u001b[34m(cmd)\u001b[39m\n\u001b[32m 10\u001b[39m print(result.stdout)\n\u001b[32m 11\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m result.returncode != \u001b[32m0\u001b[39m:\n\u001b[32m 12\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m result.stderr:\n\u001b[32m 13\u001b[39m print(result.stderr)\n\u001b[32m---> \u001b[39m\u001b[32m14\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m RuntimeError(f'Command failed: {result.returncode}')\n\u001b[32m 15\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m result\n", + "\u001b[31mRuntimeError\u001b[39m: Command failed: 1" + ] } ], "source": [ "# Create resource group and deploy Bicep\n", "# Ensure Azure CLI directory is available to subprocess calls in this kernel\n", + "\n", + "import os\n", + "\n", "az_dir = str(Path(az_cmd).parent)\n", "if az_dir not in os.environ.get('PATH', ''):\n", " os.environ['PATH'] = az_dir + os.pathsep + os.environ.get('PATH', '')\n", diff --git a/labs/ai-foundry-hosted-agents-custom-framework/clean-up-resources.ipynb b/labs/ai-foundry-hosted-agents-custom-framework/clean-up-resources.ipynb index 6fe73c08..5e37406e 100644 --- a/labs/ai-foundry-hosted-agents-custom-framework/clean-up-resources.ipynb +++ b/labs/ai-foundry-hosted-agents-custom-framework/clean-up-resources.ipynb @@ -12,7 +12,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "id": "3ab6bfd0", "metadata": {}, "outputs": [], @@ -50,7 +50,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "id": "5083d437", "metadata": {}, "outputs": [ @@ -59,22 +59,10 @@ "output_type": "stream", "text": [ "\n", - "$ az account set --subscription baba41cf-c01d-4a55-b6c5-ca494b802be5\n" - ] - }, - { - "ename": "FileNotFoundError", - "evalue": "[WinError 2] The system cannot find the file specified", - "output_type": "error", - "traceback": [ - "\u001b[31m---------------------------------------------------------------------------\u001b[39m", - "\u001b[31mFileNotFoundError\u001b[39m Traceback (most recent call last)", - "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[2]\u001b[39m\u001b[32m, line 2\u001b[39m\n\u001b[32m 1\u001b[39m \u001b[38;5;66;03m# Delete lab resources\u001b[39;00m\n\u001b[32m----> \u001b[39m\u001b[32m2\u001b[39m run([\u001b[33m'az'\u001b[39m, \u001b[33m'account'\u001b[39m, \u001b[33m'set'\u001b[39m, \u001b[33m'--subscription'\u001b[39m, subscription_id])\n\u001b[32m 3\u001b[39m run([\u001b[33m'az'\u001b[39m, \u001b[33m'group'\u001b[39m, \u001b[33m'delete'\u001b[39m, \u001b[33m'--name'\u001b[39m, resource_group, \u001b[33m'--yes'\u001b[39m, \u001b[33m'--no-wait'\u001b[39m])\n\u001b[32m 4\u001b[39m print(\u001b[33m'Deletion started. Use az group show to verify completion.'\u001b[39m)\n", - "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[1]\u001b[39m\u001b[32m, line 5\u001b[39m, in \u001b[36mrun\u001b[39m\u001b[34m(cmd)\u001b[39m\n\u001b[32m 3\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m run(cmd):\n\u001b[32m 4\u001b[39m print(\u001b[33m'\\n$ '\u001b[39m + \u001b[33m' '\u001b[39m.join(cmd))\n\u001b[32m----> \u001b[39m\u001b[32m5\u001b[39m result = subprocess.run(cmd, capture_output=\u001b[38;5;28;01mTrue\u001b[39;00m, text=\u001b[38;5;28;01mTrue\u001b[39;00m)\n\u001b[32m 6\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m result.stdout:\n\u001b[32m 7\u001b[39m print(result.stdout)\n\u001b[32m 8\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m result.returncode != \u001b[32m0\u001b[39m:\n", - "\u001b[36mFile \u001b[39m\u001b[32mc:\\Users\\ollisgeorge\\AppData\\Local\\Programs\\Python\\Python312-x64\\Lib\\subprocess.py:548\u001b[39m, in \u001b[36mrun\u001b[39m\u001b[34m(input, capture_output, timeout, check, *popenargs, **kwargs)\u001b[39m\n\u001b[32m 545\u001b[39m kwargs[\u001b[33m'\u001b[39m\u001b[33mstdout\u001b[39m\u001b[33m'\u001b[39m] = PIPE\n\u001b[32m 546\u001b[39m kwargs[\u001b[33m'\u001b[39m\u001b[33mstderr\u001b[39m\u001b[33m'\u001b[39m] = PIPE\n\u001b[32m--> \u001b[39m\u001b[32m548\u001b[39m \u001b[38;5;28;01mwith\u001b[39;00m \u001b[30;43mPopen\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43mpopenargs\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43mkwargs\u001b[39;49m\u001b[30;43m)\u001b[39;49m \u001b[38;5;28;01mas\u001b[39;00m process:\n\u001b[32m 549\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m 550\u001b[39m stdout, stderr = process.communicate(\u001b[38;5;28minput\u001b[39m, timeout=timeout)\n", - "\u001b[36mFile \u001b[39m\u001b[32mc:\\Users\\ollisgeorge\\AppData\\Local\\Programs\\Python\\Python312-x64\\Lib\\subprocess.py:1026\u001b[39m, in \u001b[36mPopen.__init__\u001b[39m\u001b[34m(self, args, bufsize, executable, stdin, stdout, stderr, preexec_fn, close_fds, shell, cwd, env, universal_newlines, startupinfo, creationflags, restore_signals, start_new_session, pass_fds, user, group, extra_groups, encoding, errors, text, umask, pipesize, process_group)\u001b[39m\n\u001b[32m 1022\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m.text_mode:\n\u001b[32m 1023\u001b[39m \u001b[38;5;28mself\u001b[39m.stderr = io.TextIOWrapper(\u001b[38;5;28mself\u001b[39m.stderr,\n\u001b[32m 1024\u001b[39m encoding=encoding, errors=errors)\n\u001b[32m-> \u001b[39m\u001b[32m1026\u001b[39m \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43m_execute_child\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43margs\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mexecutable\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mpreexec_fn\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mclose_fds\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 1027\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mpass_fds\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mcwd\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43menv\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 1028\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mstartupinfo\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mcreationflags\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mshell\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 1029\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mp2cread\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mp2cwrite\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 1030\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mc2pread\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mc2pwrite\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 1031\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43merrread\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43merrwrite\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 1032\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mrestore_signals\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 1033\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mgid\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mgids\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43muid\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mumask\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 1034\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mstart_new_session\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mprocess_group\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 1035\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m:\n\u001b[32m 1036\u001b[39m \u001b[38;5;66;03m# Cleanup if the child failed starting.\u001b[39;00m\n\u001b[32m 1037\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m f \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mfilter\u001b[39m(\u001b[38;5;28;01mNone\u001b[39;00m, (\u001b[38;5;28mself\u001b[39m.stdin, \u001b[38;5;28mself\u001b[39m.stdout, \u001b[38;5;28mself\u001b[39m.stderr)):\n", - "\u001b[36mFile \u001b[39m\u001b[32mc:\\Users\\ollisgeorge\\AppData\\Local\\Programs\\Python\\Python312-x64\\Lib\\subprocess.py:1538\u001b[39m, in \u001b[36mPopen._execute_child\u001b[39m\u001b[34m(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, unused_restore_signals, unused_gid, unused_gids, unused_uid, unused_umask, unused_start_new_session, unused_process_group)\u001b[39m\n\u001b[32m 1536\u001b[39m \u001b[38;5;66;03m# Start the process\u001b[39;00m\n\u001b[32m 1537\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m-> \u001b[39m\u001b[32m1538\u001b[39m hp, ht, pid, tid = \u001b[30;43m_winapi\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mCreateProcess\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43mexecutable\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43margs\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 1539\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43;03m# no special security\u001b[39;49;00m\n\u001b[32m 1540\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43;01mNone\u001b[39;49;00m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43;01mNone\u001b[39;49;00m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 1541\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mint\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43;01mnot\u001b[39;49;00m\u001b[30;43m \u001b[39;49m\u001b[30;43mclose_fds\u001b[39;49m\u001b[30;43m)\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 1542\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mcreationflags\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 1543\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43menv\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 1544\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mcwd\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 1545\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mstartupinfo\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 1546\u001b[39m \u001b[38;5;28;01mfinally\u001b[39;00m:\n\u001b[32m 1547\u001b[39m \u001b[38;5;66;03m# Child is launched. Close the parent's copy of those pipe\u001b[39;00m\n\u001b[32m 1548\u001b[39m \u001b[38;5;66;03m# handles that only the child should have open. You need\u001b[39;00m\n\u001b[32m (...)\u001b[39m\u001b[32m 1551\u001b[39m \u001b[38;5;66;03m# pipe will not close when the child process exits and the\u001b[39;00m\n\u001b[32m 1552\u001b[39m \u001b[38;5;66;03m# ReadFile will hang.\u001b[39;00m\n\u001b[32m 1553\u001b[39m \u001b[38;5;28mself\u001b[39m._close_pipe_fds(p2cread, p2cwrite,\n\u001b[32m 1554\u001b[39m c2pread, c2pwrite,\n\u001b[32m 1555\u001b[39m errread, errwrite)\n", - "\u001b[31mFileNotFoundError\u001b[39m: [WinError 2] The system cannot find the file specified" + "$ C:\\Program Files\\Microsoft SDKs\\Azure\\CLI2\\wbin\\az.CMD account set --subscription baba41cf-c01d-4a55-b6c5-ca494b802be5\n", + "\n", + "$ C:\\Program Files\\Microsoft SDKs\\Azure\\CLI2\\wbin\\az.CMD group delete --name rg-aigw-hosted-custom-framework --yes --no-wait\n", + "Deletion started. Use az group show to verify completion.\n" ] } ], diff --git a/labs/ai-foundry-hosted-agents-custom-framework/main.bicep b/labs/ai-foundry-hosted-agents-custom-framework/main.bicep index a282bc84..c0cf9477 100644 --- a/labs/ai-foundry-hosted-agents-custom-framework/main.bicep +++ b/labs/ai-foundry-hosted-agents-custom-framework/main.bicep @@ -95,6 +95,7 @@ module foundryModule '../../modules/cognitive-services/v3/foundry.bicep' = { // Foundry accounts created by the module, referenced here for RBAC assignments. resource aiFoundryAccounts 'Microsoft.CognitiveServices/accounts@2025-06-01' existing = [for config in aiServicesConfig: { name: '${config.name}-${resourceSuffix}' + dependsOn: [foundryModule] }] // 5. APIM Inference API pointing to Foundry/AI Services @@ -105,7 +106,7 @@ module inferenceAPIModule '../../modules/apim/v3/inference-api.bicep' = { apimLoggerId: apimModule.outputs.loggerId appInsightsId: appInsightsModule.outputs.id appInsightsInstrumentationKey: appInsightsModule.outputs.instrumentationKey - aiServicesConfig: foundryModule.outputs.extendedAIServicesConfig + aiServicesConfig: [foundryModule.outputs.extendedAIServicesConfig[0]] inferenceAPIType: inferenceAPIType inferenceAPIPath: inferenceAPIPath } @@ -127,30 +128,33 @@ resource containerRegistry 'Microsoft.ContainerRegistry/registries@2023-11-01-pr // Assign Foundry User role for all provided users on the model-hosting Foundry resource. resource modelFoundryUserRoleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for principalId in foundryUserObjectIds: { - name: guid(resourceGroup().id, aiFoundryAccounts[0].id, principalId, azureAIUserRoleDefinitionId) + name: guid(resourceGroup().id, aiFoundryAccounts[0].name, principalId, azureAIUserRoleDefinitionId) scope: aiFoundryAccounts[0] properties: { roleDefinitionId: azureAIUserRoleDefinitionId principalId: principalId principalType: 'User' } + skipDuplicateKeyErrors: true }] // Assign Foundry User role for all provided users on the hosted-agent Foundry resource. resource agentFoundryUserRoleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for principalId in foundryUserObjectIds: { - name: guid(resourceGroup().id, aiFoundryAccounts[foundryAgentAiServiceIndex].id, principalId, azureAIUserRoleDefinitionId) + name: guid(resourceGroup().id, aiFoundryAccounts[foundryAgentAiServiceIndex].name, principalId, azureAIUserRoleDefinitionId) scope: aiFoundryAccounts[foundryAgentAiServiceIndex] properties: { roleDefinitionId: azureAIUserRoleDefinitionId principalId: principalId principalType: 'User' } + skipDuplicateKeyErrors: true }] // Repository-level ACR roles (ABAC-enabled roles) var acrRepositoryReaderRoleId = resourceId('Microsoft.Authorization/roleDefinitions', 'b93aa761-3e63-49ed-ac28-beffa264f7ac') var acrRepositoryWriterRoleId = resourceId('Microsoft.Authorization/roleDefinitions', '2a1e307c-b015-4ebd-883e-5b7698a07328') var acrRepositoryCatalogListerRoleId = resourceId('Microsoft.Authorization/roleDefinitions', 'bfdb9389-c9a5-478a-bb2f-ba9ca092c3c7') +var acrPullRoleId = resourceId('Microsoft.Authorization/roleDefinitions', '7f951dda-4ed3-4680-a7ca-43fe172d538d') var foundryAgentAccountName = '${aiServicesConfig[foundryAgentAiServiceIndex].name}-${resourceSuffix}' resource foundryAgentAcrRepositoryReaderRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { @@ -161,6 +165,31 @@ resource foundryAgentAcrRepositoryReaderRoleAssignment 'Microsoft.Authorization/ principalId: foundryModule.outputs.extendedAIServicesConfig[foundryAgentAiServiceIndex].principalId principalType: 'ServicePrincipal' } + skipDuplicateKeyErrors: true +} + +// Assign ACR Repository Reader to the Foundry project identity for the hosted-agent resource. +resource foundryAgentProjectAcrRepositoryReaderRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid(resourceGroup().id, foundryAgentAccountName, 'project', acrRepositoryReaderRoleId) + scope: containerRegistry + properties: { + roleDefinitionId: acrRepositoryReaderRoleId + principalId: foundryModule.outputs.extendedAIServicesConfig[foundryAgentAiServiceIndex].projectPrincipalId + principalType: 'ServicePrincipal' + } + skipDuplicateKeyErrors: true +} + +// Assign AcrPull to the Foundry project identity for the hosted-agent resource. +resource foundryAgentProjectAcrPullRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid(resourceGroup().id, foundryAgentAccountName, 'project', acrPullRoleId) + scope: containerRegistry + properties: { + roleDefinitionId: acrPullRoleId + principalId: foundryModule.outputs.extendedAIServicesConfig[foundryAgentAiServiceIndex].projectPrincipalId + principalType: 'ServicePrincipal' + } + skipDuplicateKeyErrors: true } resource deployerAcrRepositoryWriterRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { @@ -170,6 +199,7 @@ resource deployerAcrRepositoryWriterRoleAssignment 'Microsoft.Authorization/role roleDefinitionId: acrRepositoryWriterRoleId principalId: deployer().objectId } + skipDuplicateKeyErrors: true } resource deployerAcrRepositoryCatalogListerRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { @@ -179,6 +209,7 @@ resource deployerAcrRepositoryCatalogListerRoleAssignment 'Microsoft.Authorizati roleDefinitionId: acrRepositoryCatalogListerRoleId principalId: deployer().objectId } + skipDuplicateKeyErrors: true } // Existing APIM service reference for custom API resources. @@ -217,7 +248,7 @@ resource hostedAgentResponsesOperation 'Microsoft.ApiManagement/service/apis/ope properties: { displayName: 'Create Hosted Agent Response' method: 'POST' - urlTemplate: '/responses' + urlTemplate: '/endpoint/protocols/openai/responses' templateParameters: [] responses: [ { diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/01_hosted_agent_strands_setup.ipynb b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/01_hosted_agent_strands_setup.ipynb index f6daadda..c3ae112f 100644 --- a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/01_hosted_agent_strands_setup.ipynb +++ b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/01_hosted_agent_strands_setup.ipynb @@ -34,7 +34,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 10, "id": "1cc7246e", "metadata": {}, "outputs": [ @@ -42,17 +42,17 @@ "name": "stdout", "output_type": "stream", "text": [ - "ACR_NAME=acrvu4ax6chjqjsk\n", - "ACR_LOGIN_SERVER=acrvu4ax6chjqjsk.azurecr.io\n", + "ACR_NAME=acrxhep4wovroziu\n", + "ACR_LOGIN_SERVER=acrxhep4wovroziu.azurecr.io\n", "IMAGE_NAME=strands-agent\n", "IMAGE_TAG=1.0.0\n", - "IMAGE_URI=acrvu4ax6chjqjsk.azurecr.io/strands-agent:1.0.0\n" + "IMAGE_URI=acrxhep4wovroziu.azurecr.io/strands-agent:1.0.0\n" ] } ], "source": [ "# Set these placeholders\n", - "ACR_NAME = \"acrvu4ax6chjqjsk\"\n", + "ACR_NAME = \"acrxhep4wovroziu\"\n", "IMAGE_NAME = \"strands-agent\"\n", "IMAGE_TAG = \"1.0.0\"\n", "ACR_LOGIN_SERVER = f\"{ACR_NAME}.azurecr.io\"\n", @@ -67,7 +67,26 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 14, + "id": "702db155", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Login Succeeded\n" + ] + } + ], + "source": [ + "# Ensure Docker is running\n", + "!az acr login --name {ACR_NAME}" + ] + }, + { + "cell_type": "code", + "execution_count": 15, "id": "3126aa58", "metadata": {}, "outputs": [ @@ -75,8 +94,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "Running: docker build -t acrvu4ax6chjqjsk.azurecr.io/strands-agent:1.0.0 .\n", - "Running: docker push acrvu4ax6chjqjsk.azurecr.io/strands-agent:1.0.0\n" + "Running: docker build -t acrxhep4wovroziu.azurecr.io/strands-agent:1.0.0 .\n", + "Running: docker push acrxhep4wovroziu.azurecr.io/strands-agent:1.0.0\n" ] }, { @@ -86,63 +105,26 @@ "#0 building with \"desktop-linux\" instance using docker driver\n", "\n", "#1 [internal] load build definition from Dockerfile\n", - "#1 transferring dockerfile: 233B done\n", + "#1 transferring dockerfile: 233B 0.0s done\n", "#1 DONE 0.0s\n", "\n", "#2 [internal] load metadata for docker.io/library/python:3.12-slim\n", - "#2 DONE 1.6s\n", + "#2 DONE 1.1s\n", "\n", "#3 [internal] load .dockerignore\n", - "#3 transferring context: 341B done\n", + "#3 transferring context: 341B 0.0s done\n", "#3 DONE 0.0s\n", "\n", - "#4 [internal] load build context\n", - "#4 transferring context: 68.30kB 0.0s done\n", + "#4 [1/5] FROM docker.io/library/python:3.12-slim@sha256:423ed6ab25b1921a477529254bfeeabf5855151dc2c3141699a1bfc852199fbf\n", + "#4 resolve docker.io/library/python:3.12-slim@sha256:423ed6ab25b1921a477529254bfeeabf5855151dc2c3141699a1bfc852199fbf 0.0s done\n", "#4 DONE 0.0s\n", "\n", - "#5 [1/5] FROM docker.io/library/python:3.12-slim@sha256:423ed6ab25b1921a477529254bfeeabf5855151dc2c3141699a1bfc852199fbf\n", - "#5 resolve docker.io/library/python:3.12-slim@sha256:423ed6ab25b1921a477529254bfeeabf5855151dc2c3141699a1bfc852199fbf 0.0s done\n", - "#5 DONE 0.1s\n", - "\n", - "#5 [1/5] FROM docker.io/library/python:3.12-slim@sha256:423ed6ab25b1921a477529254bfeeabf5855151dc2c3141699a1bfc852199fbf\n", - "#5 sha256:b32430367bf08f32c23778909985ac645d1794f0aeef670aa796a50c8751527d 248B / 248B 0.1s done\n", - "#5 sha256:df79d931cd67092e2b8e48d8f6369922571efe4ee0f9af71636ce36600481492 0B / 12.11MB 0.3s\n", - "#5 sha256:aff2d9f8dc87f4c10bbb7f438f3a325169379776bdfad5c49e4be5acc3c2f192 0B / 1.29MB 0.2s\n", - "#5 sha256:e95a6c7ea7d49b37920899b023ecd0e32796c976c1748491f76cae53ba86d13a 0B / 29.79MB 0.2s\n", - "#5 sha256:df79d931cd67092e2b8e48d8f6369922571efe4ee0f9af71636ce36600481492 3.15MB / 12.11MB 0.5s\n", - "#5 sha256:df79d931cd67092e2b8e48d8f6369922571efe4ee0f9af71636ce36600481492 6.29MB / 12.11MB 0.6s\n", - "#5 sha256:df79d931cd67092e2b8e48d8f6369922571efe4ee0f9af71636ce36600481492 9.44MB / 12.11MB 0.8s\n", - "#5 sha256:aff2d9f8dc87f4c10bbb7f438f3a325169379776bdfad5c49e4be5acc3c2f192 1.29MB / 1.29MB 0.6s done\n", - "#5 sha256:df79d931cd67092e2b8e48d8f6369922571efe4ee0f9af71636ce36600481492 12.11MB / 12.11MB 0.9s done\n", - "#5 sha256:e95a6c7ea7d49b37920899b023ecd0e32796c976c1748491f76cae53ba86d13a 3.15MB / 29.79MB 0.8s\n", - "#5 sha256:e95a6c7ea7d49b37920899b023ecd0e32796c976c1748491f76cae53ba86d13a 9.44MB / 29.79MB 1.1s\n", - "#5 sha256:e95a6c7ea7d49b37920899b023ecd0e32796c976c1748491f76cae53ba86d13a 11.53MB / 29.79MB 1.2s\n", - "#5 sha256:e95a6c7ea7d49b37920899b023ecd0e32796c976c1748491f76cae53ba86d13a 14.68MB / 29.79MB 1.4s\n", - "#5 sha256:e95a6c7ea7d49b37920899b023ecd0e32796c976c1748491f76cae53ba86d13a 17.83MB / 29.79MB 1.5s\n", - "#5 sha256:e95a6c7ea7d49b37920899b023ecd0e32796c976c1748491f76cae53ba86d13a 19.92MB / 29.79MB 1.7s\n", - "#5 sha256:e95a6c7ea7d49b37920899b023ecd0e32796c976c1748491f76cae53ba86d13a 23.07MB / 29.79MB 1.8s\n", - "#5 sha256:e95a6c7ea7d49b37920899b023ecd0e32796c976c1748491f76cae53ba86d13a 27.26MB / 29.79MB 2.0s\n", - "#5 sha256:e95a6c7ea7d49b37920899b023ecd0e32796c976c1748491f76cae53ba86d13a 29.79MB / 29.79MB 2.1s\n", - "#5 sha256:e95a6c7ea7d49b37920899b023ecd0e32796c976c1748491f76cae53ba86d13a 29.79MB / 29.79MB 2.1s done\n", - "#5 extracting sha256:e95a6c7ea7d49b37920899b023ecd0e32796c976c1748491f76cae53ba86d13a\n", - "#5 extracting sha256:e95a6c7ea7d49b37920899b023ecd0e32796c976c1748491f76cae53ba86d13a 0.8s done\n", - "#5 DONE 3.0s\n", - "\n", - "#5 [1/5] FROM docker.io/library/python:3.12-slim@sha256:423ed6ab25b1921a477529254bfeeabf5855151dc2c3141699a1bfc852199fbf\n", - "#5 extracting sha256:aff2d9f8dc87f4c10bbb7f438f3a325169379776bdfad5c49e4be5acc3c2f192 0.1s done\n", - "#5 DONE 3.1s\n", - "\n", - "#5 [1/5] FROM docker.io/library/python:3.12-slim@sha256:423ed6ab25b1921a477529254bfeeabf5855151dc2c3141699a1bfc852199fbf\n", - "#5 extracting sha256:df79d931cd67092e2b8e48d8f6369922571efe4ee0f9af71636ce36600481492\n", - "#5 extracting sha256:df79d931cd67092e2b8e48d8f6369922571efe4ee0f9af71636ce36600481492 0.5s done\n", - "#5 DONE 3.6s\n", - "\n", - "#5 [1/5] FROM docker.io/library/python:3.12-slim@sha256:423ed6ab25b1921a477529254bfeeabf5855151dc2c3141699a1bfc852199fbf\n", - "#5 extracting sha256:b32430367bf08f32c23778909985ac645d1794f0aeef670aa796a50c8751527d 0.0s done\n", - "#5 DONE 3.6s\n", + "#5 [internal] load build context\n", + "#5 transferring context: 79.62kB 0.0s done\n", + "#5 DONE 0.0s\n", "\n", "#6 [2/5] WORKDIR /app\n", - "#6 DONE 0.2s\n", + "#6 CACHED\n", "\n", "#7 [3/5] COPY . user_agent/\n", "#7 DONE 0.0s\n", @@ -151,437 +133,438 @@ "#8 DONE 0.0s\n", "\n", "#9 [5/5] RUN if [ -f requirements.txt ]; then pip install -r requirements.txt; fi\n", - "#9 15.53 Collecting azure-ai-agentserver-responses==1.0.0b8 (from -r requirements.txt (line 1))\n", - "#9 15.81 Downloading azure_ai_agentserver_responses-1.0.0b8-py3-none-any.whl.metadata (13 kB)\n", - "#9 16.09 Collecting strands-agents==1.45.0 (from strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 16.14 Downloading strands_agents-1.45.0-py3-none-any.whl.metadata (19 kB)\n", - "#9 16.69 Collecting python-dotenv (from -r requirements.txt (line 3))\n", - "#9 16.73 Downloading python_dotenv-1.2.2-py3-none-any.whl.metadata (27 kB)\n", - "#9 16.89 Collecting azure-ai-projects==2.3.0 (from -r requirements.txt (line 4))\n", - "#9 16.96 Downloading azure_ai_projects-2.3.0-py3-none-any.whl.metadata (64 kB)\n", - "#9 17.18 Collecting azure-ai-agentserver-core>=2.0.0b7 (from azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 17.24 Downloading azure_ai_agentserver_core-2.0.0b7-py3-none-any.whl.metadata (7.8 kB)\n", - "#9 17.52 Collecting azure-core>=1.30.0 (from azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 17.56 Downloading azure_core-1.41.0-py3-none-any.whl.metadata (49 kB)\n", - "#9 17.71 Collecting isodate>=0.6.1 (from azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 17.77 Downloading isodate-0.7.2-py3-none-any.whl.metadata (11 kB)\n", - "#9 23.23 Collecting aiohttp<4.0.0,>=3.10.0 (from azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 23.27 Downloading aiohttp-3.14.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (8.3 kB)\n", - "#9 28.83 Collecting boto3<2.0.0,>=1.26.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 28.87 Downloading boto3-1.43.42-py3-none-any.whl.metadata (6.6 kB)\n", - "#9 35.12 Collecting botocore<2.0.0,>=1.29.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 35.17 Downloading botocore-1.43.42-py3-none-any.whl.metadata (5.6 kB)\n", - "#9 35.39 Collecting docstring-parser<1.0,>=0.15 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 35.44 Downloading docstring_parser-0.18.0-py3-none-any.whl.metadata (3.5 kB)\n", - "#9 35.77 Collecting jsonschema<5.0.0,>=4.0.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 35.83 Downloading jsonschema-4.26.0-py3-none-any.whl.metadata (7.6 kB)\n", - "#9 36.18 Collecting mcp<2.0.0,>=1.23.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 36.22 Downloading mcp-1.28.1-py3-none-any.whl.metadata (9.4 kB)\n", - "#9 36.55 Collecting opentelemetry-api<2.0.0,>=1.30.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 36.58 Downloading opentelemetry_api-1.43.0-py3-none-any.whl.metadata (1.4 kB)\n", - "#9 36.87 Collecting opentelemetry-instrumentation-threading<1.00b0,>=0.51b0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 36.91 Downloading opentelemetry_instrumentation_threading-0.64b0-py3-none-any.whl.metadata (2.1 kB)\n", - "#9 37.16 Collecting opentelemetry-sdk<2.0.0,>=1.30.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 37.20 Downloading opentelemetry_sdk-1.43.0-py3-none-any.whl.metadata (1.7 kB)\n", - "#9 38.55 Collecting pydantic<3.0.0,>=2.4.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 38.59 Downloading pydantic-2.13.4-py3-none-any.whl.metadata (109 kB)\n", - "#9 39.12 Collecting pyyaml<7.0.0,>=6.0.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 39.17 Downloading pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (2.4 kB)\n", - "#9 39.43 Collecting typing-extensions<5.0.0,>=4.13.2 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 39.47 Downloading typing_extensions-4.16.0-py3-none-any.whl.metadata (3.3 kB)\n", - "#9 40.04 Collecting watchdog<7.0.0,>=6.0.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 40.08 Downloading watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl.metadata (44 kB)\n", - "#9 40.50 Collecting azure-identity>=1.15.0 (from azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", - "#9 40.54 Downloading azure_identity-1.25.3-py3-none-any.whl.metadata (91 kB)\n", - "#9 41.42 Collecting openai>=2.8.0 (from azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", - "#9 41.46 Downloading openai-2.44.0-py3-none-any.whl.metadata (34 kB)\n", - "#9 41.86 Collecting azure-storage-blob>=12.15.0 (from azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", - "#9 41.90 Downloading azure_storage_blob-12.30.0-py3-none-any.whl.metadata (26 kB)\n", - "#9 42.09 Collecting aws-bedrock-token-generator<2.0.0,>=1.1.0 (from strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 42.13 Downloading aws_bedrock_token_generator-1.1.0-py3-none-any.whl.metadata (7.5 kB)\n", - "#9 42.77 Collecting aiohappyeyeballs>=2.5.0 (from aiohttp<4.0.0,>=3.10.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 42.82 Downloading aiohappyeyeballs-2.7.1-py3-none-any.whl.metadata (5.9 kB)\n", - "#9 43.02 Collecting aiosignal>=1.4.0 (from aiohttp<4.0.0,>=3.10.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 43.06 Downloading aiosignal-1.4.0-py3-none-any.whl.metadata (3.7 kB)\n", - "#9 43.27 Collecting attrs>=17.3.0 (from aiohttp<4.0.0,>=3.10.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 43.32 Downloading attrs-26.1.0-py3-none-any.whl.metadata (8.8 kB)\n", - "#9 44.09 Collecting frozenlist>=1.1.1 (from aiohttp<4.0.0,>=3.10.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 44.14 Downloading frozenlist-1.8.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl.metadata (20 kB)\n", - "#9 46.71 Collecting multidict<7.0,>=4.5 (from aiohttp<4.0.0,>=3.10.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 46.76 Downloading multidict-6.7.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (5.3 kB)\n", - "#9 47.43 Collecting propcache>=0.2.0 (from aiohttp<4.0.0,>=3.10.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 47.48 Downloading propcache-0.5.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (16 kB)\n", - "#9 50.47 Collecting yarl<2.0,>=1.17.0 (from aiohttp<4.0.0,>=3.10.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 50.52 Downloading yarl-1.24.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (94 kB)\n", - "#9 54.05 Collecting starlette>=0.45.0 (from azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 54.09 Downloading starlette-1.3.1-py3-none-any.whl.metadata (6.4 kB)\n", - "#9 54.37 Collecting hypercorn>=0.17.0 (from azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 54.43 Downloading hypercorn-0.18.0-py3-none-any.whl.metadata (5.1 kB)\n", - "#9 54.92 Collecting microsoft-opentelemetry>=1.0.0 (from azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 54.99 Downloading microsoft_opentelemetry-1.3.5-py3-none-any.whl.metadata (23 kB)\n", - "#9 55.48 Collecting requests>=2.21.0 (from azure-core>=1.30.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 55.54 Downloading requests-2.34.2-py3-none-any.whl.metadata (4.8 kB)\n", - "#9 58.05 Collecting cryptography>=2.5 (from azure-identity>=1.15.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", - "#9 58.09 Downloading cryptography-49.0.0-cp311-abi3-manylinux_2_34_x86_64.whl.metadata (4.3 kB)\n", - "#9 58.37 Collecting msal>=1.35.1 (from azure-identity>=1.15.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", - "#9 58.41 Downloading msal-1.37.0-py3-none-any.whl.metadata (11 kB)\n", - "#9 58.59 Collecting msal-extensions>=1.2.0 (from azure-identity>=1.15.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", - "#9 58.63 Downloading msal_extensions-1.3.1-py3-none-any.whl.metadata (7.8 kB)\n", - "#9 62.15 Collecting jmespath<2.0.0,>=0.7.1 (from boto3<2.0.0,>=1.26.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 62.20 Downloading jmespath-1.1.0-py3-none-any.whl.metadata (7.6 kB)\n", - "#9 62.47 Collecting s3transfer<0.20.0,>=0.19.0 (from boto3<2.0.0,>=1.26.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 62.51 Downloading s3transfer-0.19.0-py3-none-any.whl.metadata (1.7 kB)\n", - "#9 62.83 Collecting python-dateutil<3.0.0,>=2.1 (from botocore<2.0.0,>=1.29.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 62.86 Downloading python_dateutil-2.9.0.post0-py2.py3-none-any.whl.metadata (8.4 kB)\n", - "#9 63.30 Collecting urllib3!=2.2.0,<3,>=1.25.4 (from botocore<2.0.0,>=1.29.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 63.34 Downloading urllib3-2.7.0-py3-none-any.whl.metadata (6.9 kB)\n", - "#9 63.60 Collecting jsonschema-specifications>=2023.03.6 (from jsonschema<5.0.0,>=4.0.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 63.64 Downloading jsonschema_specifications-2025.9.1-py3-none-any.whl.metadata (2.9 kB)\n", - "#9 63.95 Collecting referencing>=0.28.4 (from jsonschema<5.0.0,>=4.0.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 64.00 Downloading referencing-0.37.0-py3-none-any.whl.metadata (2.8 kB)\n", - "#9 66.98 Collecting rpds-py>=0.25.0 (from jsonschema<5.0.0,>=4.0.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 67.03 Downloading rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (4.1 kB)\n", - "#9 67.40 Collecting anyio>=4.5 (from mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 67.44 Downloading anyio-4.14.1-py3-none-any.whl.metadata (4.6 kB)\n", - "#9 67.58 Collecting httpx-sse>=0.4 (from mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 67.62 Downloading httpx_sse-0.4.3-py3-none-any.whl.metadata (9.7 kB)\n", - "#9 67.88 Collecting httpx<1.0.0,>=0.27.1 (from mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 67.93 Downloading httpx-0.28.1-py3-none-any.whl.metadata (7.1 kB)\n", - "#9 68.50 Collecting pydantic-settings>=2.5.2 (from mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 68.56 Downloading pydantic_settings-2.14.2-py3-none-any.whl.metadata (3.4 kB)\n", - "#9 69.12 Collecting pyjwt>=2.10.1 (from pyjwt[crypto]>=2.10.1->mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 69.15 Downloading pyjwt-2.13.0-py3-none-any.whl.metadata (3.4 kB)\n", - "#9 69.36 Collecting python-multipart>=0.0.9 (from mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 69.40 Downloading python_multipart-0.0.32-py3-none-any.whl.metadata (2.1 kB)\n", - "#9 69.71 Collecting sse-starlette>=1.6.1 (from mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 69.77 Downloading sse_starlette-3.4.5-py3-none-any.whl.metadata (15 kB)\n", - "#9 70.27 Collecting typing-inspection>=0.4.1 (from mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 70.32 Downloading typing_inspection-0.4.2-py3-none-any.whl.metadata (2.6 kB)\n", - "#9 70.72 Collecting uvicorn>=0.31.1 (from mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 70.75 Downloading uvicorn-0.51.0-py3-none-any.whl.metadata (6.6 kB)\n", - "#9 70.99 Collecting distro<2,>=1.7.0 (from openai>=2.8.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", - "#9 71.02 Downloading distro-1.9.0-py3-none-any.whl.metadata (6.8 kB)\n", - "#9 72.04 Collecting jiter<1,>=0.10.0 (from openai>=2.8.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", - "#9 72.10 Downloading jiter-0.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (5.2 kB)\n", - "#9 72.52 Collecting sniffio (from openai>=2.8.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", - "#9 72.58 Downloading sniffio-1.3.1-py3-none-any.whl.metadata (3.9 kB)\n", - "#9 73.01 Collecting tqdm>4 (from openai>=2.8.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", - "#9 73.05 Downloading tqdm-4.68.4-py3-none-any.whl.metadata (57 kB)\n", - "#9 73.90 Collecting opentelemetry-instrumentation==0.64b0 (from opentelemetry-instrumentation-threading<1.00b0,>=0.51b0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 73.95 Downloading opentelemetry_instrumentation-0.64b0-py3-none-any.whl.metadata (7.2 kB)\n", - "#9 76.53 Collecting wrapt<3.0.0,>=1.0.0 (from opentelemetry-instrumentation-threading<1.00b0,>=0.51b0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 76.59 Downloading wrapt-2.2.2-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl.metadata (7.4 kB)\n", - "#9 77.22 Collecting opentelemetry-semantic-conventions==0.64b0 (from opentelemetry-instrumentation==0.64b0->opentelemetry-instrumentation-threading<1.00b0,>=0.51b0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 77.27 Downloading opentelemetry_semantic_conventions-0.64b0-py3-none-any.whl.metadata (2.4 kB)\n", - "#9 77.49 Collecting packaging>=18.0 (from opentelemetry-instrumentation==0.64b0->opentelemetry-instrumentation-threading<1.00b0,>=0.51b0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 77.55 Downloading packaging-26.2-py3-none-any.whl.metadata (3.5 kB)\n", - "#9 77.90 Collecting annotated-types>=0.6.0 (from pydantic<3.0.0,>=2.4.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 77.98 Downloading annotated_types-0.7.0-py3-none-any.whl.metadata (15 kB)\n", - "#9 85.45 Collecting pydantic-core==2.46.4 (from pydantic<3.0.0,>=2.4.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 85.49 Downloading pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (6.6 kB)\n", - "#9 86.12 Collecting idna>=2.8 (from anyio>=4.5->mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 86.16 Downloading idna-3.18-py3-none-any.whl.metadata (6.1 kB)\n", - "#9 87.35 Collecting cffi>=2.0.0 (from cryptography>=2.5->azure-identity>=1.15.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", - "#9 87.41 Downloading cffi-2.1.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.metadata (2.5 kB)\n", - "#9 87.72 Collecting certifi (from httpx<1.0.0,>=0.27.1->mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 87.78 Downloading certifi-2026.6.17-py3-none-any.whl.metadata (2.5 kB)\n", - "#9 88.13 Collecting httpcore==1.* (from httpx<1.0.0,>=0.27.1->mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 88.17 Downloading httpcore-1.0.9-py3-none-any.whl.metadata (21 kB)\n", - "#9 88.39 Collecting h11>=0.16 (from httpcore==1.*->httpx<1.0.0,>=0.27.1->mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 88.44 Downloading h11-0.16.0-py3-none-any.whl.metadata (8.3 kB)\n", - "#9 88.70 Collecting h2>=4.3.0 (from hypercorn>=0.17.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 88.73 Downloading h2-4.3.0-py3-none-any.whl.metadata (5.1 kB)\n", - "#9 88.84 Collecting priority (from hypercorn>=0.17.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 88.89 Downloading priority-2.0.0-py3-none-any.whl.metadata (6.6 kB)\n", - "#9 89.00 Collecting wsproto>=0.14.0 (from hypercorn>=0.17.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 89.03 Downloading wsproto-1.3.2-py3-none-any.whl.metadata (5.2 kB)\n", - "#9 89.53 Collecting azure-core-tracing-opentelemetry~=1.0.0b11 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 89.56 Downloading azure_core_tracing_opentelemetry-1.0.0b13-py3-none-any.whl.metadata (11 kB)\n", - "#9 89.77 Collecting azure-monitor-opentelemetry-exporter~=1.0.0b54 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 89.85 Downloading azure_monitor_opentelemetry_exporter-1.0.0b55-py2.py3-none-any.whl.metadata (33 kB)\n", - "#9 90.33 Collecting opentelemetry-exporter-otlp-proto-http~=1.43.0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 90.39 Downloading opentelemetry_exporter_otlp_proto_http-1.43.0-py3-none-any.whl.metadata (2.4 kB)\n", - "#9 90.87 Collecting opentelemetry-instrumentation-django<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 90.92 Downloading opentelemetry_instrumentation_django-0.64b0-py3-none-any.whl.metadata (2.3 kB)\n", - "#9 91.14 Collecting opentelemetry-instrumentation-fastapi<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 91.21 Downloading opentelemetry_instrumentation_fastapi-0.64b0-py3-none-any.whl.metadata (2.2 kB)\n", - "#9 91.55 Collecting opentelemetry-instrumentation-flask<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 91.62 Downloading opentelemetry_instrumentation_flask-0.64b0-py3-none-any.whl.metadata (2.2 kB)\n", - "#9 91.88 Collecting opentelemetry-instrumentation-httpx<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 91.95 Downloading opentelemetry_instrumentation_httpx-0.64b0-py3-none-any.whl.metadata (7.3 kB)\n", - "#9 92.23 Collecting opentelemetry-instrumentation-psycopg2<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 92.30 Downloading opentelemetry_instrumentation_psycopg2-0.64b0-py3-none-any.whl.metadata (2.1 kB)\n", - "#9 92.61 Collecting opentelemetry-instrumentation-requests<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 92.66 Downloading opentelemetry_instrumentation_requests-0.64b0-py3-none-any.whl.metadata (2.6 kB)\n", - "#9 92.92 Collecting opentelemetry-instrumentation-urllib<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 92.96 Downloading opentelemetry_instrumentation_urllib-0.64b0-py3-none-any.whl.metadata (3.4 kB)\n", - "#9 93.26 Collecting opentelemetry-instrumentation-urllib3<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 93.33 Downloading opentelemetry_instrumentation_urllib3-0.64b0-py3-none-any.whl.metadata (4.2 kB)\n", - "#9 93.59 Collecting opentelemetry-instrumentation-logging<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 93.67 Downloading opentelemetry_instrumentation_logging-0.64b0-py3-none-any.whl.metadata (1.9 kB)\n", - "#9 93.78 Collecting opentelemetry-instrumentation-openai-agents-v2==0.1.0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 93.83 Downloading opentelemetry_instrumentation_openai_agents_v2-0.1.0-py3-none-any.whl.metadata (1.3 kB)\n", - "#9 93.97 Collecting opentelemetry-instrumentation-openai-v2==2.3b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 94.01 Downloading opentelemetry_instrumentation_openai_v2-2.3b0-py3-none-any.whl.metadata (5.2 kB)\n", - "#9 94.14 Collecting opentelemetry-resource-detector-azure<1.0.0,>=0.1.5 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 94.18 Downloading opentelemetry_resource_detector_azure-0.1.5-py3-none-any.whl.metadata (5.3 kB)\n", - "#9 94.33 Collecting wrapt<3.0.0,>=1.0.0 (from opentelemetry-instrumentation-threading<1.00b0,>=0.51b0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 94.39 Downloading wrapt-1.17.3-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl.metadata (6.4 kB)\n", - "#9 94.51 Collecting opentelemetry-util-genai==0.3b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 94.55 Downloading opentelemetry_util_genai-0.3b0-py3-none-any.whl.metadata (4.6 kB)\n", - "#9 97.72 Collecting six>=1.5 (from python-dateutil<3.0.0,>=2.1->botocore<2.0.0,>=1.29.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 97.76 Downloading six-1.17.0-py2.py3-none-any.whl.metadata (1.7 kB)\n", - "#9 99.37 Collecting charset_normalizer<4,>=2 (from requests>=2.21.0->azure-core>=1.30.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 99.42 Downloading charset_normalizer-3.4.9-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (41 kB)\n", - "#9 103.7 Collecting click>=7.0 (from uvicorn>=0.31.1->mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 103.8 Downloading click-8.4.2-py3-none-any.whl.metadata (2.6 kB)\n", - "#9 104.8 Collecting msrest>=0.6.10 (from azure-monitor-opentelemetry-exporter~=1.0.0b54->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 104.8 Downloading msrest-0.7.1-py3-none-any.whl.metadata (21 kB)\n", - "#9 105.7 Collecting psutil<8,>=5.9 (from azure-monitor-opentelemetry-exporter~=1.0.0b54->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 105.8 Downloading psutil-7.2.2-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl.metadata (22 kB)\n", - "#9 106.1 Collecting pycparser (from cffi>=2.0.0->cryptography>=2.5->azure-identity>=1.15.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", - "#9 106.1 Downloading pycparser-3.0-py3-none-any.whl.metadata (8.2 kB)\n", - "#9 106.5 Collecting hyperframe<7,>=6.1 (from h2>=4.3.0->hypercorn>=0.17.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 106.5 Downloading hyperframe-6.1.0-py3-none-any.whl.metadata (4.3 kB)\n", - "#9 106.7 Collecting hpack<5,>=4.1 (from h2>=4.3.0->hypercorn>=0.17.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 106.7 Downloading hpack-4.2.0-py3-none-any.whl.metadata (3.3 kB)\n", - "#9 107.2 Collecting googleapis-common-protos~=1.52 (from opentelemetry-exporter-otlp-proto-http~=1.43.0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 107.2 Downloading googleapis_common_protos-1.75.0-py3-none-any.whl.metadata (8.6 kB)\n", - "#9 107.5 Collecting opentelemetry-exporter-otlp-proto-common==1.43.0 (from opentelemetry-exporter-otlp-proto-http~=1.43.0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 107.5 Downloading opentelemetry_exporter_otlp_proto_common-1.43.0-py3-none-any.whl.metadata (1.8 kB)\n", - "#9 107.8 Collecting opentelemetry-proto==1.43.0 (from opentelemetry-exporter-otlp-proto-http~=1.43.0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 107.8 Downloading opentelemetry_proto-1.43.0-py3-none-any.whl.metadata (2.3 kB)\n", - "#9 109.9 Collecting protobuf<8.0,>=5.0 (from opentelemetry-proto==1.43.0->opentelemetry-exporter-otlp-proto-http~=1.43.0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 110.0 Downloading protobuf-7.35.1-cp310-abi3-manylinux2014_x86_64.whl.metadata (595 bytes)\n", - "#9 110.4 Collecting opentelemetry-instrumentation-wsgi==0.64b0 (from opentelemetry-instrumentation-django<0.65b0,>=0.64b0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 110.5 Downloading opentelemetry_instrumentation_wsgi-0.64b0-py3-none-any.whl.metadata (2.1 kB)\n", - "#9 110.8 Collecting opentelemetry-util-http==0.64b0 (from opentelemetry-instrumentation-django<0.65b0,>=0.64b0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 110.8 Downloading opentelemetry_util_http-0.64b0-py3-none-any.whl.metadata (2.6 kB)\n", - "#9 111.2 Collecting opentelemetry-instrumentation-asgi==0.64b0 (from opentelemetry-instrumentation-fastapi<0.65b0,>=0.64b0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 111.3 Downloading opentelemetry_instrumentation_asgi-0.64b0-py3-none-any.whl.metadata (2.0 kB)\n", - "#9 111.7 Collecting asgiref~=3.0 (from opentelemetry-instrumentation-asgi==0.64b0->opentelemetry-instrumentation-fastapi<0.65b0,>=0.64b0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 111.8 Downloading asgiref-3.11.1-py3-none-any.whl.metadata (9.3 kB)\n", - "#9 112.3 Collecting opentelemetry-instrumentation-dbapi==0.64b0 (from opentelemetry-instrumentation-psycopg2<0.65b0,>=0.64b0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 112.4 Downloading opentelemetry_instrumentation_dbapi-0.64b0-py3-none-any.whl.metadata (2.0 kB)\n", - "#9 113.8 Collecting requests-oauthlib>=0.5.0 (from msrest>=0.6.10->azure-monitor-opentelemetry-exporter~=1.0.0b54->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 113.9 Downloading requests_oauthlib-2.0.0-py2.py3-none-any.whl.metadata (11 kB)\n", - "#9 114.6 Collecting oauthlib>=3.0.0 (from requests-oauthlib>=0.5.0->msrest>=0.6.10->azure-monitor-opentelemetry-exporter~=1.0.0b54->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 114.6 Downloading oauthlib-3.3.1-py3-none-any.whl.metadata (7.9 kB)\n", - "#9 114.9 Downloading azure_ai_agentserver_responses-1.0.0b8-py3-none-any.whl (269 kB)\n", - "#9 115.0 Downloading strands_agents-1.45.0-py3-none-any.whl (579 kB)\n", - "#9 115.0 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 579.3/579.3 kB 12.0 MB/s eta 0:00:00\n", - "#9 115.1 Downloading azure_ai_projects-2.3.0-py3-none-any.whl (349 kB)\n", - "#9 115.2 Downloading python_dotenv-1.2.2-py3-none-any.whl (22 kB)\n", - "#9 115.3 Downloading aiohttp-3.14.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (1.8 MB)\n", - "#9 115.4 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.8/1.8 MB 16.4 MB/s eta 0:00:00\n", - "#9 115.5 Downloading aws_bedrock_token_generator-1.1.0-py3-none-any.whl (10 kB)\n", - "#9 115.5 Downloading azure_ai_agentserver_core-2.0.0b7-py3-none-any.whl (35 kB)\n", - "#9 115.6 Downloading azure_core-1.41.0-py3-none-any.whl (220 kB)\n", - "#9 115.7 Downloading azure_identity-1.25.3-py3-none-any.whl (192 kB)\n", - "#9 115.8 Downloading azure_storage_blob-12.30.0-py3-none-any.whl (435 kB)\n", - "#9 115.9 Downloading boto3-1.43.42-py3-none-any.whl (140 kB)\n", - "#9 116.0 Downloading botocore-1.43.42-py3-none-any.whl (15.4 MB)\n", - "#9 117.0 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 15.4/15.4 MB 15.7 MB/s eta 0:00:00\n", - "#9 117.0 Downloading docstring_parser-0.18.0-py3-none-any.whl (22 kB)\n", - "#9 117.1 Downloading isodate-0.7.2-py3-none-any.whl (22 kB)\n", - "#9 117.2 Downloading jsonschema-4.26.0-py3-none-any.whl (90 kB)\n", - "#9 117.4 Downloading mcp-1.28.1-py3-none-any.whl (222 kB)\n", - "#9 117.5 Downloading openai-2.44.0-py3-none-any.whl (1.4 MB)\n", - "#9 117.6 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.4/1.4 MB 13.4 MB/s eta 0:00:00\n", - "#9 117.6 Downloading opentelemetry_api-1.43.0-py3-none-any.whl (61 kB)\n", - "#9 117.7 Downloading opentelemetry_instrumentation_threading-0.64b0-py3-none-any.whl (8.5 kB)\n", - "#9 117.8 Downloading opentelemetry_instrumentation-0.64b0-py3-none-any.whl (35 kB)\n", - "#9 117.9 Downloading opentelemetry_semantic_conventions-0.64b0-py3-none-any.whl (203 kB)\n", - "#9 117.9 Downloading opentelemetry_sdk-1.43.0-py3-none-any.whl (178 kB)\n", - "#9 118.0 Downloading pydantic-2.13.4-py3-none-any.whl (472 kB)\n", - "#9 118.2 Downloading pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.1 MB)\n", - "#9 118.3 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2.1/2.1 MB 20.4 MB/s eta 0:00:00\n", - "#9 118.3 Downloading pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (807 kB)\n", - "#9 118.4 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 807.9/807.9 kB 12.8 MB/s eta 0:00:00\n", - "#9 118.5 Downloading typing_extensions-4.16.0-py3-none-any.whl (45 kB)\n", - "#9 118.6 Downloading watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl (79 kB)\n", - "#9 118.7 Downloading aiohappyeyeballs-2.7.1-py3-none-any.whl (15 kB)\n", - "#9 118.8 Downloading aiosignal-1.4.0-py3-none-any.whl (7.5 kB)\n", - "#9 118.9 Downloading annotated_types-0.7.0-py3-none-any.whl (13 kB)\n", - "#9 119.0 Downloading anyio-4.14.1-py3-none-any.whl (124 kB)\n", - "#9 119.1 Downloading attrs-26.1.0-py3-none-any.whl (67 kB)\n", - "#9 119.1 Downloading cryptography-49.0.0-cp311-abi3-manylinux_2_34_x86_64.whl (4.7 MB)\n", - "#9 119.4 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 4.7/4.7 MB 15.2 MB/s eta 0:00:00\n", - "#9 119.5 Downloading distro-1.9.0-py3-none-any.whl (20 kB)\n", - "#9 119.6 Downloading frozenlist-1.8.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl (242 kB)\n", - "#9 119.7 Downloading httpx-0.28.1-py3-none-any.whl (73 kB)\n", - "#9 119.7 Downloading httpcore-1.0.9-py3-none-any.whl (78 kB)\n", - "#9 119.8 Downloading httpx_sse-0.4.3-py3-none-any.whl (9.0 kB)\n", - "#9 119.9 Downloading hypercorn-0.18.0-py3-none-any.whl (61 kB)\n", - "#9 119.9 Downloading jiter-0.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (343 kB)\n", - "#9 120.1 Downloading jmespath-1.1.0-py3-none-any.whl (20 kB)\n", - "#9 120.1 Downloading jsonschema_specifications-2025.9.1-py3-none-any.whl (18 kB)\n", - "#9 120.2 Downloading microsoft_opentelemetry-1.3.5-py3-none-any.whl (208 kB)\n", - "#9 120.3 Downloading opentelemetry_instrumentation_openai_agents_v2-0.1.0-py3-none-any.whl (25 kB)\n", - "#9 120.4 Downloading opentelemetry_instrumentation_openai_v2-2.3b0-py3-none-any.whl (18 kB)\n", - "#9 120.5 Downloading opentelemetry_util_genai-0.3b0-py3-none-any.whl (28 kB)\n", - "#9 120.6 Downloading msal-1.37.0-py3-none-any.whl (123 kB)\n", - "#9 120.6 Downloading msal_extensions-1.3.1-py3-none-any.whl (20 kB)\n", - "#9 120.7 Downloading multidict-6.7.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (256 kB)\n", - "#9 120.8 Downloading propcache-0.5.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (61 kB)\n", - "#9 120.9 Downloading pydantic_settings-2.14.2-py3-none-any.whl (61 kB)\n", - "#9 120.9 Downloading pyjwt-2.13.0-py3-none-any.whl (31 kB)\n", - "#9 121.0 Downloading python_dateutil-2.9.0.post0-py2.py3-none-any.whl (229 kB)\n", - "#9 121.1 Downloading python_multipart-0.0.32-py3-none-any.whl (30 kB)\n", - "#9 121.2 Downloading referencing-0.37.0-py3-none-any.whl (26 kB)\n", - "#9 121.3 Downloading requests-2.34.2-py3-none-any.whl (73 kB)\n", - "#9 121.3 Downloading rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (366 kB)\n", - "#9 121.4 Downloading s3transfer-0.19.0-py3-none-any.whl (90 kB)\n", - "#9 121.5 Downloading sse_starlette-3.4.5-py3-none-any.whl (16 kB)\n", - "#9 121.6 Downloading starlette-1.3.1-py3-none-any.whl (73 kB)\n", - "#9 121.7 Downloading tqdm-4.68.4-py3-none-any.whl (676 kB)\n", - "#9 121.8 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 676.6/676.6 kB 13.2 MB/s eta 0:00:00\n", - "#9 121.8 Downloading typing_inspection-0.4.2-py3-none-any.whl (14 kB)\n", - "#9 121.9 Downloading urllib3-2.7.0-py3-none-any.whl (131 kB)\n", - "#9 122.0 Downloading uvicorn-0.51.0-py3-none-any.whl (73 kB)\n", - "#9 122.1 Downloading wrapt-1.17.3-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl (88 kB)\n", - "#9 122.2 Downloading yarl-1.24.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (105 kB)\n", - "#9 122.2 Downloading sniffio-1.3.1-py3-none-any.whl (10 kB)\n", - "#9 122.3 Downloading azure_core_tracing_opentelemetry-1.0.0b13-py3-none-any.whl (12 kB)\n", - "#9 122.3 Downloading azure_monitor_opentelemetry_exporter-1.0.0b55-py2.py3-none-any.whl (251 kB)\n", - "#9 122.4 Downloading certifi-2026.6.17-py3-none-any.whl (133 kB)\n", - "#9 122.5 Downloading cffi-2.1.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (221 kB)\n", - "#9 122.6 Downloading charset_normalizer-3.4.9-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (224 kB)\n", - "#9 122.7 Downloading click-8.4.2-py3-none-any.whl (119 kB)\n", - "#9 122.8 Downloading h11-0.16.0-py3-none-any.whl (37 kB)\n", - "#9 122.9 Downloading h2-4.3.0-py3-none-any.whl (61 kB)\n", - "#9 123.0 Downloading idna-3.18-py3-none-any.whl (65 kB)\n", - "#9 123.0 Downloading opentelemetry_exporter_otlp_proto_http-1.43.0-py3-none-any.whl (21 kB)\n", - "#9 123.1 Downloading opentelemetry_exporter_otlp_proto_common-1.43.0-py3-none-any.whl (17 kB)\n", - "#9 123.2 Downloading opentelemetry_proto-1.43.0-py3-none-any.whl (72 kB)\n", - "#9 123.2 Downloading opentelemetry_instrumentation_django-0.64b0-py3-none-any.whl (18 kB)\n", - "#9 123.3 Downloading opentelemetry_instrumentation_wsgi-0.64b0-py3-none-any.whl (13 kB)\n", - "#9 123.4 Downloading opentelemetry_util_http-0.64b0-py3-none-any.whl (8.2 kB)\n", - "#9 123.5 Downloading opentelemetry_instrumentation_fastapi-0.64b0-py3-none-any.whl (13 kB)\n", - "#9 123.6 Downloading opentelemetry_instrumentation_asgi-0.64b0-py3-none-any.whl (15 kB)\n", - "#9 123.7 Downloading opentelemetry_instrumentation_flask-0.64b0-py3-none-any.whl (15 kB)\n", - "#9 123.8 Downloading opentelemetry_instrumentation_httpx-0.64b0-py3-none-any.whl (16 kB)\n", - "#9 123.9 Downloading opentelemetry_instrumentation_logging-0.64b0-py3-none-any.whl (16 kB)\n", - "#9 123.9 Downloading opentelemetry_instrumentation_psycopg2-0.64b0-py3-none-any.whl (10 kB)\n", - "#9 124.0 Downloading opentelemetry_instrumentation_dbapi-0.64b0-py3-none-any.whl (14 kB)\n", - "#9 124.0 Downloading opentelemetry_instrumentation_requests-0.64b0-py3-none-any.whl (13 kB)\n", - "#9 124.1 Downloading opentelemetry_instrumentation_urllib-0.64b0-py3-none-any.whl (13 kB)\n", - "#9 124.2 Downloading opentelemetry_instrumentation_urllib3-0.64b0-py3-none-any.whl (13 kB)\n", - "#9 124.3 Downloading opentelemetry_resource_detector_azure-0.1.5-py3-none-any.whl (14 kB)\n", - "#9 124.4 Downloading packaging-26.2-py3-none-any.whl (100 kB)\n", - "#9 124.4 Downloading six-1.17.0-py2.py3-none-any.whl (11 kB)\n", - "#9 124.5 Downloading wsproto-1.3.2-py3-none-any.whl (24 kB)\n", - "#9 124.6 Downloading priority-2.0.0-py3-none-any.whl (8.9 kB)\n", - "#9 124.7 Downloading googleapis_common_protos-1.75.0-py3-none-any.whl (300 kB)\n", - "#9 124.8 Downloading hpack-4.2.0-py3-none-any.whl (34 kB)\n", - "#9 124.9 Downloading hyperframe-6.1.0-py3-none-any.whl (13 kB)\n", - "#9 125.0 Downloading msrest-0.7.1-py3-none-any.whl (85 kB)\n", - "#9 125.0 Downloading psutil-7.2.2-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl (155 kB)\n", - "#9 125.1 Downloading pycparser-3.0-py3-none-any.whl (48 kB)\n", - "#9 125.2 Downloading asgiref-3.11.1-py3-none-any.whl (24 kB)\n", - "#9 125.2 Downloading protobuf-7.35.1-cp310-abi3-manylinux2014_x86_64.whl (327 kB)\n", - "#9 125.3 Downloading requests_oauthlib-2.0.0-py2.py3-none-any.whl (24 kB)\n", - "#9 125.4 Downloading oauthlib-3.3.1-py3-none-any.whl (160 kB)\n", - "#9 129.1 Installing collected packages: wrapt, watchdog, urllib3, typing-extensions, tqdm, sniffio, six, rpds-py, pyyaml, python-multipart, python-dotenv, pyjwt, pycparser, psutil, protobuf, propcache, priority, packaging, opentelemetry-util-http, oauthlib, multidict, jmespath, jiter, isodate, idna, hyperframe, httpx-sse, hpack, h11, frozenlist, docstring-parser, distro, click, charset_normalizer, certifi, attrs, asgiref, annotated-types, aiohappyeyeballs, yarl, wsproto, uvicorn, typing-inspection, requests, referencing, python-dateutil, pydantic-core, opentelemetry-proto, opentelemetry-api, httpcore, h2, googleapis-common-protos, cffi, anyio, aiosignal, starlette, requests-oauthlib, pydantic, opentelemetry-semantic-conventions, opentelemetry-exporter-otlp-proto-common, jsonschema-specifications, hypercorn, httpx, cryptography, botocore, azure-core, aiohttp, sse-starlette, s3transfer, pydantic-settings, opentelemetry-sdk, opentelemetry-instrumentation, openai, msrest, jsonschema, azure-storage-blob, azure-core-tracing-opentelemetry, aws-bedrock-token-generator, opentelemetry-util-genai, opentelemetry-resource-detector-azure, opentelemetry-instrumentation-wsgi, opentelemetry-instrumentation-urllib3, opentelemetry-instrumentation-urllib, opentelemetry-instrumentation-threading, opentelemetry-instrumentation-requests, opentelemetry-instrumentation-openai-v2, opentelemetry-instrumentation-logging, opentelemetry-instrumentation-httpx, opentelemetry-instrumentation-dbapi, opentelemetry-instrumentation-asgi, opentelemetry-exporter-otlp-proto-http, msal, mcp, boto3, strands-agents, opentelemetry-instrumentation-psycopg2, opentelemetry-instrumentation-openai-agents-v2, opentelemetry-instrumentation-flask, opentelemetry-instrumentation-fastapi, opentelemetry-instrumentation-django, msal-extensions, azure-identity, azure-monitor-opentelemetry-exporter, azure-ai-projects, microsoft-opentelemetry, azure-ai-agentserver-core, azure-ai-agentserver-responses\n", - "#9 203.7 Successfully installed aiohappyeyeballs-2.7.1 aiohttp-3.14.1 aiosignal-1.4.0 annotated-types-0.7.0 anyio-4.14.1 asgiref-3.11.1 attrs-26.1.0 aws-bedrock-token-generator-1.1.0 azure-ai-agentserver-core-2.0.0b7 azure-ai-agentserver-responses-1.0.0b8 azure-ai-projects-2.3.0 azure-core-1.41.0 azure-core-tracing-opentelemetry-1.0.0b13 azure-identity-1.25.3 azure-monitor-opentelemetry-exporter-1.0.0b55 azure-storage-blob-12.30.0 boto3-1.43.42 botocore-1.43.42 certifi-2026.6.17 cffi-2.1.0 charset_normalizer-3.4.9 click-8.4.2 cryptography-49.0.0 distro-1.9.0 docstring-parser-0.18.0 frozenlist-1.8.0 googleapis-common-protos-1.75.0 h11-0.16.0 h2-4.3.0 hpack-4.2.0 httpcore-1.0.9 httpx-0.28.1 httpx-sse-0.4.3 hypercorn-0.18.0 hyperframe-6.1.0 idna-3.18 isodate-0.7.2 jiter-0.16.0 jmespath-1.1.0 jsonschema-4.26.0 jsonschema-specifications-2025.9.1 mcp-1.28.1 microsoft-opentelemetry-1.3.5 msal-1.37.0 msal-extensions-1.3.1 msrest-0.7.1 multidict-6.7.1 oauthlib-3.3.1 openai-2.44.0 opentelemetry-api-1.43.0 opentelemetry-exporter-otlp-proto-common-1.43.0 opentelemetry-exporter-otlp-proto-http-1.43.0 opentelemetry-instrumentation-0.64b0 opentelemetry-instrumentation-asgi-0.64b0 opentelemetry-instrumentation-dbapi-0.64b0 opentelemetry-instrumentation-django-0.64b0 opentelemetry-instrumentation-fastapi-0.64b0 opentelemetry-instrumentation-flask-0.64b0 opentelemetry-instrumentation-httpx-0.64b0 opentelemetry-instrumentation-logging-0.64b0 opentelemetry-instrumentation-openai-agents-v2-0.1.0 opentelemetry-instrumentation-openai-v2-2.3b0 opentelemetry-instrumentation-psycopg2-0.64b0 opentelemetry-instrumentation-requests-0.64b0 opentelemetry-instrumentation-threading-0.64b0 opentelemetry-instrumentation-urllib-0.64b0 opentelemetry-instrumentation-urllib3-0.64b0 opentelemetry-instrumentation-wsgi-0.64b0 opentelemetry-proto-1.43.0 opentelemetry-resource-detector-azure-0.1.5 opentelemetry-sdk-1.43.0 opentelemetry-semantic-conventions-0.64b0 opentelemetry-util-genai-0.3b0 opentelemetry-util-http-0.64b0 packaging-26.2 priority-2.0.0 propcache-0.5.2 protobuf-7.35.1 psutil-7.2.2 pycparser-3.0 pydantic-2.13.4 pydantic-core-2.46.4 pydantic-settings-2.14.2 pyjwt-2.13.0 python-dateutil-2.9.0.post0 python-dotenv-1.2.2 python-multipart-0.0.32 pyyaml-6.0.3 referencing-0.37.0 requests-2.34.2 requests-oauthlib-2.0.0 rpds-py-2026.6.3 s3transfer-0.19.0 six-1.17.0 sniffio-1.3.1 sse-starlette-3.4.5 starlette-1.3.1 strands-agents-1.45.0 tqdm-4.68.4 typing-extensions-4.16.0 typing-inspection-0.4.2 urllib3-2.7.0 uvicorn-0.51.0 watchdog-6.0.0 wrapt-1.17.3 wsproto-1.3.2 yarl-1.24.2\n", - "#9 203.7 WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager, possibly rendering your system unusable. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv. Use the --root-user-action option if you know what you are doing and want to suppress this warning.\n", - "#9 204.5 \n", - "#9 204.5 [notice] A new release of pip is available: 25.0.1 -> 26.1.2\n", - "#9 204.5 [notice] To update, run: pip install --upgrade pip\n", - "#9 DONE 205.9s\n", + "#9 17.81 Collecting azure-ai-agentserver-responses==1.0.0b8 (from -r requirements.txt (line 1))\n", + "#9 18.06 Downloading azure_ai_agentserver_responses-1.0.0b8-py3-none-any.whl.metadata (13 kB)\n", + "#9 18.32 Collecting strands-agents==1.45.0 (from strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 18.35 Downloading strands_agents-1.45.0-py3-none-any.whl.metadata (19 kB)\n", + "#9 18.82 Collecting python-dotenv (from -r requirements.txt (line 3))\n", + "#9 18.85 Downloading python_dotenv-1.2.2-py3-none-any.whl.metadata (27 kB)\n", + "#9 19.01 Collecting azure-ai-projects==2.3.0 (from -r requirements.txt (line 4))\n", + "#9 19.05 Downloading azure_ai_projects-2.3.0-py3-none-any.whl.metadata (64 kB)\n", + "#9 19.37 Collecting azure-ai-agentserver-core>=2.0.0b7 (from azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 19.41 Downloading azure_ai_agentserver_core-2.0.0b7-py3-none-any.whl.metadata (7.8 kB)\n", + "#9 19.67 Collecting azure-core>=1.30.0 (from azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 19.71 Downloading azure_core-1.41.0-py3-none-any.whl.metadata (49 kB)\n", + "#9 19.88 Collecting isodate>=0.6.1 (from azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 19.93 Downloading isodate-0.7.2-py3-none-any.whl.metadata (11 kB)\n", + "#9 25.43 Collecting aiohttp<4.0.0,>=3.10.0 (from azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 25.47 Downloading aiohttp-3.14.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (8.3 kB)\n", + "#9 31.16 Collecting boto3<2.0.0,>=1.26.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 31.24 Downloading boto3-1.43.42-py3-none-any.whl.metadata (6.6 kB)\n", + "#9 36.86 Collecting botocore<2.0.0,>=1.29.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 36.91 Downloading botocore-1.43.42-py3-none-any.whl.metadata (5.6 kB)\n", + "#9 37.10 Collecting docstring-parser<1.0,>=0.15 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 37.17 Downloading docstring_parser-0.18.0-py3-none-any.whl.metadata (3.5 kB)\n", + "#9 37.59 Collecting jsonschema<5.0.0,>=4.0.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 37.65 Downloading jsonschema-4.26.0-py3-none-any.whl.metadata (7.6 kB)\n", + "#9 37.97 Collecting mcp<2.0.0,>=1.23.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 38.00 Downloading mcp-1.28.1-py3-none-any.whl.metadata (9.4 kB)\n", + "#9 38.38 Collecting opentelemetry-api<2.0.0,>=1.30.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 38.42 Downloading opentelemetry_api-1.43.0-py3-none-any.whl.metadata (1.4 kB)\n", + "#9 38.60 Collecting opentelemetry-instrumentation-threading<1.00b0,>=0.51b0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 38.67 Downloading opentelemetry_instrumentation_threading-0.64b0-py3-none-any.whl.metadata (2.1 kB)\n", + "#9 39.00 Collecting opentelemetry-sdk<2.0.0,>=1.30.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 39.03 Downloading opentelemetry_sdk-1.43.0-py3-none-any.whl.metadata (1.7 kB)\n", + "#9 40.44 Collecting pydantic<3.0.0,>=2.4.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 40.48 Downloading pydantic-2.13.4-py3-none-any.whl.metadata (109 kB)\n", + "#9 41.05 Collecting pyyaml<7.0.0,>=6.0.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 41.10 Downloading pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (2.4 kB)\n", + "#9 41.32 Collecting typing-extensions<5.0.0,>=4.13.2 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 41.36 Downloading typing_extensions-4.16.0-py3-none-any.whl.metadata (3.3 kB)\n", + "#9 41.83 Collecting watchdog<7.0.0,>=6.0.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 41.91 Downloading watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl.metadata (44 kB)\n", + "#9 42.60 Collecting azure-identity>=1.15.0 (from azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", + "#9 42.64 Downloading azure_identity-1.25.3-py3-none-any.whl.metadata (91 kB)\n", + "#9 43.48 Collecting openai>=2.8.0 (from azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", + "#9 43.53 Downloading openai-2.44.0-py3-none-any.whl.metadata (34 kB)\n", + "#9 43.91 Collecting azure-storage-blob>=12.15.0 (from azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", + "#9 43.96 Downloading azure_storage_blob-12.30.0-py3-none-any.whl.metadata (26 kB)\n", + "#9 44.23 Collecting aws-bedrock-token-generator<2.0.0,>=1.1.0 (from strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 44.40 Downloading aws_bedrock_token_generator-1.1.0-py3-none-any.whl.metadata (7.5 kB)\n", + "#9 45.09 Collecting aiohappyeyeballs>=2.5.0 (from aiohttp<4.0.0,>=3.10.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 45.13 Downloading aiohappyeyeballs-2.7.1-py3-none-any.whl.metadata (5.9 kB)\n", + "#9 45.31 Collecting aiosignal>=1.4.0 (from aiohttp<4.0.0,>=3.10.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 45.36 Downloading aiosignal-1.4.0-py3-none-any.whl.metadata (3.7 kB)\n", + "#9 45.58 Collecting attrs>=17.3.0 (from aiohttp<4.0.0,>=3.10.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 45.68 Downloading attrs-26.1.0-py3-none-any.whl.metadata (8.8 kB)\n", + "#9 46.52 Collecting frozenlist>=1.1.1 (from aiohttp<4.0.0,>=3.10.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 46.59 Downloading frozenlist-1.8.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl.metadata (20 kB)\n", + "#9 49.08 Collecting multidict<7.0,>=4.5 (from aiohttp<4.0.0,>=3.10.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 49.13 Downloading multidict-6.7.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (5.3 kB)\n", + "#9 49.89 Collecting propcache>=0.2.0 (from aiohttp<4.0.0,>=3.10.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 49.93 Downloading propcache-0.5.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (16 kB)\n", + "#9 53.28 Collecting yarl<2.0,>=1.17.0 (from aiohttp<4.0.0,>=3.10.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 53.36 Downloading yarl-1.24.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (94 kB)\n", + "#9 56.99 Collecting starlette>=0.45.0 (from azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 57.04 Downloading starlette-1.3.1-py3-none-any.whl.metadata (6.4 kB)\n", + "#9 57.28 Collecting hypercorn>=0.17.0 (from azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 57.36 Downloading hypercorn-0.18.0-py3-none-any.whl.metadata (5.1 kB)\n", + "#9 57.87 Collecting microsoft-opentelemetry>=1.0.0 (from azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 57.92 Downloading microsoft_opentelemetry-1.3.5-py3-none-any.whl.metadata (23 kB)\n", + "#9 58.41 Collecting requests>=2.21.0 (from azure-core>=1.30.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 58.48 Downloading requests-2.34.2-py3-none-any.whl.metadata (4.8 kB)\n", + "#9 60.99 Collecting cryptography>=2.5 (from azure-identity>=1.15.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", + "#9 61.03 Downloading cryptography-49.0.0-cp311-abi3-manylinux_2_34_x86_64.whl.metadata (4.3 kB)\n", + "#9 61.29 Collecting msal>=1.35.1 (from azure-identity>=1.15.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", + "#9 61.34 Downloading msal-1.37.0-py3-none-any.whl.metadata (11 kB)\n", + "#9 61.50 Collecting msal-extensions>=1.2.0 (from azure-identity>=1.15.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", + "#9 61.55 Downloading msal_extensions-1.3.1-py3-none-any.whl.metadata (7.8 kB)\n", + "#9 65.29 Collecting jmespath<2.0.0,>=0.7.1 (from boto3<2.0.0,>=1.26.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 65.33 Downloading jmespath-1.1.0-py3-none-any.whl.metadata (7.6 kB)\n", + "#9 65.54 Collecting s3transfer<0.20.0,>=0.19.0 (from boto3<2.0.0,>=1.26.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 65.57 Downloading s3transfer-0.19.0-py3-none-any.whl.metadata (1.7 kB)\n", + "#9 65.77 Collecting python-dateutil<3.0.0,>=2.1 (from botocore<2.0.0,>=1.29.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 65.80 Downloading python_dateutil-2.9.0.post0-py2.py3-none-any.whl.metadata (8.4 kB)\n", + "#9 66.19 Collecting urllib3!=2.2.0,<3,>=1.25.4 (from botocore<2.0.0,>=1.29.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 66.24 Downloading urllib3-2.7.0-py3-none-any.whl.metadata (6.9 kB)\n", + "#9 66.54 Collecting jsonschema-specifications>=2023.03.6 (from jsonschema<5.0.0,>=4.0.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 66.58 Downloading jsonschema_specifications-2025.9.1-py3-none-any.whl.metadata (2.9 kB)\n", + "#9 66.95 Collecting referencing>=0.28.4 (from jsonschema<5.0.0,>=4.0.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 66.98 Downloading referencing-0.37.0-py3-none-any.whl.metadata (2.8 kB)\n", + "#9 69.94 Collecting rpds-py>=0.25.0 (from jsonschema<5.0.0,>=4.0.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 70.00 Downloading rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (4.1 kB)\n", + "#9 70.25 Collecting anyio>=4.5 (from mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 70.28 Downloading anyio-4.14.1-py3-none-any.whl.metadata (4.6 kB)\n", + "#9 70.42 Collecting httpx-sse>=0.4 (from mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 70.50 Downloading httpx_sse-0.4.3-py3-none-any.whl.metadata (9.7 kB)\n", + "#9 70.90 Collecting httpx<1.0.0,>=0.27.1 (from mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 70.99 Downloading httpx-0.28.1-py3-none-any.whl.metadata (7.1 kB)\n", + "#9 71.47 Collecting pydantic-settings>=2.5.2 (from mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 71.53 Downloading pydantic_settings-2.14.2-py3-none-any.whl.metadata (3.4 kB)\n", + "#9 72.25 Collecting pyjwt>=2.10.1 (from pyjwt[crypto]>=2.10.1->mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 72.33 Downloading pyjwt-2.13.0-py3-none-any.whl.metadata (3.4 kB)\n", + "#9 72.66 Collecting python-multipart>=0.0.9 (from mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 72.70 Downloading python_multipart-0.0.32-py3-none-any.whl.metadata (2.1 kB)\n", + "#9 72.94 Collecting sse-starlette>=1.6.1 (from mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 72.98 Downloading sse_starlette-3.4.5-py3-none-any.whl.metadata (15 kB)\n", + "#9 73.56 Collecting typing-inspection>=0.4.1 (from mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 73.61 Downloading typing_inspection-0.4.2-py3-none-any.whl.metadata (2.6 kB)\n", + "#9 74.02 Collecting uvicorn>=0.31.1 (from mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 74.05 Downloading uvicorn-0.51.0-py3-none-any.whl.metadata (6.6 kB)\n", + "#9 74.38 Collecting distro<2,>=1.7.0 (from openai>=2.8.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", + "#9 74.51 Downloading distro-1.9.0-py3-none-any.whl.metadata (6.8 kB)\n", + "#9 75.61 Collecting jiter<1,>=0.10.0 (from openai>=2.8.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", + "#9 75.66 Downloading jiter-0.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (5.2 kB)\n", + "#9 76.27 Collecting sniffio (from openai>=2.8.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", + "#9 76.33 Downloading sniffio-1.3.1-py3-none-any.whl.metadata (3.9 kB)\n", + "#9 76.76 Collecting tqdm>4 (from openai>=2.8.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", + "#9 76.84 Downloading tqdm-4.68.4-py3-none-any.whl.metadata (57 kB)\n", + "#9 77.56 Collecting opentelemetry-instrumentation==0.64b0 (from opentelemetry-instrumentation-threading<1.00b0,>=0.51b0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 77.61 Downloading opentelemetry_instrumentation-0.64b0-py3-none-any.whl.metadata (7.2 kB)\n", + "#9 80.40 Collecting wrapt<3.0.0,>=1.0.0 (from opentelemetry-instrumentation-threading<1.00b0,>=0.51b0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 80.43 Downloading wrapt-2.2.2-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl.metadata (7.4 kB)\n", + "#9 80.91 Collecting opentelemetry-semantic-conventions==0.64b0 (from opentelemetry-instrumentation==0.64b0->opentelemetry-instrumentation-threading<1.00b0,>=0.51b0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 80.97 Downloading opentelemetry_semantic_conventions-0.64b0-py3-none-any.whl.metadata (2.4 kB)\n", + "#9 81.25 Collecting packaging>=18.0 (from opentelemetry-instrumentation==0.64b0->opentelemetry-instrumentation-threading<1.00b0,>=0.51b0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 81.28 Downloading packaging-26.2-py3-none-any.whl.metadata (3.5 kB)\n", + "#9 81.70 Collecting annotated-types>=0.6.0 (from pydantic<3.0.0,>=2.4.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 81.75 Downloading annotated_types-0.7.0-py3-none-any.whl.metadata (15 kB)\n", + "#9 89.37 Collecting pydantic-core==2.46.4 (from pydantic<3.0.0,>=2.4.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 89.41 Downloading pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (6.6 kB)\n", + "#9 89.97 Collecting idna>=2.8 (from anyio>=4.5->mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 90.02 Downloading idna-3.18-py3-none-any.whl.metadata (6.1 kB)\n", + "#9 91.24 Collecting cffi>=2.0.0 (from cryptography>=2.5->azure-identity>=1.15.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", + "#9 91.28 Downloading cffi-2.1.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.metadata (2.5 kB)\n", + "#9 91.60 Collecting certifi (from httpx<1.0.0,>=0.27.1->mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 91.72 Downloading certifi-2026.6.17-py3-none-any.whl.metadata (2.5 kB)\n", + "#9 92.12 Collecting httpcore==1.* (from httpx<1.0.0,>=0.27.1->mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 92.29 Downloading httpcore-1.0.9-py3-none-any.whl.metadata (21 kB)\n", + "#9 92.49 Collecting h11>=0.16 (from httpcore==1.*->httpx<1.0.0,>=0.27.1->mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 92.53 Downloading h11-0.16.0-py3-none-any.whl.metadata (8.3 kB)\n", + "#9 92.76 Collecting h2>=4.3.0 (from hypercorn>=0.17.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 92.83 Downloading h2-4.3.0-py3-none-any.whl.metadata (5.1 kB)\n", + "#9 93.00 Collecting priority (from hypercorn>=0.17.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 93.04 Downloading priority-2.0.0-py3-none-any.whl.metadata (6.6 kB)\n", + "#9 93.14 Collecting wsproto>=0.14.0 (from hypercorn>=0.17.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 93.18 Downloading wsproto-1.3.2-py3-none-any.whl.metadata (5.2 kB)\n", + "#9 93.65 Collecting azure-core-tracing-opentelemetry~=1.0.0b11 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 93.69 Downloading azure_core_tracing_opentelemetry-1.0.0b13-py3-none-any.whl.metadata (11 kB)\n", + "#9 93.95 Collecting azure-monitor-opentelemetry-exporter~=1.0.0b54 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 94.00 Downloading azure_monitor_opentelemetry_exporter-1.0.0b55-py2.py3-none-any.whl.metadata (33 kB)\n", + "#9 94.53 Collecting opentelemetry-exporter-otlp-proto-http~=1.43.0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 94.57 Downloading opentelemetry_exporter_otlp_proto_http-1.43.0-py3-none-any.whl.metadata (2.4 kB)\n", + "#9 94.93 Collecting opentelemetry-instrumentation-django<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 94.96 Downloading opentelemetry_instrumentation_django-0.64b0-py3-none-any.whl.metadata (2.3 kB)\n", + "#9 95.22 Collecting opentelemetry-instrumentation-fastapi<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 95.27 Downloading opentelemetry_instrumentation_fastapi-0.64b0-py3-none-any.whl.metadata (2.2 kB)\n", + "#9 95.58 Collecting opentelemetry-instrumentation-flask<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 95.62 Downloading opentelemetry_instrumentation_flask-0.64b0-py3-none-any.whl.metadata (2.2 kB)\n", + "#9 95.87 Collecting opentelemetry-instrumentation-httpx<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 95.91 Downloading opentelemetry_instrumentation_httpx-0.64b0-py3-none-any.whl.metadata (7.3 kB)\n", + "#9 96.28 Collecting opentelemetry-instrumentation-psycopg2<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 96.36 Downloading opentelemetry_instrumentation_psycopg2-0.64b0-py3-none-any.whl.metadata (2.1 kB)\n", + "#9 96.74 Collecting opentelemetry-instrumentation-requests<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 96.79 Downloading opentelemetry_instrumentation_requests-0.64b0-py3-none-any.whl.metadata (2.6 kB)\n", + "#9 97.17 Collecting opentelemetry-instrumentation-urllib<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 97.21 Downloading opentelemetry_instrumentation_urllib-0.64b0-py3-none-any.whl.metadata (3.4 kB)\n", + "#9 97.52 Collecting opentelemetry-instrumentation-urllib3<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 97.56 Downloading opentelemetry_instrumentation_urllib3-0.64b0-py3-none-any.whl.metadata (4.2 kB)\n", + "#9 97.83 Collecting opentelemetry-instrumentation-logging<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 97.87 Downloading opentelemetry_instrumentation_logging-0.64b0-py3-none-any.whl.metadata (1.9 kB)\n", + "#9 97.97 Collecting opentelemetry-instrumentation-openai-agents-v2==0.1.0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 98.02 Downloading opentelemetry_instrumentation_openai_agents_v2-0.1.0-py3-none-any.whl.metadata (1.3 kB)\n", + "#9 98.28 Collecting opentelemetry-instrumentation-openai-v2==2.3b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 98.34 Downloading opentelemetry_instrumentation_openai_v2-2.3b0-py3-none-any.whl.metadata (5.2 kB)\n", + "#9 98.63 Collecting opentelemetry-resource-detector-azure<1.0.0,>=0.1.5 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 98.68 Downloading opentelemetry_resource_detector_azure-0.1.5-py3-none-any.whl.metadata (5.3 kB)\n", + "#9 98.87 Collecting wrapt<3.0.0,>=1.0.0 (from opentelemetry-instrumentation-threading<1.00b0,>=0.51b0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 98.94 Downloading wrapt-1.17.3-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl.metadata (6.4 kB)\n", + "#9 99.08 Collecting opentelemetry-util-genai==0.3b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 99.16 Downloading opentelemetry_util_genai-0.3b0-py3-none-any.whl.metadata (4.6 kB)\n", + "#9 102.6 Collecting six>=1.5 (from python-dateutil<3.0.0,>=2.1->botocore<2.0.0,>=1.29.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 102.6 Downloading six-1.17.0-py2.py3-none-any.whl.metadata (1.7 kB)\n", + "#9 104.3 Collecting charset_normalizer<4,>=2 (from requests>=2.21.0->azure-core>=1.30.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 104.4 Downloading charset_normalizer-3.4.9-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (41 kB)\n", + "#9 108.6 Collecting click>=7.0 (from uvicorn>=0.31.1->mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 108.6 Downloading click-8.4.2-py3-none-any.whl.metadata (2.6 kB)\n", + "#9 109.7 Collecting msrest>=0.6.10 (from azure-monitor-opentelemetry-exporter~=1.0.0b54->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 109.7 Downloading msrest-0.7.1-py3-none-any.whl.metadata (21 kB)\n", + "#9 110.6 Collecting psutil<8,>=5.9 (from azure-monitor-opentelemetry-exporter~=1.0.0b54->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 110.6 Downloading psutil-7.2.2-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl.metadata (22 kB)\n", + "#9 111.0 Collecting pycparser (from cffi>=2.0.0->cryptography>=2.5->azure-identity>=1.15.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", + "#9 111.1 Downloading pycparser-3.0-py3-none-any.whl.metadata (8.2 kB)\n", + "#9 111.4 Collecting hyperframe<7,>=6.1 (from h2>=4.3.0->hypercorn>=0.17.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 111.4 Downloading hyperframe-6.1.0-py3-none-any.whl.metadata (4.3 kB)\n", + "#9 111.7 Collecting hpack<5,>=4.1 (from h2>=4.3.0->hypercorn>=0.17.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 111.8 Downloading hpack-4.2.0-py3-none-any.whl.metadata (3.3 kB)\n", + "#9 112.2 Collecting googleapis-common-protos~=1.52 (from opentelemetry-exporter-otlp-proto-http~=1.43.0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 112.2 Downloading googleapis_common_protos-1.75.0-py3-none-any.whl.metadata (8.6 kB)\n", + "#9 112.6 Collecting opentelemetry-exporter-otlp-proto-common==1.43.0 (from opentelemetry-exporter-otlp-proto-http~=1.43.0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 112.7 Downloading opentelemetry_exporter_otlp_proto_common-1.43.0-py3-none-any.whl.metadata (1.8 kB)\n", + "#9 112.9 Collecting opentelemetry-proto==1.43.0 (from opentelemetry-exporter-otlp-proto-http~=1.43.0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 112.9 Downloading opentelemetry_proto-1.43.0-py3-none-any.whl.metadata (2.3 kB)\n", + "#9 115.3 Collecting protobuf<8.0,>=5.0 (from opentelemetry-proto==1.43.0->opentelemetry-exporter-otlp-proto-http~=1.43.0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 115.3 Downloading protobuf-7.35.1-cp310-abi3-manylinux2014_x86_64.whl.metadata (595 bytes)\n", + "#9 115.6 Collecting opentelemetry-instrumentation-wsgi==0.64b0 (from opentelemetry-instrumentation-django<0.65b0,>=0.64b0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 115.6 Downloading opentelemetry_instrumentation_wsgi-0.64b0-py3-none-any.whl.metadata (2.1 kB)\n", + "#9 115.9 Collecting opentelemetry-util-http==0.64b0 (from opentelemetry-instrumentation-django<0.65b0,>=0.64b0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 115.9 Downloading opentelemetry_util_http-0.64b0-py3-none-any.whl.metadata (2.6 kB)\n", + "#9 116.5 Collecting opentelemetry-instrumentation-asgi==0.64b0 (from opentelemetry-instrumentation-fastapi<0.65b0,>=0.64b0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 116.5 Downloading opentelemetry_instrumentation_asgi-0.64b0-py3-none-any.whl.metadata (2.0 kB)\n", + "#9 116.9 Collecting asgiref~=3.0 (from opentelemetry-instrumentation-asgi==0.64b0->opentelemetry-instrumentation-fastapi<0.65b0,>=0.64b0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 117.0 Downloading asgiref-3.11.1-py3-none-any.whl.metadata (9.3 kB)\n", + "#9 117.5 Collecting opentelemetry-instrumentation-dbapi==0.64b0 (from opentelemetry-instrumentation-psycopg2<0.65b0,>=0.64b0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 117.6 Downloading opentelemetry_instrumentation_dbapi-0.64b0-py3-none-any.whl.metadata (2.0 kB)\n", + "#9 118.9 Collecting requests-oauthlib>=0.5.0 (from msrest>=0.6.10->azure-monitor-opentelemetry-exporter~=1.0.0b54->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 118.9 Downloading requests_oauthlib-2.0.0-py2.py3-none-any.whl.metadata (11 kB)\n", + "#9 119.8 Collecting oauthlib>=3.0.0 (from requests-oauthlib>=0.5.0->msrest>=0.6.10->azure-monitor-opentelemetry-exporter~=1.0.0b54->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 119.9 Downloading oauthlib-3.3.1-py3-none-any.whl.metadata (7.9 kB)\n", + "#9 120.1 Downloading azure_ai_agentserver_responses-1.0.0b8-py3-none-any.whl (269 kB)\n", + "#9 120.3 Downloading strands_agents-1.45.0-py3-none-any.whl (579 kB)\n", + "#9 120.4 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 579.3/579.3 kB 3.7 MB/s eta 0:00:00\n", + "#9 120.5 Downloading azure_ai_projects-2.3.0-py3-none-any.whl (349 kB)\n", + "#9 120.6 Downloading python_dotenv-1.2.2-py3-none-any.whl (22 kB)\n", + "#9 120.7 Downloading aiohttp-3.14.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (1.8 MB)\n", + "#9 121.0 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.8/1.8 MB 5.3 MB/s eta 0:00:00\n", + "#9 121.0 Downloading aws_bedrock_token_generator-1.1.0-py3-none-any.whl (10 kB)\n", + "#9 121.1 Downloading azure_ai_agentserver_core-2.0.0b7-py3-none-any.whl (35 kB)\n", + "#9 121.3 Downloading azure_core-1.41.0-py3-none-any.whl (220 kB)\n", + "#9 121.4 Downloading azure_identity-1.25.3-py3-none-any.whl (192 kB)\n", + "#9 121.7 Downloading azure_storage_blob-12.30.0-py3-none-any.whl (435 kB)\n", + "#9 122.1 Downloading boto3-1.43.42-py3-none-any.whl (140 kB)\n", + "#9 122.2 Downloading botocore-1.43.42-py3-none-any.whl (15.4 MB)\n", + "#9 124.6 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 15.4/15.4 MB 6.9 MB/s eta 0:00:00\n", + "#9 124.6 Downloading docstring_parser-0.18.0-py3-none-any.whl (22 kB)\n", + "#9 124.7 Downloading isodate-0.7.2-py3-none-any.whl (22 kB)\n", + "#9 124.9 Downloading jsonschema-4.26.0-py3-none-any.whl (90 kB)\n", + "#9 125.0 Downloading mcp-1.28.1-py3-none-any.whl (222 kB)\n", + "#9 125.2 Downloading openai-2.44.0-py3-none-any.whl (1.4 MB)\n", + "#9 125.3 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.4/1.4 MB 9.8 MB/s eta 0:00:00\n", + "#9 125.4 Downloading opentelemetry_api-1.43.0-py3-none-any.whl (61 kB)\n", + "#9 125.5 Downloading opentelemetry_instrumentation_threading-0.64b0-py3-none-any.whl (8.5 kB)\n", + "#9 125.5 Downloading opentelemetry_instrumentation-0.64b0-py3-none-any.whl (35 kB)\n", + "#9 125.6 Downloading opentelemetry_semantic_conventions-0.64b0-py3-none-any.whl (203 kB)\n", + "#9 125.8 Downloading opentelemetry_sdk-1.43.0-py3-none-any.whl (178 kB)\n", + "#9 125.9 Downloading pydantic-2.13.4-py3-none-any.whl (472 kB)\n", + "#9 126.1 Downloading pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.1 MB)\n", + "#9 126.4 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2.1/2.1 MB 6.0 MB/s eta 0:00:00\n", + "#9 126.5 Downloading pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (807 kB)\n", + "#9 126.6 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 807.9/807.9 kB 6.7 MB/s eta 0:00:00\n", + "#9 126.7 Downloading typing_extensions-4.16.0-py3-none-any.whl (45 kB)\n", + "#9 126.7 Downloading watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl (79 kB)\n", + "#9 126.8 Downloading aiohappyeyeballs-2.7.1-py3-none-any.whl (15 kB)\n", + "#9 126.9 Downloading aiosignal-1.4.0-py3-none-any.whl (7.5 kB)\n", + "#9 126.9 Downloading annotated_types-0.7.0-py3-none-any.whl (13 kB)\n", + "#9 127.0 Downloading anyio-4.14.1-py3-none-any.whl (124 kB)\n", + "#9 127.1 Downloading attrs-26.1.0-py3-none-any.whl (67 kB)\n", + "#9 127.2 Downloading cryptography-49.0.0-cp311-abi3-manylinux_2_34_x86_64.whl (4.7 MB)\n", + "#9 127.9 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 4.7/4.7 MB 7.2 MB/s eta 0:00:00\n", + "#9 127.9 Downloading distro-1.9.0-py3-none-any.whl (20 kB)\n", + "#9 128.0 Downloading frozenlist-1.8.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl (242 kB)\n", + "#9 128.2 Downloading httpx-0.28.1-py3-none-any.whl (73 kB)\n", + "#9 128.3 Downloading httpcore-1.0.9-py3-none-any.whl (78 kB)\n", + "#9 128.4 Downloading httpx_sse-0.4.3-py3-none-any.whl (9.0 kB)\n", + "#9 128.5 Downloading hypercorn-0.18.0-py3-none-any.whl (61 kB)\n", + "#9 128.6 Downloading jiter-0.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (343 kB)\n", + "#9 128.8 Downloading jmespath-1.1.0-py3-none-any.whl (20 kB)\n", + "#9 128.9 Downloading jsonschema_specifications-2025.9.1-py3-none-any.whl (18 kB)\n", + "#9 129.0 Downloading microsoft_opentelemetry-1.3.5-py3-none-any.whl (208 kB)\n", + "#9 129.1 Downloading opentelemetry_instrumentation_openai_agents_v2-0.1.0-py3-none-any.whl (25 kB)\n", + "#9 129.2 Downloading opentelemetry_instrumentation_openai_v2-2.3b0-py3-none-any.whl (18 kB)\n", + "#9 129.2 Downloading opentelemetry_util_genai-0.3b0-py3-none-any.whl (28 kB)\n", + "#9 129.3 Downloading msal-1.37.0-py3-none-any.whl (123 kB)\n", + "#9 129.4 Downloading msal_extensions-1.3.1-py3-none-any.whl (20 kB)\n", + "#9 129.5 Downloading multidict-6.7.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (256 kB)\n", + "#9 129.6 Downloading propcache-0.5.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (61 kB)\n", + "#9 129.6 Downloading pydantic_settings-2.14.2-py3-none-any.whl (61 kB)\n", + "#9 129.7 Downloading pyjwt-2.13.0-py3-none-any.whl (31 kB)\n", + "#9 129.8 Downloading python_dateutil-2.9.0.post0-py2.py3-none-any.whl (229 kB)\n", + "#9 129.9 Downloading python_multipart-0.0.32-py3-none-any.whl (30 kB)\n", + "#9 130.0 Downloading referencing-0.37.0-py3-none-any.whl (26 kB)\n", + "#9 130.0 Downloading requests-2.34.2-py3-none-any.whl (73 kB)\n", + "#9 130.1 Downloading rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (366 kB)\n", + "#9 130.2 Downloading s3transfer-0.19.0-py3-none-any.whl (90 kB)\n", + "#9 130.3 Downloading sse_starlette-3.4.5-py3-none-any.whl (16 kB)\n", + "#9 130.3 Downloading starlette-1.3.1-py3-none-any.whl (73 kB)\n", + "#9 130.4 Downloading tqdm-4.68.4-py3-none-any.whl (676 kB)\n", + "#9 130.7 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 676.6/676.6 kB 1.3 MB/s eta 0:00:00\n", + "#9 130.8 Downloading typing_inspection-0.4.2-py3-none-any.whl (14 kB)\n", + "#9 130.9 Downloading urllib3-2.7.0-py3-none-any.whl (131 kB)\n", + "#9 130.9 Downloading uvicorn-0.51.0-py3-none-any.whl (73 kB)\n", + "#9 131.0 Downloading wrapt-1.17.3-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl (88 kB)\n", + "#9 131.0 Downloading yarl-1.24.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (105 kB)\n", + "#9 131.1 Downloading sniffio-1.3.1-py3-none-any.whl (10 kB)\n", + "#9 131.1 Downloading azure_core_tracing_opentelemetry-1.0.0b13-py3-none-any.whl (12 kB)\n", + "#9 131.2 Downloading azure_monitor_opentelemetry_exporter-1.0.0b55-py2.py3-none-any.whl (251 kB)\n", + "#9 131.3 Downloading certifi-2026.6.17-py3-none-any.whl (133 kB)\n", + "#9 131.3 Downloading cffi-2.1.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (221 kB)\n", + "#9 131.4 Downloading charset_normalizer-3.4.9-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (224 kB)\n", + "#9 131.4 Downloading click-8.4.2-py3-none-any.whl (119 kB)\n", + "#9 131.5 Downloading h11-0.16.0-py3-none-any.whl (37 kB)\n", + "#9 131.5 Downloading h2-4.3.0-py3-none-any.whl (61 kB)\n", + "#9 131.6 Downloading idna-3.18-py3-none-any.whl (65 kB)\n", + "#9 131.7 Downloading opentelemetry_exporter_otlp_proto_http-1.43.0-py3-none-any.whl (21 kB)\n", + "#9 131.8 Downloading opentelemetry_exporter_otlp_proto_common-1.43.0-py3-none-any.whl (17 kB)\n", + "#9 131.8 Downloading opentelemetry_proto-1.43.0-py3-none-any.whl (72 kB)\n", + "#9 131.9 Downloading opentelemetry_instrumentation_django-0.64b0-py3-none-any.whl (18 kB)\n", + "#9 132.0 Downloading opentelemetry_instrumentation_wsgi-0.64b0-py3-none-any.whl (13 kB)\n", + "#9 132.1 Downloading opentelemetry_util_http-0.64b0-py3-none-any.whl (8.2 kB)\n", + "#9 132.1 Downloading opentelemetry_instrumentation_fastapi-0.64b0-py3-none-any.whl (13 kB)\n", + "#9 132.2 Downloading opentelemetry_instrumentation_asgi-0.64b0-py3-none-any.whl (15 kB)\n", + "#9 132.3 Downloading opentelemetry_instrumentation_flask-0.64b0-py3-none-any.whl (15 kB)\n", + "#9 132.3 Downloading opentelemetry_instrumentation_httpx-0.64b0-py3-none-any.whl (16 kB)\n", + "#9 132.4 Downloading opentelemetry_instrumentation_logging-0.64b0-py3-none-any.whl (16 kB)\n", + "#9 132.5 Downloading opentelemetry_instrumentation_psycopg2-0.64b0-py3-none-any.whl (10 kB)\n", + "#9 132.5 Downloading opentelemetry_instrumentation_dbapi-0.64b0-py3-none-any.whl (14 kB)\n", + "#9 132.6 Downloading opentelemetry_instrumentation_requests-0.64b0-py3-none-any.whl (13 kB)\n", + "#9 132.6 Downloading opentelemetry_instrumentation_urllib-0.64b0-py3-none-any.whl (13 kB)\n", + "#9 132.7 Downloading opentelemetry_instrumentation_urllib3-0.64b0-py3-none-any.whl (13 kB)\n", + "#9 132.7 Downloading opentelemetry_resource_detector_azure-0.1.5-py3-none-any.whl (14 kB)\n", + "#9 132.8 Downloading packaging-26.2-py3-none-any.whl (100 kB)\n", + "#9 132.8 Downloading six-1.17.0-py2.py3-none-any.whl (11 kB)\n", + "#9 132.9 Downloading wsproto-1.3.2-py3-none-any.whl (24 kB)\n", + "#9 132.9 Downloading priority-2.0.0-py3-none-any.whl (8.9 kB)\n", + "#9 133.0 Downloading googleapis_common_protos-1.75.0-py3-none-any.whl (300 kB)\n", + "#9 133.1 Downloading hpack-4.2.0-py3-none-any.whl (34 kB)\n", + "#9 133.1 Downloading hyperframe-6.1.0-py3-none-any.whl (13 kB)\n", + "#9 133.2 Downloading msrest-0.7.1-py3-none-any.whl (85 kB)\n", + "#9 133.2 Downloading psutil-7.2.2-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl (155 kB)\n", + "#9 133.3 Downloading pycparser-3.0-py3-none-any.whl (48 kB)\n", + "#9 133.4 Downloading asgiref-3.11.1-py3-none-any.whl (24 kB)\n", + "#9 133.5 Downloading protobuf-7.35.1-cp310-abi3-manylinux2014_x86_64.whl (327 kB)\n", + "#9 133.7 Downloading requests_oauthlib-2.0.0-py2.py3-none-any.whl (24 kB)\n", + "#9 133.8 Downloading oauthlib-3.3.1-py3-none-any.whl (160 kB)\n", + "#9 137.5 Installing collected packages: wrapt, watchdog, urllib3, typing-extensions, tqdm, sniffio, six, rpds-py, pyyaml, python-multipart, python-dotenv, pyjwt, pycparser, psutil, protobuf, propcache, priority, packaging, opentelemetry-util-http, oauthlib, multidict, jmespath, jiter, isodate, idna, hyperframe, httpx-sse, hpack, h11, frozenlist, docstring-parser, distro, click, charset_normalizer, certifi, attrs, asgiref, annotated-types, aiohappyeyeballs, yarl, wsproto, uvicorn, typing-inspection, requests, referencing, python-dateutil, pydantic-core, opentelemetry-proto, opentelemetry-api, httpcore, h2, googleapis-common-protos, cffi, anyio, aiosignal, starlette, requests-oauthlib, pydantic, opentelemetry-semantic-conventions, opentelemetry-exporter-otlp-proto-common, jsonschema-specifications, hypercorn, httpx, cryptography, botocore, azure-core, aiohttp, sse-starlette, s3transfer, pydantic-settings, opentelemetry-sdk, opentelemetry-instrumentation, openai, msrest, jsonschema, azure-storage-blob, azure-core-tracing-opentelemetry, aws-bedrock-token-generator, opentelemetry-util-genai, opentelemetry-resource-detector-azure, opentelemetry-instrumentation-wsgi, opentelemetry-instrumentation-urllib3, opentelemetry-instrumentation-urllib, opentelemetry-instrumentation-threading, opentelemetry-instrumentation-requests, opentelemetry-instrumentation-openai-v2, opentelemetry-instrumentation-logging, opentelemetry-instrumentation-httpx, opentelemetry-instrumentation-dbapi, opentelemetry-instrumentation-asgi, opentelemetry-exporter-otlp-proto-http, msal, mcp, boto3, strands-agents, opentelemetry-instrumentation-psycopg2, opentelemetry-instrumentation-openai-agents-v2, opentelemetry-instrumentation-flask, opentelemetry-instrumentation-fastapi, opentelemetry-instrumentation-django, msal-extensions, azure-identity, azure-monitor-opentelemetry-exporter, azure-ai-projects, microsoft-opentelemetry, azure-ai-agentserver-core, azure-ai-agentserver-responses\n", + "#9 213.7 Successfully installed aiohappyeyeballs-2.7.1 aiohttp-3.14.1 aiosignal-1.4.0 annotated-types-0.7.0 anyio-4.14.1 asgiref-3.11.1 attrs-26.1.0 aws-bedrock-token-generator-1.1.0 azure-ai-agentserver-core-2.0.0b7 azure-ai-agentserver-responses-1.0.0b8 azure-ai-projects-2.3.0 azure-core-1.41.0 azure-core-tracing-opentelemetry-1.0.0b13 azure-identity-1.25.3 azure-monitor-opentelemetry-exporter-1.0.0b55 azure-storage-blob-12.30.0 boto3-1.43.42 botocore-1.43.42 certifi-2026.6.17 cffi-2.1.0 charset_normalizer-3.4.9 click-8.4.2 cryptography-49.0.0 distro-1.9.0 docstring-parser-0.18.0 frozenlist-1.8.0 googleapis-common-protos-1.75.0 h11-0.16.0 h2-4.3.0 hpack-4.2.0 httpcore-1.0.9 httpx-0.28.1 httpx-sse-0.4.3 hypercorn-0.18.0 hyperframe-6.1.0 idna-3.18 isodate-0.7.2 jiter-0.16.0 jmespath-1.1.0 jsonschema-4.26.0 jsonschema-specifications-2025.9.1 mcp-1.28.1 microsoft-opentelemetry-1.3.5 msal-1.37.0 msal-extensions-1.3.1 msrest-0.7.1 multidict-6.7.1 oauthlib-3.3.1 openai-2.44.0 opentelemetry-api-1.43.0 opentelemetry-exporter-otlp-proto-common-1.43.0 opentelemetry-exporter-otlp-proto-http-1.43.0 opentelemetry-instrumentation-0.64b0 opentelemetry-instrumentation-asgi-0.64b0 opentelemetry-instrumentation-dbapi-0.64b0 opentelemetry-instrumentation-django-0.64b0 opentelemetry-instrumentation-fastapi-0.64b0 opentelemetry-instrumentation-flask-0.64b0 opentelemetry-instrumentation-httpx-0.64b0 opentelemetry-instrumentation-logging-0.64b0 opentelemetry-instrumentation-openai-agents-v2-0.1.0 opentelemetry-instrumentation-openai-v2-2.3b0 opentelemetry-instrumentation-psycopg2-0.64b0 opentelemetry-instrumentation-requests-0.64b0 opentelemetry-instrumentation-threading-0.64b0 opentelemetry-instrumentation-urllib-0.64b0 opentelemetry-instrumentation-urllib3-0.64b0 opentelemetry-instrumentation-wsgi-0.64b0 opentelemetry-proto-1.43.0 opentelemetry-resource-detector-azure-0.1.5 opentelemetry-sdk-1.43.0 opentelemetry-semantic-conventions-0.64b0 opentelemetry-util-genai-0.3b0 opentelemetry-util-http-0.64b0 packaging-26.2 priority-2.0.0 propcache-0.5.2 protobuf-7.35.1 psutil-7.2.2 pycparser-3.0 pydantic-2.13.4 pydantic-core-2.46.4 pydantic-settings-2.14.2 pyjwt-2.13.0 python-dateutil-2.9.0.post0 python-dotenv-1.2.2 python-multipart-0.0.32 pyyaml-6.0.3 referencing-0.37.0 requests-2.34.2 requests-oauthlib-2.0.0 rpds-py-2026.6.3 s3transfer-0.19.0 six-1.17.0 sniffio-1.3.1 sse-starlette-3.4.5 starlette-1.3.1 strands-agents-1.45.0 tqdm-4.68.4 typing-extensions-4.16.0 typing-inspection-0.4.2 urllib3-2.7.0 uvicorn-0.51.0 watchdog-6.0.0 wrapt-1.17.3 wsproto-1.3.2 yarl-1.24.2\n", + "#9 213.7 WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager, possibly rendering your system unusable. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv. Use the --root-user-action option if you know what you are doing and want to suppress this warning.\n", + "#9 214.6 \n", + "#9 214.6 [notice] A new release of pip is available: 25.0.1 -> 26.1.2\n", + "#9 214.6 [notice] To update, run: pip install --upgrade pip\n", + "#9 DONE 216.0s\n", "\n", "#10 exporting to image\n", "#10 exporting layers\n", "#10 exporting layers 5.9s done\n", - "#10 exporting manifest sha256:35f0f217ae600a88d65c2ab51371e147d615913decd5e6499de584b97fd2187e\n", - "#10 exporting manifest sha256:35f0f217ae600a88d65c2ab51371e147d615913decd5e6499de584b97fd2187e 0.0s done\n", - "#10 exporting config sha256:076bd17831d575d16d30100abb9881e88216dbb08a343202fe5a677538ff6489 0.0s done\n", - "#10 exporting attestation manifest sha256:f1b15d9ff6ed0b2cad5b215b4686340fdf2dd1427290f53852be1a055bc3ce4e 0.0s done\n", - "#10 exporting manifest list sha256:416112ec1036a05de70379fd53150ef164f287caeb5adf23668f0b6daff10a95 0.0s done\n", - "#10 naming to acrvu4ax6chjqjsk.azurecr.io/strands-agent:1.0.0 done\n", - "#10 DONE 6.0s\n" + "#10 exporting manifest sha256:f83339a6f88c9855285a635dc6a82f3330db39d722752b5566a976a017184318 0.0s done\n", + "#10 exporting config sha256:25e26bb089b0d3fc015de4cc0e060393904941195b286ff385e949092ca55112 0.0s done\n", + "#10 exporting attestation manifest sha256:55604b7e39e2e155e90068bb085dc70c2dc6403dc306d8846a8a0755a64aaabe 0.0s done\n", + "#10 exporting manifest list sha256:696f84a1b0bae9bcb0dcc4ca855933fe86629c5b4fc201903e08e0a0cdf025e7 0.0s done\n", + "#10 naming to acrxhep4wovroziu.azurecr.io/strands-agent:1.0.0\n", + "#10 naming to acrxhep4wovroziu.azurecr.io/strands-agent:1.0.0 done\n", + "#10 DONE 6.1s\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "The push refers to repository [acrvu4ax6chjqjsk.azurecr.io/strands-agent]\n", - "5448f2dea2bc: Waiting\n", - "9fe7005554a0: Waiting\n", + "The push refers to repository [acrxhep4wovroziu.azurecr.io/strands-agent]\n", + "d8928a1a5156: Waiting\n", + "b32430367bf0: Waiting\n", + "920a378a0384: Waiting\n", "4f4fb700ef54: Waiting\n", "df79d931cd67: Waiting\n", "e95a6c7ea7d4: Waiting\n", - "b32430367bf0: Waiting\n", - "6ad5ff264d4d: Waiting\n", - "b12bbba8f9a6: Waiting\n", + "5448f2dea2bc: Waiting\n", + "aff2d9f8dc87: Waiting\n", + "8c85a4e00d52: Waiting\n", "aff2d9f8dc87: Waiting\n", + "8c85a4e00d52: Waiting\n", + "d8928a1a5156: Waiting\n", + "b32430367bf0: Waiting\n", + "920a378a0384: Waiting\n", "4f4fb700ef54: Waiting\n", "df79d931cd67: Waiting\n", "e95a6c7ea7d4: Waiting\n", - "b32430367bf0: Waiting\n", - "6ad5ff264d4d: Waiting\n", - "b12bbba8f9a6: Waiting\n", - "aff2d9f8dc87: Waiting\n", - "5448f2dea2bc: Waiting\n", - "9fe7005554a0: Waiting\n", - "6ad5ff264d4d: Waiting\n", - "b12bbba8f9a6: Waiting\n", - "aff2d9f8dc87: Waiting\n", "5448f2dea2bc: Waiting\n", - "9fe7005554a0: Waiting\n", + "8c85a4e00d52: Waiting\n", + "d8928a1a5156: Waiting\n", + "b32430367bf0: Waiting\n", + "920a378a0384: Waiting\n", "4f4fb700ef54: Waiting\n", "df79d931cd67: Waiting\n", "e95a6c7ea7d4: Waiting\n", + "5448f2dea2bc: Waiting\n", + "aff2d9f8dc87: Waiting\n", "b32430367bf0: Waiting\n", + "920a378a0384: Waiting\n", + "4f4fb700ef54: Waiting\n", "df79d931cd67: Waiting\n", "e95a6c7ea7d4: Waiting\n", - "b32430367bf0: Waiting\n", - "6ad5ff264d4d: Waiting\n", - "b12bbba8f9a6: Waiting\n", - "aff2d9f8dc87: Waiting\n", "5448f2dea2bc: Waiting\n", - "9fe7005554a0: Waiting\n", - "4f4fb700ef54: Waiting\n", - "6ad5ff264d4d: Waiting\n", - "b12bbba8f9a6: Waiting\n", "aff2d9f8dc87: Waiting\n", - "5448f2dea2bc: Waiting\n", - "9fe7005554a0: Waiting\n", + "8c85a4e00d52: Waiting\n", + "d8928a1a5156: Waiting\n", + "8c85a4e00d52: Waiting\n", + "d8928a1a5156: Waiting\n", + "b32430367bf0: Waiting\n", + "920a378a0384: Waiting\n", "4f4fb700ef54: Waiting\n", "df79d931cd67: Waiting\n", "e95a6c7ea7d4: Waiting\n", - "b32430367bf0: Waiting\n", - "6ad5ff264d4d: Waiting\n", - "b12bbba8f9a6: Waiting\n", - "aff2d9f8dc87: Waiting\n", "5448f2dea2bc: Waiting\n", - "9fe7005554a0: Waiting\n", + "aff2d9f8dc87: Waiting\n", + "8c85a4e00d52: Waiting\n", + "d8928a1a5156: Waiting\n", + "b32430367bf0: Waiting\n", + "920a378a0384: Waiting\n", "4f4fb700ef54: Waiting\n", - "df79d931cd67: Layer already exists\n", + "df79d931cd67: Waiting\n", "e95a6c7ea7d4: Waiting\n", - "b32430367bf0: Waiting\n", - "b12bbba8f9a6: Waiting\n", + "5448f2dea2bc: Waiting\n", "aff2d9f8dc87: Waiting\n", - "9fe7005554a0: Waiting\n", - "4f4fb700ef54: Layer already exists\n", - "e95a6c7ea7d4: Waiting\n", + "8c85a4e00d52: Waiting\n", + "d8928a1a5156: Waiting\n", "b32430367bf0: Waiting\n", - "6ad5ff264d4d: Waiting\n", - "aff2d9f8dc87: Layer already exists\n", - "e95a6c7ea7d4: Waiting\n", - "b32430367bf0: Layer already exists\n", + "920a378a0384: Waiting\n", + "df79d931cd67: Waiting\n", + "5448f2dea2bc: Waiting\n", + "4f4fb700ef54: Pushed\n", "5448f2dea2bc: Pushed\n", - "6ad5ff264d4d: Pushed\n", - "9fe7005554a0: Pushed\n", + "8c85a4e00d52: Pushed\n", + "b32430367bf0: Pushed\n", + "920a378a0384: Pushed\n", + "aff2d9f8dc87: Pushed\n", + "df79d931cd67: Pushed\n", "e95a6c7ea7d4: Pushed\n", - "b12bbba8f9a6: Pushed\n", - "1.0.0: digest: sha256:416112ec1036a05de70379fd53150ef164f287caeb5adf23668f0b6daff10a95 size: 856\n", + "d8928a1a5156: Pushed\n", + "1.0.0: digest: sha256:696f84a1b0bae9bcb0dcc4ca855933fe86629c5b4fc201903e08e0a0cdf025e7 size: 856\n", "Docker build and push completed successfully.\n" ] } ], "source": [ + "\n", "# Use Docker directly from the notebook\n", "print(f\"Running: docker build -t {IMAGE_URI} .\")\n", "!docker build -t {IMAGE_URI} --platform linux/amd64 .\n", @@ -611,7 +594,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 16, "id": "cca00471", "metadata": {}, "outputs": [ @@ -620,96 +603,155 @@ "output_type": "stream", "text": [ "Collecting azure-ai-projects==2.3.0\n", - " Using cached azure_ai_projects-2.3.0-py3-none-any.whl.metadata (64 kB)\n", + " Downloading azure_ai_projects-2.3.0-py3-none-any.whl.metadata (64 kB)\n", "Collecting isodate>=0.6.1 (from azure-ai-projects==2.3.0)\n", - " Using cached isodate-0.7.2-py3-none-any.whl.metadata (11 kB)\n", + " Downloading isodate-0.7.2-py3-none-any.whl.metadata (11 kB)\n", "Collecting azure-core>=1.37.0 (from azure-ai-projects==2.3.0)\n", - " Using cached azure_core-1.41.0-py3-none-any.whl.metadata (49 kB)\n", - "Requirement already satisfied: typing-extensions>=4.11 in c:\\users\\ollisgeorge\\appdata\\roaming\\python\\python312\\site-packages (from azure-ai-projects==2.3.0) (4.16.0)\n", + " Downloading azure_core-1.41.0-py3-none-any.whl.metadata (49 kB)\n", + "Collecting typing-extensions>=4.11 (from azure-ai-projects==2.3.0)\n", + " Downloading typing_extensions-4.16.0-py3-none-any.whl.metadata (3.3 kB)\n", "Collecting azure-identity>=1.15.0 (from azure-ai-projects==2.3.0)\n", - " Using cached azure_identity-1.25.3-py3-none-any.whl.metadata (91 kB)\n", + " Downloading azure_identity-1.25.3-py3-none-any.whl.metadata (91 kB)\n", "Collecting openai>=2.8.0 (from azure-ai-projects==2.3.0)\n", - " Using cached openai-2.44.0-py3-none-any.whl.metadata (34 kB)\n", + " Downloading openai-2.44.0-py3-none-any.whl.metadata (34 kB)\n", "Collecting azure-storage-blob>=12.15.0 (from azure-ai-projects==2.3.0)\n", - " Using cached azure_storage_blob-12.30.0-py3-none-any.whl.metadata (26 kB)\n", + " Downloading azure_storage_blob-12.30.0-py3-none-any.whl.metadata (26 kB)\n", "Collecting requests>=2.21.0 (from azure-core>=1.37.0->azure-ai-projects==2.3.0)\n", - " Using cached requests-2.34.2-py3-none-any.whl.metadata (4.8 kB)\n", + " Downloading requests-2.34.2-py3-none-any.whl.metadata (4.8 kB)\n", "Collecting cryptography>=2.5 (from azure-identity>=1.15.0->azure-ai-projects==2.3.0)\n", - " Using cached cryptography-49.0.0-cp311-abi3-win_amd64.whl.metadata (4.3 kB)\n", + " Downloading cryptography-49.0.0-cp311-abi3-win_amd64.whl.metadata (4.3 kB)\n", "Collecting msal>=1.35.1 (from azure-identity>=1.15.0->azure-ai-projects==2.3.0)\n", - " Using cached msal-1.37.0-py3-none-any.whl.metadata (11 kB)\n", + " Downloading msal-1.37.0-py3-none-any.whl.metadata (11 kB)\n", "Collecting msal-extensions>=1.2.0 (from azure-identity>=1.15.0->azure-ai-projects==2.3.0)\n", - " Using cached msal_extensions-1.3.1-py3-none-any.whl.metadata (7.8 kB)\n", + " Downloading msal_extensions-1.3.1-py3-none-any.whl.metadata (7.8 kB)\n", "Collecting anyio<5,>=3.5.0 (from openai>=2.8.0->azure-ai-projects==2.3.0)\n", - " Using cached anyio-4.14.1-py3-none-any.whl.metadata (4.6 kB)\n", + " Downloading anyio-4.14.1-py3-none-any.whl.metadata (4.6 kB)\n", "Collecting distro<2,>=1.7.0 (from openai>=2.8.0->azure-ai-projects==2.3.0)\n", - " Using cached distro-1.9.0-py3-none-any.whl.metadata (6.8 kB)\n", + " Downloading distro-1.9.0-py3-none-any.whl.metadata (6.8 kB)\n", "Collecting httpx<1,>=0.23.0 (from openai>=2.8.0->azure-ai-projects==2.3.0)\n", - " Using cached httpx-0.28.1-py3-none-any.whl.metadata (7.1 kB)\n", + " Downloading httpx-0.28.1-py3-none-any.whl.metadata (7.1 kB)\n", "Collecting jiter<1,>=0.10.0 (from openai>=2.8.0->azure-ai-projects==2.3.0)\n", - " Using cached jiter-0.16.0-cp312-cp312-win_amd64.whl.metadata (5.3 kB)\n", + " Downloading jiter-0.16.0-cp312-cp312-win_amd64.whl.metadata (5.3 kB)\n", "Collecting pydantic<3,>=1.9.0 (from openai>=2.8.0->azure-ai-projects==2.3.0)\n", - " Using cached pydantic-2.13.4-py3-none-any.whl.metadata (109 kB)\n", + " Downloading pydantic-2.13.4-py3-none-any.whl.metadata (109 kB)\n", "Collecting sniffio (from openai>=2.8.0->azure-ai-projects==2.3.0)\n", - " Using cached sniffio-1.3.1-py3-none-any.whl.metadata (3.9 kB)\n", + " Downloading sniffio-1.3.1-py3-none-any.whl.metadata (3.9 kB)\n", "Collecting tqdm>4 (from openai>=2.8.0->azure-ai-projects==2.3.0)\n", - " Using cached tqdm-4.68.4-py3-none-any.whl.metadata (57 kB)\n", + " Downloading tqdm-4.68.4-py3-none-any.whl.metadata (57 kB)\n", "Collecting idna>=2.8 (from anyio<5,>=3.5.0->openai>=2.8.0->azure-ai-projects==2.3.0)\n", - " Using cached idna-3.18-py3-none-any.whl.metadata (6.1 kB)\n", + " Downloading idna-3.18-py3-none-any.whl.metadata (6.1 kB)\n", "Collecting cffi>=2.0.0 (from cryptography>=2.5->azure-identity>=1.15.0->azure-ai-projects==2.3.0)\n", - " Using cached cffi-2.1.0-cp312-cp312-win_amd64.whl.metadata (2.6 kB)\n", + " Downloading cffi-2.1.0-cp312-cp312-win_amd64.whl.metadata (2.6 kB)\n", "Collecting certifi (from httpx<1,>=0.23.0->openai>=2.8.0->azure-ai-projects==2.3.0)\n", - " Using cached certifi-2026.6.17-py3-none-any.whl.metadata (2.5 kB)\n", + " Downloading certifi-2026.6.17-py3-none-any.whl.metadata (2.5 kB)\n", "Collecting httpcore==1.* (from httpx<1,>=0.23.0->openai>=2.8.0->azure-ai-projects==2.3.0)\n", - " Using cached httpcore-1.0.9-py3-none-any.whl.metadata (21 kB)\n", + " Downloading httpcore-1.0.9-py3-none-any.whl.metadata (21 kB)\n", "Collecting h11>=0.16 (from httpcore==1.*->httpx<1,>=0.23.0->openai>=2.8.0->azure-ai-projects==2.3.0)\n", - " Using cached h11-0.16.0-py3-none-any.whl.metadata (8.3 kB)\n", + " Downloading h11-0.16.0-py3-none-any.whl.metadata (8.3 kB)\n", "Collecting PyJWT<3,>=1.0.0 (from PyJWT[crypto]<3,>=1.0.0->msal>=1.35.1->azure-identity>=1.15.0->azure-ai-projects==2.3.0)\n", - " Using cached pyjwt-2.13.0-py3-none-any.whl.metadata (3.4 kB)\n", + " Downloading pyjwt-2.13.0-py3-none-any.whl.metadata (3.4 kB)\n", "Collecting annotated-types>=0.6.0 (from pydantic<3,>=1.9.0->openai>=2.8.0->azure-ai-projects==2.3.0)\n", - " Using cached annotated_types-0.7.0-py3-none-any.whl.metadata (15 kB)\n", + " Downloading annotated_types-0.7.0-py3-none-any.whl.metadata (15 kB)\n", "Collecting pydantic-core==2.46.4 (from pydantic<3,>=1.9.0->openai>=2.8.0->azure-ai-projects==2.3.0)\n", - " Using cached pydantic_core-2.46.4-cp312-cp312-win_amd64.whl.metadata (6.7 kB)\n", + " Downloading pydantic_core-2.46.4-cp312-cp312-win_amd64.whl.metadata (6.7 kB)\n", "Collecting typing-inspection>=0.4.2 (from pydantic<3,>=1.9.0->openai>=2.8.0->azure-ai-projects==2.3.0)\n", - " Using cached typing_inspection-0.4.2-py3-none-any.whl.metadata (2.6 kB)\n", + " Downloading typing_inspection-0.4.2-py3-none-any.whl.metadata (2.6 kB)\n", "Collecting charset_normalizer<4,>=2 (from requests>=2.21.0->azure-core>=1.37.0->azure-ai-projects==2.3.0)\n", - " Using cached charset_normalizer-3.4.9-cp312-cp312-win_amd64.whl.metadata (42 kB)\n", + " Downloading charset_normalizer-3.4.9-cp312-cp312-win_amd64.whl.metadata (42 kB)\n", "Collecting urllib3<3,>=1.26 (from requests>=2.21.0->azure-core>=1.37.0->azure-ai-projects==2.3.0)\n", - " Using cached urllib3-2.7.0-py3-none-any.whl.metadata (6.9 kB)\n", - "Requirement already satisfied: colorama in c:\\users\\ollisgeorge\\appdata\\roaming\\python\\python312\\site-packages (from tqdm>4->openai>=2.8.0->azure-ai-projects==2.3.0) (0.4.6)\n", + " Downloading urllib3-2.7.0-py3-none-any.whl.metadata (6.9 kB)\n", + "Collecting colorama (from tqdm>4->openai>=2.8.0->azure-ai-projects==2.3.0)\n", + " Downloading colorama-0.4.6-py2.py3-none-any.whl.metadata (17 kB)\n", "Collecting pycparser (from cffi>=2.0.0->cryptography>=2.5->azure-identity>=1.15.0->azure-ai-projects==2.3.0)\n", - " Using cached pycparser-3.0-py3-none-any.whl.metadata (8.2 kB)\n", - "Using cached azure_ai_projects-2.3.0-py3-none-any.whl (349 kB)\n", - "Using cached azure_core-1.41.0-py3-none-any.whl (220 kB)\n", - "Using cached azure_identity-1.25.3-py3-none-any.whl (192 kB)\n", - "Using cached azure_storage_blob-12.30.0-py3-none-any.whl (435 kB)\n", - "Using cached isodate-0.7.2-py3-none-any.whl (22 kB)\n", - "Using cached openai-2.44.0-py3-none-any.whl (1.4 MB)\n", - "Using cached anyio-4.14.1-py3-none-any.whl (124 kB)\n", - "Using cached cryptography-49.0.0-cp311-abi3-win_amd64.whl (3.8 MB)\n", - "Using cached distro-1.9.0-py3-none-any.whl (20 kB)\n", - "Using cached httpx-0.28.1-py3-none-any.whl (73 kB)\n", - "Using cached httpcore-1.0.9-py3-none-any.whl (78 kB)\n", - "Using cached jiter-0.16.0-cp312-cp312-win_amd64.whl (196 kB)\n", - "Using cached msal-1.37.0-py3-none-any.whl (123 kB)\n", - "Using cached msal_extensions-1.3.1-py3-none-any.whl (20 kB)\n", - "Using cached pydantic-2.13.4-py3-none-any.whl (472 kB)\n", - "Using cached pydantic_core-2.46.4-cp312-cp312-win_amd64.whl (2.1 MB)\n", - "Using cached requests-2.34.2-py3-none-any.whl (73 kB)\n", - "Using cached tqdm-4.68.4-py3-none-any.whl (676 kB)\n", - "Using cached sniffio-1.3.1-py3-none-any.whl (10 kB)\n", - "Using cached annotated_types-0.7.0-py3-none-any.whl (13 kB)\n", - "Using cached certifi-2026.6.17-py3-none-any.whl (133 kB)\n", - "Using cached cffi-2.1.0-cp312-cp312-win_amd64.whl (185 kB)\n", - "Using cached charset_normalizer-3.4.9-cp312-cp312-win_amd64.whl (162 kB)\n", - "Using cached idna-3.18-py3-none-any.whl (65 kB)\n", - "Using cached pyjwt-2.13.0-py3-none-any.whl (31 kB)\n", - "Using cached typing_inspection-0.4.2-py3-none-any.whl (14 kB)\n", - "Using cached urllib3-2.7.0-py3-none-any.whl (131 kB)\n", - "Using cached h11-0.16.0-py3-none-any.whl (37 kB)\n", - "Using cached pycparser-3.0-py3-none-any.whl (48 kB)\n", - "Installing collected packages: urllib3, typing-inspection, tqdm, sniffio, PyJWT, pydantic-core, pycparser, jiter, isodate, idna, h11, distro, charset_normalizer, certifi, annotated-types, requests, pydantic, httpcore, cffi, anyio, httpx, cryptography, azure-core, openai, azure-storage-blob, msal, msal-extensions, azure-identity, azure-ai-projects\n", - "Successfully installed PyJWT-2.13.0 annotated-types-0.7.0 anyio-4.14.1 azure-ai-projects-2.3.0 azure-core-1.41.0 azure-identity-1.25.3 azure-storage-blob-12.30.0 certifi-2026.6.17 cffi-2.1.0 charset_normalizer-3.4.9 cryptography-49.0.0 distro-1.9.0 h11-0.16.0 httpcore-1.0.9 httpx-0.28.1 idna-3.18 isodate-0.7.2 jiter-0.16.0 msal-1.37.0 msal-extensions-1.3.1 openai-2.44.0 pycparser-3.0 pydantic-2.13.4 pydantic-core-2.46.4 requests-2.34.2 sniffio-1.3.1 tqdm-4.68.4 typing-inspection-0.4.2 urllib3-2.7.0\n", + " Downloading pycparser-3.0-py3-none-any.whl.metadata (8.2 kB)\n", + "Downloading azure_ai_projects-2.3.0-py3-none-any.whl (349 kB)\n", + "Downloading azure_core-1.41.0-py3-none-any.whl (220 kB)\n", + "Downloading azure_identity-1.25.3-py3-none-any.whl (192 kB)\n", + "Downloading azure_storage_blob-12.30.0-py3-none-any.whl (435 kB)\n", + "Downloading isodate-0.7.2-py3-none-any.whl (22 kB)\n", + "Downloading openai-2.44.0-py3-none-any.whl (1.4 MB)\n", + " ---------------------------------------- 0.0/1.4 MB ? eta -:--:--\n", + " ----------------------- ---------------- 0.8/1.4 MB 4.8 MB/s eta 0:00:01\n", + " ---------------------------------------- 1.4/1.4 MB 3.2 MB/s eta 0:00:00\n", + "Downloading typing_extensions-4.16.0-py3-none-any.whl (45 kB)\n", + "Downloading anyio-4.14.1-py3-none-any.whl (124 kB)\n", + "Downloading cryptography-49.0.0-cp311-abi3-win_amd64.whl (3.8 MB)\n", + " ---------------------------------------- 0.0/3.8 MB ? eta -:--:--\n", + " ------------- -------------------------- 1.3/3.8 MB 6.7 MB/s eta 0:00:01\n", + " --------------------------- ------------ 2.6/3.8 MB 6.3 MB/s eta 0:00:01\n", + " ---------------------------------------- 3.8/3.8 MB 6.3 MB/s eta 0:00:00\n", + "Downloading distro-1.9.0-py3-none-any.whl (20 kB)\n", + "Downloading httpx-0.28.1-py3-none-any.whl (73 kB)\n", + "Downloading httpcore-1.0.9-py3-none-any.whl (78 kB)\n", + "Downloading jiter-0.16.0-cp312-cp312-win_amd64.whl (196 kB)\n", + "Downloading msal-1.37.0-py3-none-any.whl (123 kB)\n", + "Downloading msal_extensions-1.3.1-py3-none-any.whl (20 kB)\n", + "Downloading pydantic-2.13.4-py3-none-any.whl (472 kB)\n", + "Downloading pydantic_core-2.46.4-cp312-cp312-win_amd64.whl (2.1 MB)\n", + " ---------------------------------------- 0.0/2.1 MB ? eta -:--:--\n", + " ------------------------- -------------- 1.3/2.1 MB 6.7 MB/s eta 0:00:01\n", + " ---------------------------------------- 2.1/2.1 MB 6.4 MB/s eta 0:00:00\n", + "Downloading requests-2.34.2-py3-none-any.whl (73 kB)\n", + "Downloading tqdm-4.68.4-py3-none-any.whl (676 kB)\n", + " ---------------------------------------- 0.0/676.6 kB ? eta -:--:--\n", + " ---------------------------------------- 676.6/676.6 kB 3.3 MB/s eta 0:00:00\n", + "Downloading sniffio-1.3.1-py3-none-any.whl (10 kB)\n", + "Downloading annotated_types-0.7.0-py3-none-any.whl (13 kB)\n", + "Downloading certifi-2026.6.17-py3-none-any.whl (133 kB)\n", + "Downloading cffi-2.1.0-cp312-cp312-win_amd64.whl (185 kB)\n", + "Downloading charset_normalizer-3.4.9-cp312-cp312-win_amd64.whl (162 kB)\n", + "Downloading idna-3.18-py3-none-any.whl (65 kB)\n", + "Downloading pyjwt-2.13.0-py3-none-any.whl (31 kB)\n", + "Downloading typing_inspection-0.4.2-py3-none-any.whl (14 kB)\n", + "Downloading urllib3-2.7.0-py3-none-any.whl (131 kB)\n", + "Downloading colorama-0.4.6-py2.py3-none-any.whl (25 kB)\n", + "Downloading h11-0.16.0-py3-none-any.whl (37 kB)\n", + "Downloading pycparser-3.0-py3-none-any.whl (48 kB)\n", + "Installing collected packages: urllib3, typing-extensions, sniffio, PyJWT, pycparser, jiter, isodate, idna, h11, distro, colorama, charset_normalizer, certifi, annotated-types, typing-inspection, tqdm, requests, pydantic-core, httpcore, cffi, anyio, pydantic, httpx, cryptography, azure-core, openai, azure-storage-blob, msal, msal-extensions, azure-identity, azure-ai-projects\n", + " Attempting uninstall: urllib3\n", + " Found existing installation: urllib3 2.7.0\n", + " Uninstalling urllib3-2.7.0:\n", + " Successfully uninstalled urllib3-2.7.0\n", + " Attempting uninstall: typing-extensions\n", + " Found existing installation: typing_extensions 4.16.0\n", + " Uninstalling typing_extensions-4.16.0:\n", + " Successfully uninstalled typing_extensions-4.16.0\n", + " Attempting uninstall: sniffio\n", + " Found existing installation: sniffio 1.3.1\n", + " Uninstalling sniffio-1.3.1:\n", + " Successfully uninstalled sniffio-1.3.1\n", + " Attempting uninstall: PyJWT\n", + " Found existing installation: PyJWT 2.13.0\n", + " Uninstalling PyJWT-2.13.0:\n", + " Successfully uninstalled PyJWT-2.13.0\n", + " Attempting uninstall: pycparser\n", + " Found existing installation: pycparser 3.0\n", + " Uninstalling pycparser-3.0:\n", + " Successfully uninstalled pycparser-3.0\n", + " Attempting uninstall: jiter\n", + " Found existing installation: jiter 0.16.0\n", + " Uninstalling jiter-0.16.0:\n", + " Successfully uninstalled jiter-0.16.0\n", + " Attempting uninstall: isodate\n", + " Found existing installation: isodate 0.7.2\n", + " Uninstalling isodate-0.7.2:\n", + " Successfully uninstalled isodate-0.7.2\n", + " Attempting uninstall: idna\n", + " Found existing installation: idna 3.18\n", + " Uninstalling idna-3.18:\n", + " Successfully uninstalled idna-3.18\n", + " Attempting uninstall: h11\n", + " Found existing installation: h11 0.16.0\n", + " Uninstalling h11-0.16.0:\n", + " Successfully uninstalled h11-0.16.0\n", + " Attempting uninstall: distro\n", + " Found existing installation: distro 1.9.0\n", + " Uninstalling distro-1.9.0:\n", + " Successfully uninstalled distro-1.9.0\n", + " Attempting uninstall: colorama\n", + " Found existing installation: colorama 0.4.6\n", + " Uninstalling colorama-0.4.6:\n", + " Successfully uninstalled colorama-0.4.6\n", "Note: you may need to restart the kernel to use updated packages.\n" ] }, @@ -717,18 +759,16 @@ "name": "stderr", "output_type": "stream", "text": [ - " WARNING: The script tqdm.exe is installed in 'c:\\Users\\ollisgeorge\\AppData\\Local\\Programs\\Python\\Python312-x64\\Scripts' which is not on PATH.\n", - " Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.\n", + "WARNING: Ignoring invalid distribution ~harset-normalizer (c:\\Users\\ollisgeorge\\AppData\\Local\\Programs\\Python\\Python312-x64\\Lib\\site-packages)\n", + "WARNING: Ignoring invalid distribution ~harset-normalizer (c:\\Users\\ollisgeorge\\AppData\\Local\\Programs\\Python\\Python312-x64\\Lib\\site-packages)\n", + "WARNING: Ignoring invalid distribution ~harset-normalizer (c:\\Users\\ollisgeorge\\AppData\\Local\\Programs\\Python\\Python312-x64\\Lib\\site-packages)\n", " WARNING: The script idna.exe is installed in 'c:\\Users\\ollisgeorge\\AppData\\Local\\Programs\\Python\\Python312-x64\\Scripts' which is not on PATH.\n", " Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.\n", " WARNING: The script distro.exe is installed in 'c:\\Users\\ollisgeorge\\AppData\\Local\\Programs\\Python\\Python312-x64\\Scripts' which is not on PATH.\n", " Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.\n", - " WARNING: The script normalizer.exe is installed in 'c:\\Users\\ollisgeorge\\AppData\\Local\\Programs\\Python\\Python312-x64\\Scripts' which is not on PATH.\n", - " Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.\n", - " WARNING: The script cffi-gen-src.exe is installed in 'c:\\Users\\ollisgeorge\\AppData\\Local\\Programs\\Python\\Python312-x64\\Scripts' which is not on PATH.\n", - " Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.\n", - " WARNING: The script httpx.exe is installed in 'c:\\Users\\ollisgeorge\\AppData\\Local\\Programs\\Python\\Python312-x64\\Scripts' which is not on PATH.\n", - " Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.\n", + "ERROR: Could not install packages due to an OSError: [WinError 5] Access is denied: 'c:\\\\Users\\\\ollisgeorge\\\\AppData\\\\Local\\\\Programs\\\\Python\\\\Python312-x64\\\\Lib\\\\site-packages\\\\charset_normalizer\\\\cd.cp312-win_amd64.pyd'\n", + "Consider using the `--user` option or check the permissions.\n", + "\n", "\n", "[notice] A new release of pip is available: 25.0.1 -> 26.1.2\n", "[notice] To update, run: python.exe -m pip install --upgrade pip\n" @@ -736,12 +776,12 @@ } ], "source": [ - "pip install azure-ai-projects==2.3.0" + "pip install azure-ai-projects==2.3.0 --force-reinstall --no-cache-dir" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 22, "id": "89e98ee4", "metadata": {}, "outputs": [ @@ -749,8 +789,9 @@ "name": "stdout", "output_type": "stream", "text": [ - "acrvu4ax6chjqjsk.azurecr.io/strands-agent:1.0.0\n", - "Agent created: strands-1222121, version: 2\n" + "PROJECT_ENDPOINT: https://foundry-agents-xhep4wovroziu.services.ai.azure.com/api/projects/default-foundry-agents\n", + "AGENT_NAME: strands-agent\n", + "Agent created: strands-agent, version: 3, id strands-agent:3, endpomint: agent.version\n" ] } ], @@ -762,28 +803,28 @@ " AgentEndpointProtocol,\n", " ContainerConfiguration,\n", " )\n", - "from azure.identity import DefaultAzureCredential\n", + "from azure.identity import DefaultAzureCredential, AzureCliCredential\n", "\n", "# Placeholder values - update before running\n", - "PROJECT_ENDPOINT = \"https://foundry-agents-vu4ax6chjqjsk.services.ai.azure.com/api/projects/default-foundry-agents\"\n", - "AGENT_NAME = \"strands-1222121\"\n", + "PROJECT_ENDPOINT = \"https://foundry-agents-xhep4wovroziu.services.ai.azure.com/api/projects/default-foundry-agents\"\n", + "AGENT_NAME = \"strands-agent\"\n", "\n", "# APIM inference endpoint for model calls.\n", - "# IMPORTANT: this APIM API must route to backend 'foundry-models'.\n", - "# Backend 'foundry-agents' is for hosted agent Responses API/proxy only.\n", - "AZURE_OPENAI_ENDPOINT = \"https://apim-vu4ax6chjqjsk.azure-api.net/inference/models\"\n", + "AZURE_OPENAI_ENDPOINT = \"https://apim-xhep4wovroziu.azure-api.net/inference/models\"\n", "AZURE_OPENAI_API_VERSION = \"2024-05-01-preview\"\n", "AZURE_OPENAI_DEPLOYMENT = \"gpt-5-mini\"\n", - "APIM_SUBSCRIPTION_KEY = \"da1b83bcbd6e45f4b94501061e298591\"\n", + "APIM_SUBSCRIPTION_KEY = \"0ff2e5d4b7144ee7aa009eadbee3bc21\"\n", "\n", - "print(IMAGE_URI)\n", + "print(f\"PROJECT_ENDPOINT: {PROJECT_ENDPOINT}\")\n", + "print(f\"AGENT_NAME: {AGENT_NAME}\")\n", + "\n", + "credential = AzureCliCredential()\n", "\n", - "credential = DefaultAzureCredential()\n", "project = AIProjectClient(\n", " endpoint=PROJECT_ENDPOINT,\n", " credential=credential,\n", " allow_preview=True,\n", - " )\n", + ")\n", "\n", "agent = project.agents.create_version(\n", " agent_name=AGENT_NAME,\n", @@ -805,7 +846,277 @@ " ),\n", " )\n", "\n", - "print(f\"Agent created: {agent.name}, version: {agent.version}\")" + "print(f\"Agent created: {agent.name}, version: {agent.version}, id {agent.id}\")" + ] + }, + { + "cell_type": "markdown", + "id": "faaf591d", + "metadata": {}, + "source": [ + "## 4. Test The Hosted Agent\n", + "\n", + "Sends a request directly to the Foundry Hosted Agent Responses API using a bearer token from your CLI credential." + ] + }, + { + "cell_type": "markdown", + "id": "3ba0fe43", + "metadata": {}, + "source": [ + "## 3. Check Agent Status\n", + "\n", + "Wait for the hosted agent to transition to \"Running\" state before calling it." + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "93be92da", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "POST https://foundry-agents-xhep4wovroziu.services.ai.azure.com/api/projects/default-foundry-agents/agents/strands-agent/endpoint/protocols/openai/responses?api-version=v1\n", + "Agent Name: strands-agent\n", + "Payload: {\n", + " \"input\": \"Hello! What can you help me with? What's the weather in Paris today?\",\n", + " \"stream\": false\n", + "}\n", + "\n", + "Status: 200\n", + "Headers: {'Content-Length': '1187', 'Content-Type': 'application/json', 'content-encoding': 'identity', 'request-context': 'appId=', 'x-ms-response-type': 'standard', 'x-request-id': '9db970915a015177e285d2d9b66cc93f,9db970915a015177e285d2d9b66cc93f', 'api-supported-versions': '1.0,2025-05-15-preview,2025-11-15-preview', 'x-agent-session-id': '23d1816e1019ada17936cbd434b60fc35826f3aac5359d1f36b9b041185497b', 'x-platform-server': 'azure-ai-agentserver-core/2.0.0b7 (python/3.12) azure-ai-agentserver-responses/1.0.0b8 (python/3.12)', 'azureml-served-by-cluster': 'hyena-swedencentral-02', 'apim-request-id': '1f0cbb12-52b6-43f6-a7a4-d57e28ee72a9', 'Strict-Transport-Security': 'max-age=31536000; includeSubDomains; preload', 'x-content-type-options': 'nosniff', 'x-ms-region': 'Sweden Central', 'Access-Control-Expose-Headers': 'Operation-Location,Location,Apim-Request-Id,x-agent-session-id,x-agent-invocation-id', 'Date': 'Wed, 08 Jul 2026 18:12:32 GMT'}\n", + "Response text (first 500 chars): {\"id\":\"caresp_e0231748c6fea86400dfbs4B5CHUWPzROuuiXS2O9TpGS2YYpM\",\"object\":\"response\",\"output\":[{\"type\":\"message\",\"id\":\"msg_e0231748c6fea86400qh5yTL1cyHak7ylRDo9iUzaGlDLJ6tHq\",\"role\":\"assistant\",\"content\":[{\"type\":\"output_text\",\"text\":\"Hi — I can help with facts and explanations, summarize or rewrite text, brainstorm and plan, solve math and coding problems, translate, and more. Ask me to dive deeper into any of those.\\n\\nCurrent weather in Paris: -2 °C (about 28.4 °F). That’s below freezing — d\n", + "\n", + "Response JSON:\n", + "{\n", + " \"id\": \"caresp_e0231748c6fea86400dfbs4B5CHUWPzROuuiXS2O9TpGS2YYpM\",\n", + " \"object\": \"response\",\n", + " \"output\": [\n", + " {\n", + " \"type\": \"message\",\n", + " \"id\": \"msg_e0231748c6fea86400qh5yTL1cyHak7ylRDo9iUzaGlDLJ6tHq\",\n", + " \"role\": \"assistant\",\n", + " \"content\": [\n", + " {\n", + " \"type\": \"output_text\",\n", + " \"text\": \"Hi \\u2014 I can help with facts and explanations, summarize or rewrite text, brainstorm and plan, solve math and coding problems, translate, and more. Ask me to dive deeper into any of those.\\n\\nCurrent weather in Paris: -2 \\u00b0C (about 28.4 \\u00b0F). That\\u2019s below freezing \\u2014 dress warmly and watch for icy spots. Would you like a forecast for today, an hourly breakdown, or weather for another city?\",\n", + " \"annotations\": [],\n", + " \"logprobs\": []\n", + " }\n", + " ],\n", + " \"status\": \"completed\",\n", + " \"response_id\": \"caresp_e0231748c6fea86400dfbs4B5CHUWPzROuuiXS2O9TpGS2YYpM\",\n", + " \"agent_reference\": {\n", + " \"type\": \"agent_reference\",\n", + " \"name\": \"strands-agent\",\n", + " \"version\": \"3\"\n", + " }\n", + " }\n", + " ],\n", + " \"created_at\": 1783534347,\n", + " \"agent_reference\": {\n", + " \"type\": \"agent_reference\",\n", + " \"name\": \"strands-agent\",\n", + " \"version\": \"3\"\n", + " },\n", + " \"status\": \"completed\",\n", + " \"completed_at\": 1783534352,\n", + " \"response_id\": \"caresp_e0231748c6fea86400dfbs4B5CHUWPzROuuiXS2O9TpGS2YYpM\",\n", + " \"model\": \"\",\n", + " \"agent_session_id\": \"23d1816e1019ada17936cbd434b60fc35826f3aac5359d1f36b9b041185497b\",\n", + " \"background\": false\n", + "}\n" + ] + } + ], + "source": [ + "import json\n", + "import requests\n", + "from azure.core.credentials import AccessToken\n", + "\n", + "# Correct endpoint for Responses protocol (per Microsoft Learn)\n", + "API_VERSION = \"v1\"\n", + "\n", + "# Build the correct URL: use agent name only (not name:version)\n", + "url = f\"{PROJECT_ENDPOINT}/agents/{AGENT_NAME}/endpoint/protocols/openai/responses\"\n", + "\n", + "# Get a token for Foundry Responses API\n", + "token: AccessToken = credential.get_token(\"https://ai.azure.com/.default\")\n", + "\n", + "headers = {\n", + " \"Authorization\": f\"Bearer {token.token}\",\n", + " \"Content-Type\": \"application/json\",\n", + " \"Foundry-Features\": \"HostedAgents=V1Preview\", # Required for preview\n", + "}\n", + "\n", + "payload = {\n", + " \"input\": \"Hello! What can you help me with? What's the weather in Paris today?\",\n", + " \"stream\": False,\n", + "}\n", + "\n", + "print(f\"POST {url}?api-version={API_VERSION}\")\n", + "print(f\"Agent Name: {AGENT_NAME}\")\n", + "print(f\"Payload: {json.dumps(payload, indent=2)}\")\n", + "print()\n", + "\n", + "response = requests.post(url, headers=headers, json=payload, params={\"api-version\": API_VERSION})\n", + "print(f\"Status: {response.status_code}\")\n", + "print(f\"Headers: {dict(response.headers)}\")\n", + "print(f\"Response text (first 500 chars): {response.text[:500]}\")\n", + "print()\n", + "\n", + "if response.status_code == 200:\n", + " try:\n", + " result = response.json()\n", + " print(f\"Response JSON:\")\n", + " print(json.dumps(result, indent=2))\n", + " if \"output_text\" in result:\n", + " print(f\"\\nAgent output:\\n{result['output_text']}\")\n", + " except json.JSONDecodeError as e:\n", + " print(f\"Failed to parse JSON: {e}\")\n", + " print(f\"Raw response: {response.text}\")\n", + "else:\n", + " print(f\"Error: {response.status_code}\")\n", + " if response.text:\n", + " try:\n", + " print(json.dumps(response.json(), indent=2))\n", + " except:\n", + " print(response.text)" + ] + }, + { + "cell_type": "markdown", + "id": "cc246a06", + "metadata": {}, + "source": [ + "## 5. Test Through APIM (After Deployment)\n", + "\n", + "Once you've deployed the agent and configured APIM (via the main deployment notebook with `enable_hosted_agent_responses_api=True`), call the agent through APIM instead of directly.\n", + "This ensures the full production path works: client → APIM → Foundry Agent → container." + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "id": "aa0daead", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "POST https://apim-xhep4wovroziu.azure-api.net/hosted-agent-responses/endpoint/protocols/openai/responses?api-version=v1\n", + "Agent ID: strands-agent:3\n", + "Headers (excluding key): Content-Type, api-key\n", + "Payload: {\n", + " \"input\": \"Hello from APIM!\",\n", + " \"stream\": false\n", + "}\n", + "\n", + "Status: 403\n", + "Response headers (first 500 chars): {'Content-Length': '0', 'Date': 'Wed, 08 Jul 2026 18:13:38 GMT', 'Access-Control-Expose-Headers': 'Operation-Location,Location,Apim-Request-Id,x-agent-session-id,x-agent-invocation-id', 'Strict-Transport-Security': 'max-age=31536000; includeSubDomains; preload', 'request-context': 'appId=', 'x-ms-response-type': 'standard', 'azureml-served-by-cluster': 'hyena-swedencentral-01', 'apim-request-id': 'dd903f53-4eb6-4e34-b801-f49056f454c4', 'X-Content-Type-Options': 'nosniff', 'x-ms-region': 'Sweden \n", + "\n", + "✗ Error: 403\n" + ] + } + ], + "source": [ + "# After deploying the hosted agent and re-running the main deployment notebook,\n", + "# call the agent through APIM instead of directly.\n", + "#\n", + "# Values from main deployment:\n", + "# - APIM_GATEWAY_URL: from deployment outputs (e.g., https://apim-.azure-api.net)\n", + "# - APIM_SUBSCRIPTION_KEY: from the 'starter' subscription created in deployment\n", + "# - HOSTED_AGENT_ID: the agent ID from agent creation (e.g., \"strands-agent:3\")\n", + "\n", + "# Update these values from the deployment outputs\n", + "APIM_GATEWAY_URL = \"https://apim-xhep4wovroziu.azure-api.net\" # From deployment output\n", + "HOSTED_AGENT_RESPONSES_PATH = \"hosted-agent-responses\" # From main.bicep parameter\n", + "APIM_SUBSCRIPTION_KEY = \"0ff2e5d4b7144ee7aa009eadbee3bc21\" # From deployment (APIM subscription key, not APIM Key)\n", + "HOSTED_AGENT_ID = \"strands-agent:3\" # Set this to your deployed agent ID from cell 7\n", + "\n", + "# Build APIM URL: path/endpoint/protocols/openai/responses\n", + "# The /endpoint/protocols/openai/responses portion is appended to the Foundry agent endpoint by APIM operation\n", + "apim_url = f\"{APIM_GATEWAY_URL}/{HOSTED_AGENT_RESPONSES_PATH}/endpoint/protocols/openai/responses\"\n", + "\n", + "headers = {\n", + " \"Content-Type\": \"application/json\",\n", + " \"api-key\": APIM_SUBSCRIPTION_KEY, # APIM subscription key for access control\n", + "}\n", + "\n", + "payload = {\n", + " \"input\": \"Hello from APIM!\",\n", + " \"stream\": False,\n", + "}\n", + "\n", + "print(f\"POST {apim_url}?api-version=v1\")\n", + "print(f\"Agent ID: {HOSTED_AGENT_ID}\")\n", + "print(f\"Headers (excluding key): Content-Type, api-key\")\n", + "print(f\"Payload: {json.dumps(payload, indent=2)}\")\n", + "print()\n", + "\n", + "response = requests.post(apim_url, headers=headers, json=payload, params={\"api-version\": \"v1\"})\n", + "print(f\"Status: {response.status_code}\")\n", + "print(f\"Response headers (first 500 chars): {str(dict(response.headers))[:500]}\")\n", + "print()\n", + "\n", + "if response.status_code == 200:\n", + " try:\n", + " result = response.json()\n", + " print(f\"Response JSON:\")\n", + " print(json.dumps(result, indent=2))\n", + " if \"output_text\" in result:\n", + " print(f\"\\n✓ Agent response via APIM:\\n{result['output_text']}\")\n", + " except json.JSONDecodeError as e:\n", + " print(f\"Failed to parse JSON: {e}\")\n", + " print(f\"Raw response: {response.text}\")\n", + "else:\n", + " print(f\"✗ Error: {response.status_code}\")\n", + " if response.text:\n", + " try:\n", + " print(json.dumps(response.json(), indent=2))\n", + " except:\n", + " print(response.text)" + ] + }, + { + "cell_type": "markdown", + "id": "5927b8ad", + "metadata": {}, + "source": [ + "## APIM Configuration Checklist\n", + "\n", + "When the main deployment notebook runs with `enable_hosted_agent_responses_api=True` and a valid `hosted_agent_id`, APIM should be configured as follows:\n", + "\n", + "**API: `hosted-agent-responses-api`**\n", + "- Path: `hosted-agent-responses` (configurable via `hostedAgentResponsesApiPath`)\n", + "- Backend: `{foundry-agents-account}/agents/{hostedAgentId}` (direct Foundry endpoint)\n", + "\n", + "**Operation: `create-response`**\n", + "- Method: `POST`\n", + "- URL template: `/endpoint/protocols/openai/responses`\n", + "- Full path when called: `/hosted-agent-responses/endpoint/protocols/openai/responses`\n", + "\n", + "**Policy (inbound):**\n", + "- ✓ Authenticate using **managed identity** (audience: `https://cognitiveservices.azure.com`) — APIM calls Foundry with its identity\n", + "- ✓ Set `Authorization` header to bearer token from managed identity\n", + "- ✓ Set `api-version` query parameter to `2025-05-15-preview` (the Foundry Hosted Agent API version)\n", + "\n", + "**Authentication for client → APIM:**\n", + "- Subscription key required (`api-key` header or `?api-key=` query param)\n", + "- Subscription: `starter` (created by deployment)\n", + "\n", + "**Full request flow:**\n", + "1. Client calls: `POST https://apim-xyz.azure-api.net/hosted-agent-responses/endpoint/protocols/openai/responses?api-version=v1`\n", + "2. Client provides: `api-key: ` (from APIM subscription)\n", + "3. APIM validates subscription → extracts managed identity token\n", + "4. APIM calls Foundry: `POST https://foundry-agents-xyz.../api/projects/.../agents/{agentId}/endpoint/protocols/openai/responses?api-version=2025-05-15-preview`\n", + "5. APIM provides: `Authorization: Bearer ` (managed identity token with `https://cognitiveservices.azure.com` audience)\n", + "\n", + "If the deployment succeeded and the agent is running, the next cell will verify the APIM configuration is working." ] } ], From db20653aaeae52afa2cdf7642e47a65be5051462 Mon Sep 17 00:00:00 2001 From: George Ollis Date: Wed, 8 Jul 2026 20:23:12 +0100 Subject: [PATCH 03/17] Add hosted agent policy for Foundry Responses API integration - Introduced a new XML policy file to manage inbound requests for the Foundry Responses API. - Implemented managed identity authentication to retrieve access tokens. - Set necessary headers including Authorization, Content-Type, and Foundry-Features for API requests. - Added a query parameter for API versioning to ensure compatibility with the preview version. --- .../README.md | 102 +- ...undry-hosted-agents-custom-framework.ipynb | 786 +------------ .../hosted-agent-policy.xml | 36 + .../main.bicep | 30 +- .../01_hosted_agent_strands_setup.ipynb | 1024 +++-------------- 5 files changed, 324 insertions(+), 1654 deletions(-) create mode 100644 labs/ai-foundry-hosted-agents-custom-framework/hosted-agent-policy.xml diff --git a/labs/ai-foundry-hosted-agents-custom-framework/README.md b/labs/ai-foundry-hosted-agents-custom-framework/README.md index 712e528c..379f0977 100644 --- a/labs/ai-foundry-hosted-agents-custom-framework/README.md +++ b/labs/ai-foundry-hosted-agents-custom-framework/README.md @@ -50,19 +50,34 @@ Agents are managed as platform assets in the Foundry control plane, with operati ## [Infrastructure deployment notebook](ai-foundry-hosted-agents-custom-framework.ipynb) -Use this notebook first to deploy core infrastructure with Bicep: +Use this notebook first to deploy core infrastructure with Bicep. -- Azure API Management (APIM) -- Microsoft Foundry (two foundry resources: models + hosted agents) -- GPT-5-Mini model deployment -- Azure Container Registry (ACR) for hosted agent images +### What gets deployed -The deployment also configures: +**Core Services:** +- Azure API Management (APIM) - Acts as the gateway and reverse proxy +- Microsoft Foundry (two separate AI Services resources): + - **foundry-models**: Hosts inference models (GPT-5-Mini) for your agents to use + - **foundry-agents**: Hosts your custom framework agent runtimes via Hosted Agents Responses protocol v1.0.0 +- Azure Container Registry (ACR) - Stores your agent container images +- Application Insights & Log Analytics - Provides observability and diagnostics -- ACR repository permissions for the hosted-agent Foundry resource and its project identity (`Container Registry Repository Reader`) +**RBAC & Access Control:** +- ACR repository permissions for the hosted-agent Foundry resource (`Container Registry Repository Reader` + `AcrPull`) - ACR repository permissions for the deploying user (`Container Registry Repository Writer` + `Container Registry Repository Catalog Lister`) -- Foundry User role assignments (`Foundry User`) for configured user object IDs across all Foundry resources deployed by this lab -- Optional APIM proxy API for the Hosted Agent Responses endpoint, added after the hosted agent has been deployed and is running +- Foundry User role assignments (`Foundry User`) for configured user object IDs across all Foundry resources + +**APIM Proxy Configuration** (optional, added when `enableHostedAgentResponsesApi=true`): +- Dedicated API endpoint proxying your hosted agent's Responses API +- Managed identity token injection (Foundry authentication) +- Automatic header injection: + - `Content-Type: application/json` + - `Foundry-Features: HostedAgents=V1Preview` (required for preview access) +- Automatic query parameter enforcement: + - `api-version: 2025-05-15-preview` +- Uses APIM subscription key for client authentication (cleaner than managing bearer tokens on client side) + +Policy definition is in [hosted-agent-policy.xml](hosted-agent-policy.xml) for easy customization. The deployment template is in [main.bicep](main.bicep). @@ -75,20 +90,75 @@ The deployment template is in [main.bicep](main.bicep). - [Python 3.12 or later version](https://www.python.org/) installed - [VS Code](https://code.visualstudio.com/) installed with the [Jupyter notebook extension](https://marketplace.visualstudio.com/items?itemName=ms-toolsai.jupyter) enabled -- [uv](https://docs.astral.sh/uv/) - run `uv sync` from the repo root to install dependencies +- Python dependencies: Install via `pip install azure-ai-projects azure-identity requests` (or run the dependency cell in each notebook) - [An Azure Subscription](https://azure.microsoft.com/free/) with [Contributor](https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles/privileged#contributor) + [RBAC Administrator](https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles/privileged#role-based-access-control-administrator) or [Owner](https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles/privileged#owner) roles - [Azure CLI](https://learn.microsoft.com/cli/azure/install-azure-cli) installed and [signed into your Azure subscription](https://learn.microsoft.com/cli/azure/authenticate-azure-cli-interactively) - [Docker](https://www.docker.com/get-started/) installed and running (for building container images) ### Get started -1. Run the [infrastructure deployment notebook](ai-foundry-hosted-agents-custom-framework.ipynb). -2. Choose one of the sample frameworks above. -3. Open its setup notebook and run all steps. -4. Build and push the container image to your Azure Container Registry. -5. Deploy the hosted agent version in your Foundry project. -6. Set the hosted agent ID in the infra notebook config and re-run deployment to provision APIM fronting for the Responses API. +**Step 1: Deploy Infrastructure** +- Run all cells in [ai-foundry-hosted-agents-custom-framework.ipynb](ai-foundry-hosted-agents-custom-framework.ipynb) +- This creates your Foundry resources, APIM, ACR, and monitoring infrastructure +- Note the outputs (Foundry endpoints, ACR login server, APIM URL) for the next steps + +**Step 2: Choose & Deploy Your Agent** +- Pick one of the sample frameworks: [Pydantic AI](src/responses/agents/pydantic-ai/README.md) or [Strands](src/responses/agents/strands/README.md) +- Open the corresponding setup notebook and run all cells: + 1. Build the Docker container image for your agent framework + 2. Push the image to ACR + 3. Create a hosted agent version in your Foundry project + 4. Test the agent directly via Foundry's Responses API (baseline validation) + 5. Test the agent via APIM (validates the proxy gateway) + +**Step 3: Enable APIM Proxy (Optional but Recommended)** +- Once your agent is deployed and running, go back to [ai-foundry-hosted-agents-custom-framework.ipynb](ai-foundry-hosted-agents-custom-framework.ipynb) +- Set `hosted_agent_id` in the config to your agent name (e.g., `'strands-agent:1'`) and re-run the deployment +- This provisions the APIM API proxy with automatic header/query-param injection + +### Test Flow Explained + +Each sample notebook includes three test scenarios: + +1. **Direct Foundry Test** (Section 3) + - Calls the Foundry Hosted Agent Responses API directly + - Uses your Azure CLI credential (bearer token with `https://ai.azure.com/.default` audience) + - Validates the agent runtime and basic connectivity + - No APIM involvement—good baseline for troubleshooting + +2. **APIM Test** (Section 4) + - Routes through APIM gateway using subscription key (`api-key` header) + - APIM injects managed identity token to Foundry automatically + - APIM enforces `Content-Type`, `Foundry-Features`, and `api-version` headers + - Tests the full production-like path (client → APIM → Foundry agent) ### Clean up resources Use the [clean-up-resources notebook](clean-up-resources.ipynb) to remove deployed resources when you are finished. + +### Troubleshooting + +**Section 3 (Direct Test) fails:** +- Check agent status in Foundry—should be "Running" +- Verify you're logged into Azure CLI (`az login`) +- Confirm the `PROJECT_ENDPOINT` is correct from the infrastructure deployment +- Check network connectivity (firewall, proxy) + +**Section 4 (APIM Test) fails but Section 3 succeeds:** +- Verify `APIM_SUFFIX` matches your APIM instance name +- Confirm `APIM_SUBSCRIPTION_KEY` is correct +- Check APIM policy in `hosted-agent-policy.xml`—ensure token audience is `https://ai.azure.com` +- Use APIM's TRACE tool to debug the request flow: + - In Azure Portal → APIM → Diagnose and solve problems → Trace + - Re-run your test and examine the detailed trace output + - Look for authentication errors, backend routing issues, or header mismatches + +**Agent container fails to start:** +- Check ACR permissions—Foundry resource identity needs `AcrPull` role +- Verify the container image URI in Foundry matches what you pushed to ACR +- Check logs via Foundry's diagnostics or Application Insights + +**For more help:** +- Review the [APIM policy file](hosted-agent-policy.xml) to understand header/parameter enforcement +- Check [Bicep template](main.bicep) for resource configuration details +- Consult [Microsoft Foundry documentation](https://learn.microsoft.com/en-us/foundry/) diff --git a/labs/ai-foundry-hosted-agents-custom-framework/ai-foundry-hosted-agents-custom-framework.ipynb b/labs/ai-foundry-hosted-agents-custom-framework/ai-foundry-hosted-agents-custom-framework.ipynb index be885a14..8c51078d 100644 --- a/labs/ai-foundry-hosted-agents-custom-framework/ai-foundry-hosted-agents-custom-framework.ipynb +++ b/labs/ai-foundry-hosted-agents-custom-framework/ai-foundry-hosted-agents-custom-framework.ipynb @@ -47,18 +47,10 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "id": "99068750", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Lab directory: c:\\GitHub\\ai-gateway\\AI-Gateway\\labs\\ai-foundry-hosted-agents-custom-framework\n" - ] - } - ], + "outputs": [], "source": [ "import json\n", "import os\n", @@ -85,21 +77,13 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "id": "1c47a2ce", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Configuration ready. Set real values before running deployment.\n" - ] - } - ], + "outputs": [], "source": [ "# Update these values as needed\n", - "subscription_id = '9be21359-7b5a-4ccd-b0c7-24c97acd7d0c'\n", + "subscription_id = 'XXXX'\n", "resource_group = 'rg-aigw-hosted-custom-framework'\n", "location = 'swedencentral'\n", "deployment_name = 'deploy-hosted-custom-framework'\n", @@ -143,36 +127,24 @@ " }\n", "]\n", "\n", - "# Deploy the hosted agent first. After it is running, set these values and rerun\n", - "# this notebook to add the APIM proxy in front of the Hosted Agent Responses API.\n", + "# Deploy Foundry infrastructure and APIM with hosted agent responses API support.\n", + "# The hosted agent ID should match what you will deploy in the Strands notebook.\n", + "# Format: \"agent-name:version\" (version is auto-assigned by Foundry)\n", + "# For now, use a placeholder that will be updated after you see the actual agent version\n", "enable_hosted_agent_responses_api = True\n", - "hosted_agent_id = 'strands-agent:3' # set to your deployed hosted agent id to enable APIM proxy\n", + "hosted_agent_id = 'strands-agent:1' # Update this after deploying the agent in Strands notebook, then redeploy\n", "\n", - "print('Configuration ready. Set real values before running deployment.')" + "print('Configuration ready. Set real values before running deployment.')\n", + "print(f'Note: hosted_agent_id is set to \"{hosted_agent_id}\". After deploying in the Strands notebook,')\n", + "print('update this to the actual agent version (e.g., \"strands-agent:3\") and redeploy to finalize APIM routing.')" ] }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "id": "91b2888b", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "$ cmd /c C:\\Program Files\\Microsoft SDKs\\Azure\\CLI2\\wbin\\az.cmd ad signed-in-user show --query id -o tsv\n", - "13f94c0d-8a51-492a-928b-59392c23c1ac\n", - "\n", - "Foundry user object IDs:\n", - "[\n", - " \"13f94c0d-8a51-492a-928b-59392c23c1ac\"\n", - "]\n", - "Saved to: c:\\GitHub\\ai-gateway\\AI-Gateway\\labs\\ai-foundry-hosted-agents-custom-framework\\foundry-user-object-ids.json\n" - ] - } - ], + "outputs": [], "source": [ "from pathlib import Path\n", "import json\n", @@ -215,702 +187,10 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "id": "3c1be18b", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "$ cmd /c C:\\Program Files\\Microsoft SDKs\\Azure\\CLI2\\wbin\\az.cmd account set --subscription 9be21359-7b5a-4ccd-b0c7-24c97acd7d0c\n", - "\n", - "$ cmd /c C:\\Program Files\\Microsoft SDKs\\Azure\\CLI2\\wbin\\az.cmd group create --name rg-aigw-hosted-custom-framework --location swedencentral\n", - "{\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework\",\n", - " \"location\": \"swedencentral\",\n", - " \"managedBy\": null,\n", - " \"name\": \"rg-aigw-hosted-custom-framework\",\n", - " \"properties\": {\n", - " \"provisioningState\": \"Succeeded\"\n", - " },\n", - " \"tags\": null,\n", - " \"type\": \"Microsoft.Resources/resourceGroups\"\n", - "}\n", - "\n", - "Wrote parameters: c:\\GitHub\\ai-gateway\\AI-Gateway\\labs\\ai-foundry-hosted-agents-custom-framework\\main.parameters.generated.json\n", - "\n", - "$ cmd /c C:\\Program Files\\Microsoft SDKs\\Azure\\CLI2\\wbin\\az.cmd bicep install\n", - "Bicep CLI is already installed at 'C:\\Users\\ollisgeorge\\.azure\\bin\\bicep.exe'. Skipping installation as no specific version was requested.\n", - "\n", - "\n", - "$ cmd /c C:\\Program Files\\Microsoft SDKs\\Azure\\CLI2\\wbin\\az.cmd deployment group validate --resource-group rg-aigw-hosted-custom-framework --template-file C:\\GitHub\\ai-gateway\\AI-Gateway\\labs\\ai-foundry-hosted-agents-custom-framework\\main.bicep --parameters @C:\\GitHub\\ai-gateway\\AI-Gateway\\labs\\ai-foundry-hosted-agents-custom-framework\\main.parameters.generated.json --only-show-errors\n", - "{\n", - " \"error\": null,\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/main\",\n", - " \"name\": \"main\",\n", - " \"properties\": {\n", - " \"correlationId\": \"8474ac3c-4c54-4861-bfd3-f9816f7a13f2\",\n", - " \"debugSetting\": null,\n", - " \"dependencies\": [\n", - " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrxhep4wovroziu\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"acrxhep4wovroziu\",\n", - " \"resourceType\": \"Microsoft.ContainerRegistry/registries\"\n", - " },\n", - " {\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/foundryModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"foundryModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrxhep4wovroziu/providers/Microsoft.Authorization/roleAssignments/9fdae2e2-758a-52c5-a9f4-bbe68deee382\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"9fdae2e2-758a-52c5-a9f4-bbe68deee382\",\n", - " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", - " },\n", - " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrxhep4wovroziu\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"acrxhep4wovroziu\",\n", - " \"resourceType\": \"Microsoft.ContainerRegistry/registries\"\n", - " },\n", - " {\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/foundryModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"foundryModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrxhep4wovroziu/providers/Microsoft.Authorization/roleAssignments/d978b2df-d75d-526b-9743-60720d2c081c\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"d978b2df-d75d-526b-9743-60720d2c081c\",\n", - " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", - " },\n", - " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrxhep4wovroziu\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"acrxhep4wovroziu\",\n", - " \"resourceType\": \"Microsoft.ContainerRegistry/registries\"\n", - " },\n", - " {\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/foundryModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"foundryModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrxhep4wovroziu/providers/Microsoft.Authorization/roleAssignments/63983143-77d9-582c-b53c-793fefd1bd93\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"63983143-77d9-582c-b53c-793fefd1bd93\",\n", - " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", - " },\n", - " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrxhep4wovroziu\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"acrxhep4wovroziu\",\n", - " \"resourceType\": \"Microsoft.ContainerRegistry/registries\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrxhep4wovroziu/providers/Microsoft.Authorization/roleAssignments/b0406c01-b2e5-5a38-8735-416921bc283e\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"b0406c01-b2e5-5a38-8735-416921bc283e\",\n", - " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", - " },\n", - " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrxhep4wovroziu\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"acrxhep4wovroziu\",\n", - " \"resourceType\": \"Microsoft.ContainerRegistry/registries\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrxhep4wovroziu/providers/Microsoft.Authorization/roleAssignments/c3a8ec22-2dde-50ce-a21a-2adcc18a175f\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"c3a8ec22-2dde-50ce-a21a-2adcc18a175f\",\n", - " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", - " },\n", - " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/apimModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"apimModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " },\n", - " {\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/foundryModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"foundryModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ApiManagement/service/apim-xhep4wovroziu/apis/hosted-agent-responses-api\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"apim-xhep4wovroziu/hosted-agent-responses-api\",\n", - " \"resourceType\": \"Microsoft.ApiManagement/service/apis\"\n", - " },\n", - " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ApiManagement/service/apim-xhep4wovroziu/apis/hosted-agent-responses-api\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"apim-xhep4wovroziu/hosted-agent-responses-api\",\n", - " \"resourceType\": \"Microsoft.ApiManagement/service/apis\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ApiManagement/service/apim-xhep4wovroziu/apis/hosted-agent-responses-api/operations/create-response\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"apim-xhep4wovroziu/hosted-agent-responses-api/create-response\",\n", - " \"resourceType\": \"Microsoft.ApiManagement/service/apis/operations\"\n", - " },\n", - " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ApiManagement/service/apim-xhep4wovroziu/apis/hosted-agent-responses-api\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"apim-xhep4wovroziu/hosted-agent-responses-api\",\n", - " \"resourceType\": \"Microsoft.ApiManagement/service/apis\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ApiManagement/service/apim-xhep4wovroziu/apis/hosted-agent-responses-api/policies/policy\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"apim-xhep4wovroziu/hosted-agent-responses-api/policy\",\n", - " \"resourceType\": \"Microsoft.ApiManagement/service/apis/policies\"\n", - " },\n", - " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/lawModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"lawModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/appInsightsModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"appInsightsModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " },\n", - " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/appInsightsModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"appInsightsModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " },\n", - " {\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/lawModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"lawModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/apimModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"apimModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " },\n", - " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/apimModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"apimModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " },\n", - " {\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/appInsightsModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"appInsightsModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/foundryModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"foundryModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " },\n", - " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/apimModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"apimModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " },\n", - " {\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/appInsightsModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"appInsightsModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " },\n", - " {\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/foundryModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"foundryModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/inferenceAPIModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"inferenceAPIModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " },\n", - " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/foundryModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"foundryModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.CognitiveServices/accounts/foundry-models-xhep4wovroziu/providers/Microsoft.Authorization/roleAssignments/dc422f45-552b-5b34-9880-e664b7afe0aa\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"dc422f45-552b-5b34-9880-e664b7afe0aa\",\n", - " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", - " },\n", - " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/foundryModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"foundryModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.CognitiveServices/accounts/foundry-agents-xhep4wovroziu/providers/Microsoft.Authorization/roleAssignments/c4d31936-032e-5bdb-b9d3-a12891127593\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceName\": \"c4d31936-032e-5bdb-b9d3-a12891127593\",\n", - " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", - " }\n", - " ],\n", - " \"diagnostics\": [\n", - " {\n", - " \"additionalInfo\": null,\n", - " \"code\": \"NestedDeploymentShortCircuited\",\n", - " \"level\": \"Warning\",\n", - " \"message\": \"A nested deployment got short-circuited and all its resources got skipped from validation. This is due to a nested template having a parameter that was not fully evaluated (e.g. contains a reference() function). Please see https://aka.ms/WhatIfEvalStopped for more guidance.\",\n", - " \"target\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/appInsightsModule\"\n", - " },\n", - " {\n", - " \"additionalInfo\": null,\n", - " \"code\": \"NestedDeploymentShortCircuited\",\n", - " \"level\": \"Warning\",\n", - " \"message\": \"A nested deployment got short-circuited and all its resources got skipped from validation. This is due to a nested template having a parameter that was not fully evaluated (e.g. contains a reference() function). Please see https://aka.ms/WhatIfEvalStopped for more guidance.\",\n", - " \"target\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/apimModule\"\n", - " },\n", - " {\n", - " \"additionalInfo\": null,\n", - " \"code\": \"NestedDeploymentShortCircuited\",\n", - " \"level\": \"Warning\",\n", - " \"message\": \"A nested deployment got short-circuited and all its resources got skipped from validation. This is due to a nested template having a parameter that was not fully evaluated (e.g. contains a reference() function). Please see https://aka.ms/WhatIfEvalStopped for more guidance.\",\n", - " \"target\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/foundryModule\"\n", - " },\n", - " {\n", - " \"additionalInfo\": null,\n", - " \"code\": \"NestedDeploymentShortCircuited\",\n", - " \"level\": \"Warning\",\n", - " \"message\": \"A nested deployment got short-circuited and all its resources got skipped from validation. This is due to a nested template having a parameter that was not fully evaluated (e.g. contains a reference() function). Please see https://aka.ms/WhatIfEvalStopped for more guidance.\",\n", - " \"target\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/inferenceAPIModule\"\n", - " }\n", - " ],\n", - " \"duration\": \"PT0S\",\n", - " \"error\": null,\n", - " \"extensions\": [],\n", - " \"mode\": \"Incremental\",\n", - " \"onErrorDeployment\": null,\n", - " \"outputResources\": null,\n", - " \"outputs\": null,\n", - " \"parameters\": {\n", - " \"aiServicesConfig\": {\n", - " \"type\": \"Array\",\n", - " \"value\": [\n", - " {\n", - " \"location\": \"swedencentral\",\n", - " \"name\": \"foundry-models\",\n", - " \"priority\": 1,\n", - " \"weight\": 100\n", - " },\n", - " {\n", - " \"location\": \"swedencentral\",\n", - " \"name\": \"foundry-agents\",\n", - " \"priority\": 1,\n", - " \"weight\": 100\n", - " }\n", - " ]\n", - " },\n", - " \"apimSku\": {\n", - " \"type\": \"String\",\n", - " \"value\": \"Basicv2\"\n", - " },\n", - " \"apimSubscriptionsConfig\": {\n", - " \"type\": \"Array\",\n", - " \"value\": [\n", - " {\n", - " \"displayName\": \"Starter\",\n", - " \"name\": \"starter\",\n", - " \"scope\": \"/apis\"\n", - " }\n", - " ]\n", - " },\n", - " \"enableHostedAgentResponsesApi\": {\n", - " \"type\": \"Bool\",\n", - " \"value\": true\n", - " },\n", - " \"foundryAgentAiServiceIndex\": {\n", - " \"type\": \"Int\",\n", - " \"value\": 1\n", - " },\n", - " \"foundryProjectName\": {\n", - " \"type\": \"String\",\n", - " \"value\": \"default\"\n", - " },\n", - " \"foundryUserObjectIds\": {\n", - " \"type\": \"Array\",\n", - " \"value\": [\n", - " \"13f94c0d-8a51-492a-928b-59392c23c1ac\"\n", - " ]\n", - " },\n", - " \"hostedAgentId\": {\n", - " \"type\": \"String\",\n", - " \"value\": \"strands-agent:3\"\n", - " },\n", - " \"hostedAgentResponsesApiPath\": {\n", - " \"type\": \"String\",\n", - " \"value\": \"hosted-agent-responses\"\n", - " },\n", - " \"hostedAgentResponsesApiVersion\": {\n", - " \"type\": \"String\",\n", - " \"value\": \"2025-05-15-preview\"\n", - " },\n", - " \"inferenceAPIPath\": {\n", - " \"type\": \"String\",\n", - " \"value\": \"inference\"\n", - " },\n", - " \"inferenceAPIType\": {\n", - " \"type\": \"String\",\n", - " \"value\": \"AzureAI\"\n", - " },\n", - " \"modelsConfig\": {\n", - " \"type\": \"Array\",\n", - " \"value\": [\n", - " {\n", - " \"aiservice\": \"foundry-models\",\n", - " \"capacity\": 10,\n", - " \"name\": \"gpt-5-mini\",\n", - " \"publisher\": \"OpenAI\",\n", - " \"sku\": \"GlobalStandard\",\n", - " \"version\": \"2025-08-07\"\n", - " }\n", - " ]\n", - " }\n", - " },\n", - " \"parametersLink\": null,\n", - " \"providers\": [\n", - " {\n", - " \"id\": null,\n", - " \"namespace\": \"Microsoft.ContainerRegistry\",\n", - " \"providerAuthorizationConsentState\": null,\n", - " \"registrationPolicy\": null,\n", - " \"registrationState\": null,\n", - " \"resourceTypes\": [\n", - " {\n", - " \"aliases\": null,\n", - " \"apiProfiles\": null,\n", - " \"apiVersions\": null,\n", - " \"capabilities\": null,\n", - " \"defaultApiVersion\": null,\n", - " \"locationMappings\": null,\n", - " \"locations\": [\n", - " \"swedencentral\"\n", - " ],\n", - " \"properties\": null,\n", - " \"resourceType\": \"registries\",\n", - " \"zoneMappings\": null\n", - " }\n", - " ]\n", - " },\n", - " {\n", - " \"id\": null,\n", - " \"namespace\": \"Microsoft.Authorization\",\n", - " \"providerAuthorizationConsentState\": null,\n", - " \"registrationPolicy\": null,\n", - " \"registrationState\": null,\n", - " \"resourceTypes\": [\n", - " {\n", - " \"aliases\": null,\n", - " \"apiProfiles\": null,\n", - " \"apiVersions\": null,\n", - " \"capabilities\": null,\n", - " \"defaultApiVersion\": null,\n", - " \"locationMappings\": null,\n", - " \"locations\": [\n", - " null\n", - " ],\n", - " \"properties\": null,\n", - " \"resourceType\": \"roleAssignments\",\n", - " \"zoneMappings\": null\n", - " }\n", - " ]\n", - " },\n", - " {\n", - " \"id\": null,\n", - " \"namespace\": \"Microsoft.ApiManagement\",\n", - " \"providerAuthorizationConsentState\": null,\n", - " \"registrationPolicy\": null,\n", - " \"registrationState\": null,\n", - " \"resourceTypes\": [\n", - " {\n", - " \"aliases\": null,\n", - " \"apiProfiles\": null,\n", - " \"apiVersions\": null,\n", - " \"capabilities\": null,\n", - " \"defaultApiVersion\": null,\n", - " \"locationMappings\": null,\n", - " \"locations\": [\n", - " null\n", - " ],\n", - " \"properties\": null,\n", - " \"resourceType\": \"service/apis\",\n", - " \"zoneMappings\": null\n", - " },\n", - " {\n", - " \"aliases\": null,\n", - " \"apiProfiles\": null,\n", - " \"apiVersions\": null,\n", - " \"capabilities\": null,\n", - " \"defaultApiVersion\": null,\n", - " \"locationMappings\": null,\n", - " \"locations\": [\n", - " null\n", - " ],\n", - " \"properties\": null,\n", - " \"resourceType\": \"service/apis/operations\",\n", - " \"zoneMappings\": null\n", - " },\n", - " {\n", - " \"aliases\": null,\n", - " \"apiProfiles\": null,\n", - " \"apiVersions\": null,\n", - " \"capabilities\": null,\n", - " \"defaultApiVersion\": null,\n", - " \"locationMappings\": null,\n", - " \"locations\": [\n", - " null\n", - " ],\n", - " \"properties\": null,\n", - " \"resourceType\": \"service/apis/policies\",\n", - " \"zoneMappings\": null\n", - " }\n", - " ]\n", - " },\n", - " {\n", - " \"id\": null,\n", - " \"namespace\": \"Microsoft.Resources\",\n", - " \"providerAuthorizationConsentState\": null,\n", - " \"registrationPolicy\": null,\n", - " \"registrationState\": null,\n", - " \"resourceTypes\": [\n", - " {\n", - " \"aliases\": null,\n", - " \"apiProfiles\": null,\n", - " \"apiVersions\": null,\n", - " \"capabilities\": null,\n", - " \"defaultApiVersion\": null,\n", - " \"locationMappings\": null,\n", - " \"locations\": [\n", - " null\n", - " ],\n", - " \"properties\": null,\n", - " \"resourceType\": \"deployments\",\n", - " \"zoneMappings\": null\n", - " }\n", - " ]\n", - " }\n", - " ],\n", - " \"provisioningState\": \"Succeeded\",\n", - " \"templateHash\": \"12337644779082219195\",\n", - " \"templateLink\": null,\n", - " \"timestamp\": \"2026-07-08T17:46:38.824042+00:00\",\n", - " \"validatedResources\": [\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ApiManagement/service/apim-xhep4wovroziu/apis/hosted-agent-responses-api\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceType\": null\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ApiManagement/service/apim-xhep4wovroziu/apis/hosted-agent-responses-api/operations/create-response\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceType\": null\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ApiManagement/service/apim-xhep4wovroziu/apis/hosted-agent-responses-api/policies/policy\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceType\": null\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.CognitiveServices/accounts/foundry-agents-xhep4wovroziu/providers/Microsoft.Authorization/roleAssignments/c4d31936-032e-5bdb-b9d3-a12891127593\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceType\": null\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.CognitiveServices/accounts/foundry-models-xhep4wovroziu/providers/Microsoft.Authorization/roleAssignments/dc422f45-552b-5b34-9880-e664b7afe0aa\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceType\": null\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrxhep4wovroziu\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceType\": null\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrxhep4wovroziu/providers/Microsoft.Authorization/roleAssignments/63983143-77d9-582c-b53c-793fefd1bd93\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceType\": null\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrxhep4wovroziu/providers/Microsoft.Authorization/roleAssignments/9fdae2e2-758a-52c5-a9f4-bbe68deee382\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceType\": null\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrxhep4wovroziu/providers/Microsoft.Authorization/roleAssignments/b0406c01-b2e5-5a38-8735-416921bc283e\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceType\": null\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrxhep4wovroziu/providers/Microsoft.Authorization/roleAssignments/c3a8ec22-2dde-50ce-a21a-2adcc18a175f\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceType\": null\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.ContainerRegistry/registries/acrxhep4wovroziu/providers/Microsoft.Authorization/roleAssignments/d978b2df-d75d-526b-9743-60720d2c081c\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceType\": null\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.OperationalInsights/workspaces/workspace-xhep4wovroziu\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceType\": null\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/apimModule\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceType\": null\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/appInsightsModule\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceType\": null\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/foundryModule\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceType\": null\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/inferenceAPIModule\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceType\": null\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/lawModule\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"resourceType\": null\n", - " }\n", - " ],\n", - " \"validationLevel\": null\n", - " },\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework\",\n", - " \"type\": \"Microsoft.Resources/deployments\"\n", - "}\n", - "\n", - "\n", - "$ cmd /c C:\\Program Files\\Microsoft SDKs\\Azure\\CLI2\\wbin\\az.cmd deployment group create --resource-group rg-aigw-hosted-custom-framework --name deploy-hosted-custom-framework --template-file C:\\GitHub\\ai-gateway\\AI-Gateway\\labs\\ai-foundry-hosted-agents-custom-framework\\main.bicep --parameters @C:\\GitHub\\ai-gateway\\AI-Gateway\\labs\\ai-foundry-hosted-agents-custom-framework\\main.parameters.generated.json --only-show-errors\n", - "ERROR: {\"status\":\"Failed\",\"error\":{\"code\":\"DeploymentFailed\",\"target\":\"/subscriptions/9be21359-7b5a-4ccd-b0c7-24c97acd7d0c/resourceGroups/rg-aigw-hosted-custom-framework/providers/Microsoft.Resources/deployments/deploy-hosted-custom-framework\",\"message\":\"At least one resource deployment operation failed. Please list deployment operations for details. Please see https://aka.ms/arm-deployment-operations for usage details.\",\"details\":[{\"code\":\"RoleAssignmentExists\",\"message\":\"The role assignment already exists. The ID of the existing role assignment is 3ee88ca04a0f46ada7dc792f08d82442.\"},{\"code\":\"RoleAssignmentExists\",\"message\":\"The role assignment already exists. The ID of the existing role assignment is 80356ae269865962a1f930f33d06915b.\"},{\"code\":\"RoleAssignmentExists\",\"message\":\"The role assignment already exists. The ID of the existing role assignment is 625cdc99b9c45912836d1d68a740fbb5.\"}]}}\n", - "\n" - ] - }, - { - "ename": "RuntimeError", - "evalue": "Command failed: 1", - "output_type": "error", - "traceback": [ - "\u001b[31m---------------------------------------------------------------------------\u001b[39m", - "\u001b[31mRuntimeError\u001b[39m Traceback (most recent call last)", - "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[9]\u001b[39m\u001b[32m, line 59\u001b[39m\n\u001b[32m 55\u001b[39m ])\n\u001b[32m 56\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m RuntimeError \u001b[38;5;28;01mas\u001b[39;00m ex:\n\u001b[32m 57\u001b[39m print(f'Validation failed, continuing to deployment create step: {ex}')\n\u001b[32m 58\u001b[39m \n\u001b[32m---> \u001b[39m\u001b[32m59\u001b[39m result = az_run([\n\u001b[32m 60\u001b[39m \u001b[33m'deployment'\u001b[39m, \u001b[33m'group'\u001b[39m, \u001b[33m'create'\u001b[39m,\n\u001b[32m 61\u001b[39m \u001b[33m'--resource-group'\u001b[39m, resource_group,\n\u001b[32m 62\u001b[39m \u001b[33m'--name'\u001b[39m, deployment_name,\n", - "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[9]\u001b[39m\u001b[32m, line 12\u001b[39m, in \u001b[36maz_run\u001b[39m\u001b[34m(args)\u001b[39m\n\u001b[32m 10\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m az_run(args):\n\u001b[32m 11\u001b[39m command = [\u001b[33m'cmd'\u001b[39m, \u001b[33m'/c'\u001b[39m, az_cmd, *args] \u001b[38;5;28;01mif\u001b[39;00m az_cmd.lower().endswith(\u001b[33m'.cmd'\u001b[39m) \u001b[38;5;28;01melse\u001b[39;00m [az_cmd, *args]\n\u001b[32m---> \u001b[39m\u001b[32m12\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m run(command)\n", - "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[6]\u001b[39m\u001b[32m, line 14\u001b[39m, in \u001b[36mrun\u001b[39m\u001b[34m(cmd)\u001b[39m\n\u001b[32m 10\u001b[39m print(result.stdout)\n\u001b[32m 11\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m result.returncode != \u001b[32m0\u001b[39m:\n\u001b[32m 12\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m result.stderr:\n\u001b[32m 13\u001b[39m print(result.stderr)\n\u001b[32m---> \u001b[39m\u001b[32m14\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m RuntimeError(f'Command failed: {result.returncode}')\n\u001b[32m 15\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m result\n", - "\u001b[31mRuntimeError\u001b[39m: Command failed: 1" - ] - } - ], + "outputs": [], "source": [ "# Create resource group and deploy Bicep\n", "# Ensure Azure CLI directory is available to subprocess calls in this kernel\n", @@ -1003,13 +283,31 @@ "id": "d0249aaa", "metadata": {}, "source": [ - "## Next step\n", - "\n", - "1. Run this notebook once to deploy Foundry and APIM.\n", - "2. Use one of the framework notebooks under `src/responses/agents/` to build, push, and deploy the hosted agent.\n", - "3. Set `hosted_agent_id` and `enable_hosted_agent_responses_api=True` in the config cell.\n", - "4. Re-run this notebook to add the APIM front door for the Hosted Agent Responses API.\n", - "5. Call APIM at the `hostedAgentResponsesApimPath` output endpoint." + "## Deployment Workflow\n", + "\n", + "**One-time deployment:**\n", + "\n", + "1. Run this notebook to deploy all Foundry and APIM infrastructure at once\n", + " - Foundry resources (models + agents)\n", + " - APIM with inference API and hosted agent responses API\n", + " - All role assignments\n", + " \n", + "**Then proceed to framework-specific setup:**\n", + "\n", + "2. Use one of the framework notebooks under `src/responses/agents/` to build, push, and deploy the hosted agent:\n", + " - `src/responses/agents/strands/01_hosted_agent_strands_setup.ipynb`\n", + " - The agent will be created with a name and version (e.g., `strands-agent:3`)\n", + " \n", + "**If the agent version doesn't match the hosted_agent_id:**\n", + "\n", + "3. If the deployed agent version differs from `hosted_agent_id` in the config above:\n", + " - Update `hosted_agent_id` to match (e.g., change from `strands-agent:1` to `strands-agent:3`)\n", + " - Re-run this deployment notebook to update APIM routing\n", + " - This is optional—APIM will route correctly once you update the backend ID\n", + "\n", + "**The agent responses API will be available at:**\n", + "- `POST https://apim-{suffix}.azure-api.net/hosted-agent-responses/endpoint/protocols/openai/responses?api-version=v1`\n", + "- With header: `api-key: {subscription-key-from-outputs}`" ] } ], diff --git a/labs/ai-foundry-hosted-agents-custom-framework/hosted-agent-policy.xml b/labs/ai-foundry-hosted-agents-custom-framework/hosted-agent-policy.xml new file mode 100644 index 00000000..40d90de2 --- /dev/null +++ b/labs/ai-foundry-hosted-agents-custom-framework/hosted-agent-policy.xml @@ -0,0 +1,36 @@ + + + + + + + + + @("Bearer " + (string)context.Variables["managed-id-access-token"]) + + + + + application/json + + + + + HostedAgents=V1Preview + + + + + 2025-05-15-preview + + + + + + + + + + + + \ No newline at end of file diff --git a/labs/ai-foundry-hosted-agents-custom-framework/main.bicep b/labs/ai-foundry-hosted-agents-custom-framework/main.bicep index c0cf9477..f96c8ca4 100644 --- a/labs/ai-foundry-hosted-agents-custom-framework/main.bicep +++ b/labs/ai-foundry-hosted-agents-custom-framework/main.bicep @@ -135,7 +135,6 @@ resource modelFoundryUserRoleAssignments 'Microsoft.Authorization/roleAssignment principalId: principalId principalType: 'User' } - skipDuplicateKeyErrors: true }] // Assign Foundry User role for all provided users on the hosted-agent Foundry resource. @@ -147,7 +146,6 @@ resource agentFoundryUserRoleAssignments 'Microsoft.Authorization/roleAssignment principalId: principalId principalType: 'User' } - skipDuplicateKeyErrors: true }] // Repository-level ACR roles (ABAC-enabled roles) @@ -165,31 +163,17 @@ resource foundryAgentAcrRepositoryReaderRoleAssignment 'Microsoft.Authorization/ principalId: foundryModule.outputs.extendedAIServicesConfig[foundryAgentAiServiceIndex].principalId principalType: 'ServicePrincipal' } - skipDuplicateKeyErrors: true } -// Assign ACR Repository Reader to the Foundry project identity for the hosted-agent resource. -resource foundryAgentProjectAcrRepositoryReaderRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { - name: guid(resourceGroup().id, foundryAgentAccountName, 'project', acrRepositoryReaderRoleId) - scope: containerRegistry - properties: { - roleDefinitionId: acrRepositoryReaderRoleId - principalId: foundryModule.outputs.extendedAIServicesConfig[foundryAgentAiServiceIndex].projectPrincipalId - principalType: 'ServicePrincipal' - } - skipDuplicateKeyErrors: true -} - -// Assign AcrPull to the Foundry project identity for the hosted-agent resource. -resource foundryAgentProjectAcrPullRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { - name: guid(resourceGroup().id, foundryAgentAccountName, 'project', acrPullRoleId) +// Assign AcrPull to Foundry project for container image pulls +resource foundryAgentAcrPullRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid(resourceGroup().id, foundryAgentAccountName, acrPullRoleId) scope: containerRegistry properties: { roleDefinitionId: acrPullRoleId - principalId: foundryModule.outputs.extendedAIServicesConfig[foundryAgentAiServiceIndex].projectPrincipalId + principalId: foundryModule.outputs.extendedAIServicesConfig[foundryAgentAiServiceIndex].principalId principalType: 'ServicePrincipal' } - skipDuplicateKeyErrors: true } resource deployerAcrRepositoryWriterRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { @@ -199,7 +183,6 @@ resource deployerAcrRepositoryWriterRoleAssignment 'Microsoft.Authorization/role roleDefinitionId: acrRepositoryWriterRoleId principalId: deployer().objectId } - skipDuplicateKeyErrors: true } resource deployerAcrRepositoryCatalogListerRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { @@ -209,7 +192,6 @@ resource deployerAcrRepositoryCatalogListerRoleAssignment 'Microsoft.Authorizati roleDefinitionId: acrRepositoryCatalogListerRoleId principalId: deployer().objectId } - skipDuplicateKeyErrors: true } // Existing APIM service reference for custom API resources. @@ -232,7 +214,7 @@ resource hostedAgentResponsesApi 'Microsoft.ApiManagement/service/apis@2024-06-0 protocols: [ 'https' ] - serviceUrl: '${foundryModule.outputs.extendedAIServicesConfig[foundryAgentAiServiceIndex].foundryProjectEndpoint}/agents/${hostedAgentId}' + serviceUrl: '${foundryModule.outputs.extendedAIServicesConfig[foundryAgentAiServiceIndex].foundryProjectEndpoint}/agents/${split(hostedAgentId, ':')[0]}' subscriptionKeyParameterNames: { header: 'api-key' query: 'api-key' @@ -264,7 +246,7 @@ resource hostedAgentResponsesApiPolicy 'Microsoft.ApiManagement/service/apis/pol parent: hostedAgentResponsesApi properties: { format: 'rawxml' - value: '@("Bearer " + (string)context.Variables["managed-id-access-token"])${hostedAgentResponsesApiVersion}' + value: loadTextContent('hosted-agent-policy.xml') } } diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/01_hosted_agent_strands_setup.ipynb b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/01_hosted_agent_strands_setup.ipynb index c3ae112f..fb0c6cae 100644 --- a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/01_hosted_agent_strands_setup.ipynb +++ b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/01_hosted_agent_strands_setup.ipynb @@ -7,18 +7,26 @@ "source": [ "# Strands Hosted Agent Setup\n", "\n", - "This notebook helps you:\n", - "1. Build and push a container image for your hosted agent code.\n", - "2. Create or update a hosted agent version from Python.\n", - "\n", - "## Prerequisites\n", - "- Docker Desktop running\n", - "- Docker authenticated to your ACR (`docker login .azurecr.io`)\n", - "- An authenticated Azure credential available for Step 2 (for example `az login`)\n", - "- Your signed-in identity has `Container Registry Repository Writer` on the target ACR repository (or equivalent push permission)\n", - "- The Microsoft Foundry project/resource identity has pull access to the image in ACR (for example `Container Registry Repository Reader` or equivalent repository-level pull permission)\n", - "\n", - "Fill in all placeholder values before running code cells." + "This notebook helps you build, deploy, and test a **Strands-based custom agent** on Microsoft Foundry Hosted Agents.\n", + "\n", + "### What this notebook does\n", + "\n", + "1. **Build & Push** - Builds a Docker container image for your Strands agent and pushes it to Azure Container Registry (ACR)\n", + "2. **Deploy** - Creates a hosted agent version in your Foundry project, pulling the image from ACR\n", + "3. **Test Direct** - Validates the agent works by calling Foundry's Responses API directly with your Azure credentials\n", + "4. **Test via APIM** - Routes requests through Azure API Management to test the production gateway path\n", + "\n", + "### Prerequisites\n", + "\n", + "Before running this notebook:\n", + "- Complete the **infrastructure deployment** notebook first (creates Foundry resources, APIM, ACR)\n", + "- Have the deployment outputs available:\n", + " - Foundry project endpoint\n", + " - ACR login server\n", + " - APIM suffix\n", + " - APIM subscription key\n", + "- Docker Desktop must be running\n", + "- You must be logged in to Azure CLI (`az login`)" ] }, { @@ -34,25 +42,13 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "id": "1cc7246e", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "ACR_NAME=acrxhep4wovroziu\n", - "ACR_LOGIN_SERVER=acrxhep4wovroziu.azurecr.io\n", - "IMAGE_NAME=strands-agent\n", - "IMAGE_TAG=1.0.0\n", - "IMAGE_URI=acrxhep4wovroziu.azurecr.io/strands-agent:1.0.0\n" - ] - } - ], + "outputs": [], "source": [ "# Set these placeholders\n", - "ACR_NAME = \"acrxhep4wovroziu\"\n", + "ACR_NAME = \"xxxx\"\n", "IMAGE_NAME = \"strands-agent\"\n", "IMAGE_TAG = \"1.0.0\"\n", "ACR_LOGIN_SERVER = f\"{ACR_NAME}.azurecr.io\"\n", @@ -65,20 +61,27 @@ "print(f\"IMAGE_URI={IMAGE_URI}\")" ] }, + { + "cell_type": "markdown", + "id": "97e66486", + "metadata": {}, + "source": [ + "### Fill in your configuration\n", + "\n", + "Replace the placeholder values below with your actual Azure resources. These should match the outputs from the infrastructure deployment notebook:\n", + "- `ACR_NAME`: Your Azure Container Registry name (e.g., `acrxhep4wovroziu`)\n", + "- `IMAGE_NAME`: Container image name for your Strands agent (usually `strands-agent`)\n", + "- `IMAGE_TAG`: Semantic version tag for your image (e.g., `1.0.0`)\n", + "\n", + "The computed values (`ACR_LOGIN_SERVER`, `IMAGE_URI`) will be used in subsequent steps." + ] + }, { "cell_type": "code", - "execution_count": 14, + "execution_count": null, "id": "702db155", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Login Succeeded\n" - ] - } - ], + "outputs": [], "source": [ "# Ensure Docker is running\n", "!az acr login --name {ACR_NAME}" @@ -86,483 +89,10 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": null, "id": "3126aa58", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Running: docker build -t acrxhep4wovroziu.azurecr.io/strands-agent:1.0.0 .\n", - "Running: docker push acrxhep4wovroziu.azurecr.io/strands-agent:1.0.0\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "#0 building with \"desktop-linux\" instance using docker driver\n", - "\n", - "#1 [internal] load build definition from Dockerfile\n", - "#1 transferring dockerfile: 233B 0.0s done\n", - "#1 DONE 0.0s\n", - "\n", - "#2 [internal] load metadata for docker.io/library/python:3.12-slim\n", - "#2 DONE 1.1s\n", - "\n", - "#3 [internal] load .dockerignore\n", - "#3 transferring context: 341B 0.0s done\n", - "#3 DONE 0.0s\n", - "\n", - "#4 [1/5] FROM docker.io/library/python:3.12-slim@sha256:423ed6ab25b1921a477529254bfeeabf5855151dc2c3141699a1bfc852199fbf\n", - "#4 resolve docker.io/library/python:3.12-slim@sha256:423ed6ab25b1921a477529254bfeeabf5855151dc2c3141699a1bfc852199fbf 0.0s done\n", - "#4 DONE 0.0s\n", - "\n", - "#5 [internal] load build context\n", - "#5 transferring context: 79.62kB 0.0s done\n", - "#5 DONE 0.0s\n", - "\n", - "#6 [2/5] WORKDIR /app\n", - "#6 CACHED\n", - "\n", - "#7 [3/5] COPY . user_agent/\n", - "#7 DONE 0.0s\n", - "\n", - "#8 [4/5] WORKDIR /app/user_agent\n", - "#8 DONE 0.0s\n", - "\n", - "#9 [5/5] RUN if [ -f requirements.txt ]; then pip install -r requirements.txt; fi\n", - "#9 17.81 Collecting azure-ai-agentserver-responses==1.0.0b8 (from -r requirements.txt (line 1))\n", - "#9 18.06 Downloading azure_ai_agentserver_responses-1.0.0b8-py3-none-any.whl.metadata (13 kB)\n", - "#9 18.32 Collecting strands-agents==1.45.0 (from strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 18.35 Downloading strands_agents-1.45.0-py3-none-any.whl.metadata (19 kB)\n", - "#9 18.82 Collecting python-dotenv (from -r requirements.txt (line 3))\n", - "#9 18.85 Downloading python_dotenv-1.2.2-py3-none-any.whl.metadata (27 kB)\n", - "#9 19.01 Collecting azure-ai-projects==2.3.0 (from -r requirements.txt (line 4))\n", - "#9 19.05 Downloading azure_ai_projects-2.3.0-py3-none-any.whl.metadata (64 kB)\n", - "#9 19.37 Collecting azure-ai-agentserver-core>=2.0.0b7 (from azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 19.41 Downloading azure_ai_agentserver_core-2.0.0b7-py3-none-any.whl.metadata (7.8 kB)\n", - "#9 19.67 Collecting azure-core>=1.30.0 (from azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 19.71 Downloading azure_core-1.41.0-py3-none-any.whl.metadata (49 kB)\n", - "#9 19.88 Collecting isodate>=0.6.1 (from azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 19.93 Downloading isodate-0.7.2-py3-none-any.whl.metadata (11 kB)\n", - "#9 25.43 Collecting aiohttp<4.0.0,>=3.10.0 (from azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 25.47 Downloading aiohttp-3.14.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (8.3 kB)\n", - "#9 31.16 Collecting boto3<2.0.0,>=1.26.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 31.24 Downloading boto3-1.43.42-py3-none-any.whl.metadata (6.6 kB)\n", - "#9 36.86 Collecting botocore<2.0.0,>=1.29.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 36.91 Downloading botocore-1.43.42-py3-none-any.whl.metadata (5.6 kB)\n", - "#9 37.10 Collecting docstring-parser<1.0,>=0.15 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 37.17 Downloading docstring_parser-0.18.0-py3-none-any.whl.metadata (3.5 kB)\n", - "#9 37.59 Collecting jsonschema<5.0.0,>=4.0.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 37.65 Downloading jsonschema-4.26.0-py3-none-any.whl.metadata (7.6 kB)\n", - "#9 37.97 Collecting mcp<2.0.0,>=1.23.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 38.00 Downloading mcp-1.28.1-py3-none-any.whl.metadata (9.4 kB)\n", - "#9 38.38 Collecting opentelemetry-api<2.0.0,>=1.30.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 38.42 Downloading opentelemetry_api-1.43.0-py3-none-any.whl.metadata (1.4 kB)\n", - "#9 38.60 Collecting opentelemetry-instrumentation-threading<1.00b0,>=0.51b0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 38.67 Downloading opentelemetry_instrumentation_threading-0.64b0-py3-none-any.whl.metadata (2.1 kB)\n", - "#9 39.00 Collecting opentelemetry-sdk<2.0.0,>=1.30.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 39.03 Downloading opentelemetry_sdk-1.43.0-py3-none-any.whl.metadata (1.7 kB)\n", - "#9 40.44 Collecting pydantic<3.0.0,>=2.4.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 40.48 Downloading pydantic-2.13.4-py3-none-any.whl.metadata (109 kB)\n", - "#9 41.05 Collecting pyyaml<7.0.0,>=6.0.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 41.10 Downloading pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (2.4 kB)\n", - "#9 41.32 Collecting typing-extensions<5.0.0,>=4.13.2 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 41.36 Downloading typing_extensions-4.16.0-py3-none-any.whl.metadata (3.3 kB)\n", - "#9 41.83 Collecting watchdog<7.0.0,>=6.0.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 41.91 Downloading watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl.metadata (44 kB)\n", - "#9 42.60 Collecting azure-identity>=1.15.0 (from azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", - "#9 42.64 Downloading azure_identity-1.25.3-py3-none-any.whl.metadata (91 kB)\n", - "#9 43.48 Collecting openai>=2.8.0 (from azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", - "#9 43.53 Downloading openai-2.44.0-py3-none-any.whl.metadata (34 kB)\n", - "#9 43.91 Collecting azure-storage-blob>=12.15.0 (from azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", - "#9 43.96 Downloading azure_storage_blob-12.30.0-py3-none-any.whl.metadata (26 kB)\n", - "#9 44.23 Collecting aws-bedrock-token-generator<2.0.0,>=1.1.0 (from strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 44.40 Downloading aws_bedrock_token_generator-1.1.0-py3-none-any.whl.metadata (7.5 kB)\n", - "#9 45.09 Collecting aiohappyeyeballs>=2.5.0 (from aiohttp<4.0.0,>=3.10.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 45.13 Downloading aiohappyeyeballs-2.7.1-py3-none-any.whl.metadata (5.9 kB)\n", - "#9 45.31 Collecting aiosignal>=1.4.0 (from aiohttp<4.0.0,>=3.10.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 45.36 Downloading aiosignal-1.4.0-py3-none-any.whl.metadata (3.7 kB)\n", - "#9 45.58 Collecting attrs>=17.3.0 (from aiohttp<4.0.0,>=3.10.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 45.68 Downloading attrs-26.1.0-py3-none-any.whl.metadata (8.8 kB)\n", - "#9 46.52 Collecting frozenlist>=1.1.1 (from aiohttp<4.0.0,>=3.10.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 46.59 Downloading frozenlist-1.8.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl.metadata (20 kB)\n", - "#9 49.08 Collecting multidict<7.0,>=4.5 (from aiohttp<4.0.0,>=3.10.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 49.13 Downloading multidict-6.7.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (5.3 kB)\n", - "#9 49.89 Collecting propcache>=0.2.0 (from aiohttp<4.0.0,>=3.10.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 49.93 Downloading propcache-0.5.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (16 kB)\n", - "#9 53.28 Collecting yarl<2.0,>=1.17.0 (from aiohttp<4.0.0,>=3.10.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 53.36 Downloading yarl-1.24.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (94 kB)\n", - "#9 56.99 Collecting starlette>=0.45.0 (from azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 57.04 Downloading starlette-1.3.1-py3-none-any.whl.metadata (6.4 kB)\n", - "#9 57.28 Collecting hypercorn>=0.17.0 (from azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 57.36 Downloading hypercorn-0.18.0-py3-none-any.whl.metadata (5.1 kB)\n", - "#9 57.87 Collecting microsoft-opentelemetry>=1.0.0 (from azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 57.92 Downloading microsoft_opentelemetry-1.3.5-py3-none-any.whl.metadata (23 kB)\n", - "#9 58.41 Collecting requests>=2.21.0 (from azure-core>=1.30.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 58.48 Downloading requests-2.34.2-py3-none-any.whl.metadata (4.8 kB)\n", - "#9 60.99 Collecting cryptography>=2.5 (from azure-identity>=1.15.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", - "#9 61.03 Downloading cryptography-49.0.0-cp311-abi3-manylinux_2_34_x86_64.whl.metadata (4.3 kB)\n", - "#9 61.29 Collecting msal>=1.35.1 (from azure-identity>=1.15.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", - "#9 61.34 Downloading msal-1.37.0-py3-none-any.whl.metadata (11 kB)\n", - "#9 61.50 Collecting msal-extensions>=1.2.0 (from azure-identity>=1.15.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", - "#9 61.55 Downloading msal_extensions-1.3.1-py3-none-any.whl.metadata (7.8 kB)\n", - "#9 65.29 Collecting jmespath<2.0.0,>=0.7.1 (from boto3<2.0.0,>=1.26.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 65.33 Downloading jmespath-1.1.0-py3-none-any.whl.metadata (7.6 kB)\n", - "#9 65.54 Collecting s3transfer<0.20.0,>=0.19.0 (from boto3<2.0.0,>=1.26.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 65.57 Downloading s3transfer-0.19.0-py3-none-any.whl.metadata (1.7 kB)\n", - "#9 65.77 Collecting python-dateutil<3.0.0,>=2.1 (from botocore<2.0.0,>=1.29.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 65.80 Downloading python_dateutil-2.9.0.post0-py2.py3-none-any.whl.metadata (8.4 kB)\n", - "#9 66.19 Collecting urllib3!=2.2.0,<3,>=1.25.4 (from botocore<2.0.0,>=1.29.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 66.24 Downloading urllib3-2.7.0-py3-none-any.whl.metadata (6.9 kB)\n", - "#9 66.54 Collecting jsonschema-specifications>=2023.03.6 (from jsonschema<5.0.0,>=4.0.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 66.58 Downloading jsonschema_specifications-2025.9.1-py3-none-any.whl.metadata (2.9 kB)\n", - "#9 66.95 Collecting referencing>=0.28.4 (from jsonschema<5.0.0,>=4.0.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 66.98 Downloading referencing-0.37.0-py3-none-any.whl.metadata (2.8 kB)\n", - "#9 69.94 Collecting rpds-py>=0.25.0 (from jsonschema<5.0.0,>=4.0.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 70.00 Downloading rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (4.1 kB)\n", - "#9 70.25 Collecting anyio>=4.5 (from mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 70.28 Downloading anyio-4.14.1-py3-none-any.whl.metadata (4.6 kB)\n", - "#9 70.42 Collecting httpx-sse>=0.4 (from mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 70.50 Downloading httpx_sse-0.4.3-py3-none-any.whl.metadata (9.7 kB)\n", - "#9 70.90 Collecting httpx<1.0.0,>=0.27.1 (from mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 70.99 Downloading httpx-0.28.1-py3-none-any.whl.metadata (7.1 kB)\n", - "#9 71.47 Collecting pydantic-settings>=2.5.2 (from mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 71.53 Downloading pydantic_settings-2.14.2-py3-none-any.whl.metadata (3.4 kB)\n", - "#9 72.25 Collecting pyjwt>=2.10.1 (from pyjwt[crypto]>=2.10.1->mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 72.33 Downloading pyjwt-2.13.0-py3-none-any.whl.metadata (3.4 kB)\n", - "#9 72.66 Collecting python-multipart>=0.0.9 (from mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 72.70 Downloading python_multipart-0.0.32-py3-none-any.whl.metadata (2.1 kB)\n", - "#9 72.94 Collecting sse-starlette>=1.6.1 (from mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 72.98 Downloading sse_starlette-3.4.5-py3-none-any.whl.metadata (15 kB)\n", - "#9 73.56 Collecting typing-inspection>=0.4.1 (from mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 73.61 Downloading typing_inspection-0.4.2-py3-none-any.whl.metadata (2.6 kB)\n", - "#9 74.02 Collecting uvicorn>=0.31.1 (from mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 74.05 Downloading uvicorn-0.51.0-py3-none-any.whl.metadata (6.6 kB)\n", - "#9 74.38 Collecting distro<2,>=1.7.0 (from openai>=2.8.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", - "#9 74.51 Downloading distro-1.9.0-py3-none-any.whl.metadata (6.8 kB)\n", - "#9 75.61 Collecting jiter<1,>=0.10.0 (from openai>=2.8.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", - "#9 75.66 Downloading jiter-0.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (5.2 kB)\n", - "#9 76.27 Collecting sniffio (from openai>=2.8.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", - "#9 76.33 Downloading sniffio-1.3.1-py3-none-any.whl.metadata (3.9 kB)\n", - "#9 76.76 Collecting tqdm>4 (from openai>=2.8.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", - "#9 76.84 Downloading tqdm-4.68.4-py3-none-any.whl.metadata (57 kB)\n", - "#9 77.56 Collecting opentelemetry-instrumentation==0.64b0 (from opentelemetry-instrumentation-threading<1.00b0,>=0.51b0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 77.61 Downloading opentelemetry_instrumentation-0.64b0-py3-none-any.whl.metadata (7.2 kB)\n", - "#9 80.40 Collecting wrapt<3.0.0,>=1.0.0 (from opentelemetry-instrumentation-threading<1.00b0,>=0.51b0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 80.43 Downloading wrapt-2.2.2-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl.metadata (7.4 kB)\n", - "#9 80.91 Collecting opentelemetry-semantic-conventions==0.64b0 (from opentelemetry-instrumentation==0.64b0->opentelemetry-instrumentation-threading<1.00b0,>=0.51b0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 80.97 Downloading opentelemetry_semantic_conventions-0.64b0-py3-none-any.whl.metadata (2.4 kB)\n", - "#9 81.25 Collecting packaging>=18.0 (from opentelemetry-instrumentation==0.64b0->opentelemetry-instrumentation-threading<1.00b0,>=0.51b0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 81.28 Downloading packaging-26.2-py3-none-any.whl.metadata (3.5 kB)\n", - "#9 81.70 Collecting annotated-types>=0.6.0 (from pydantic<3.0.0,>=2.4.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 81.75 Downloading annotated_types-0.7.0-py3-none-any.whl.metadata (15 kB)\n", - "#9 89.37 Collecting pydantic-core==2.46.4 (from pydantic<3.0.0,>=2.4.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 89.41 Downloading pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (6.6 kB)\n", - "#9 89.97 Collecting idna>=2.8 (from anyio>=4.5->mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 90.02 Downloading idna-3.18-py3-none-any.whl.metadata (6.1 kB)\n", - "#9 91.24 Collecting cffi>=2.0.0 (from cryptography>=2.5->azure-identity>=1.15.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", - "#9 91.28 Downloading cffi-2.1.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.metadata (2.5 kB)\n", - "#9 91.60 Collecting certifi (from httpx<1.0.0,>=0.27.1->mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 91.72 Downloading certifi-2026.6.17-py3-none-any.whl.metadata (2.5 kB)\n", - "#9 92.12 Collecting httpcore==1.* (from httpx<1.0.0,>=0.27.1->mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 92.29 Downloading httpcore-1.0.9-py3-none-any.whl.metadata (21 kB)\n", - "#9 92.49 Collecting h11>=0.16 (from httpcore==1.*->httpx<1.0.0,>=0.27.1->mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 92.53 Downloading h11-0.16.0-py3-none-any.whl.metadata (8.3 kB)\n", - "#9 92.76 Collecting h2>=4.3.0 (from hypercorn>=0.17.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 92.83 Downloading h2-4.3.0-py3-none-any.whl.metadata (5.1 kB)\n", - "#9 93.00 Collecting priority (from hypercorn>=0.17.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 93.04 Downloading priority-2.0.0-py3-none-any.whl.metadata (6.6 kB)\n", - "#9 93.14 Collecting wsproto>=0.14.0 (from hypercorn>=0.17.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 93.18 Downloading wsproto-1.3.2-py3-none-any.whl.metadata (5.2 kB)\n", - "#9 93.65 Collecting azure-core-tracing-opentelemetry~=1.0.0b11 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 93.69 Downloading azure_core_tracing_opentelemetry-1.0.0b13-py3-none-any.whl.metadata (11 kB)\n", - "#9 93.95 Collecting azure-monitor-opentelemetry-exporter~=1.0.0b54 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 94.00 Downloading azure_monitor_opentelemetry_exporter-1.0.0b55-py2.py3-none-any.whl.metadata (33 kB)\n", - "#9 94.53 Collecting opentelemetry-exporter-otlp-proto-http~=1.43.0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 94.57 Downloading opentelemetry_exporter_otlp_proto_http-1.43.0-py3-none-any.whl.metadata (2.4 kB)\n", - "#9 94.93 Collecting opentelemetry-instrumentation-django<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 94.96 Downloading opentelemetry_instrumentation_django-0.64b0-py3-none-any.whl.metadata (2.3 kB)\n", - "#9 95.22 Collecting opentelemetry-instrumentation-fastapi<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 95.27 Downloading opentelemetry_instrumentation_fastapi-0.64b0-py3-none-any.whl.metadata (2.2 kB)\n", - "#9 95.58 Collecting opentelemetry-instrumentation-flask<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 95.62 Downloading opentelemetry_instrumentation_flask-0.64b0-py3-none-any.whl.metadata (2.2 kB)\n", - "#9 95.87 Collecting opentelemetry-instrumentation-httpx<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 95.91 Downloading opentelemetry_instrumentation_httpx-0.64b0-py3-none-any.whl.metadata (7.3 kB)\n", - "#9 96.28 Collecting opentelemetry-instrumentation-psycopg2<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 96.36 Downloading opentelemetry_instrumentation_psycopg2-0.64b0-py3-none-any.whl.metadata (2.1 kB)\n", - "#9 96.74 Collecting opentelemetry-instrumentation-requests<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 96.79 Downloading opentelemetry_instrumentation_requests-0.64b0-py3-none-any.whl.metadata (2.6 kB)\n", - "#9 97.17 Collecting opentelemetry-instrumentation-urllib<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 97.21 Downloading opentelemetry_instrumentation_urllib-0.64b0-py3-none-any.whl.metadata (3.4 kB)\n", - "#9 97.52 Collecting opentelemetry-instrumentation-urllib3<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 97.56 Downloading opentelemetry_instrumentation_urllib3-0.64b0-py3-none-any.whl.metadata (4.2 kB)\n", - "#9 97.83 Collecting opentelemetry-instrumentation-logging<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 97.87 Downloading opentelemetry_instrumentation_logging-0.64b0-py3-none-any.whl.metadata (1.9 kB)\n", - "#9 97.97 Collecting opentelemetry-instrumentation-openai-agents-v2==0.1.0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 98.02 Downloading opentelemetry_instrumentation_openai_agents_v2-0.1.0-py3-none-any.whl.metadata (1.3 kB)\n", - "#9 98.28 Collecting opentelemetry-instrumentation-openai-v2==2.3b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 98.34 Downloading opentelemetry_instrumentation_openai_v2-2.3b0-py3-none-any.whl.metadata (5.2 kB)\n", - "#9 98.63 Collecting opentelemetry-resource-detector-azure<1.0.0,>=0.1.5 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 98.68 Downloading opentelemetry_resource_detector_azure-0.1.5-py3-none-any.whl.metadata (5.3 kB)\n", - "#9 98.87 Collecting wrapt<3.0.0,>=1.0.0 (from opentelemetry-instrumentation-threading<1.00b0,>=0.51b0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 98.94 Downloading wrapt-1.17.3-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl.metadata (6.4 kB)\n", - "#9 99.08 Collecting opentelemetry-util-genai==0.3b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 99.16 Downloading opentelemetry_util_genai-0.3b0-py3-none-any.whl.metadata (4.6 kB)\n", - "#9 102.6 Collecting six>=1.5 (from python-dateutil<3.0.0,>=2.1->botocore<2.0.0,>=1.29.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 102.6 Downloading six-1.17.0-py2.py3-none-any.whl.metadata (1.7 kB)\n", - "#9 104.3 Collecting charset_normalizer<4,>=2 (from requests>=2.21.0->azure-core>=1.30.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 104.4 Downloading charset_normalizer-3.4.9-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (41 kB)\n", - "#9 108.6 Collecting click>=7.0 (from uvicorn>=0.31.1->mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 108.6 Downloading click-8.4.2-py3-none-any.whl.metadata (2.6 kB)\n", - "#9 109.7 Collecting msrest>=0.6.10 (from azure-monitor-opentelemetry-exporter~=1.0.0b54->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 109.7 Downloading msrest-0.7.1-py3-none-any.whl.metadata (21 kB)\n", - "#9 110.6 Collecting psutil<8,>=5.9 (from azure-monitor-opentelemetry-exporter~=1.0.0b54->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 110.6 Downloading psutil-7.2.2-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl.metadata (22 kB)\n", - "#9 111.0 Collecting pycparser (from cffi>=2.0.0->cryptography>=2.5->azure-identity>=1.15.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", - "#9 111.1 Downloading pycparser-3.0-py3-none-any.whl.metadata (8.2 kB)\n", - "#9 111.4 Collecting hyperframe<7,>=6.1 (from h2>=4.3.0->hypercorn>=0.17.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 111.4 Downloading hyperframe-6.1.0-py3-none-any.whl.metadata (4.3 kB)\n", - "#9 111.7 Collecting hpack<5,>=4.1 (from h2>=4.3.0->hypercorn>=0.17.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 111.8 Downloading hpack-4.2.0-py3-none-any.whl.metadata (3.3 kB)\n", - "#9 112.2 Collecting googleapis-common-protos~=1.52 (from opentelemetry-exporter-otlp-proto-http~=1.43.0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 112.2 Downloading googleapis_common_protos-1.75.0-py3-none-any.whl.metadata (8.6 kB)\n", - "#9 112.6 Collecting opentelemetry-exporter-otlp-proto-common==1.43.0 (from opentelemetry-exporter-otlp-proto-http~=1.43.0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 112.7 Downloading opentelemetry_exporter_otlp_proto_common-1.43.0-py3-none-any.whl.metadata (1.8 kB)\n", - "#9 112.9 Collecting opentelemetry-proto==1.43.0 (from opentelemetry-exporter-otlp-proto-http~=1.43.0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 112.9 Downloading opentelemetry_proto-1.43.0-py3-none-any.whl.metadata (2.3 kB)\n", - "#9 115.3 Collecting protobuf<8.0,>=5.0 (from opentelemetry-proto==1.43.0->opentelemetry-exporter-otlp-proto-http~=1.43.0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 115.3 Downloading protobuf-7.35.1-cp310-abi3-manylinux2014_x86_64.whl.metadata (595 bytes)\n", - "#9 115.6 Collecting opentelemetry-instrumentation-wsgi==0.64b0 (from opentelemetry-instrumentation-django<0.65b0,>=0.64b0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 115.6 Downloading opentelemetry_instrumentation_wsgi-0.64b0-py3-none-any.whl.metadata (2.1 kB)\n", - "#9 115.9 Collecting opentelemetry-util-http==0.64b0 (from opentelemetry-instrumentation-django<0.65b0,>=0.64b0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 115.9 Downloading opentelemetry_util_http-0.64b0-py3-none-any.whl.metadata (2.6 kB)\n", - "#9 116.5 Collecting opentelemetry-instrumentation-asgi==0.64b0 (from opentelemetry-instrumentation-fastapi<0.65b0,>=0.64b0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 116.5 Downloading opentelemetry_instrumentation_asgi-0.64b0-py3-none-any.whl.metadata (2.0 kB)\n", - "#9 116.9 Collecting asgiref~=3.0 (from opentelemetry-instrumentation-asgi==0.64b0->opentelemetry-instrumentation-fastapi<0.65b0,>=0.64b0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 117.0 Downloading asgiref-3.11.1-py3-none-any.whl.metadata (9.3 kB)\n", - "#9 117.5 Collecting opentelemetry-instrumentation-dbapi==0.64b0 (from opentelemetry-instrumentation-psycopg2<0.65b0,>=0.64b0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 117.6 Downloading opentelemetry_instrumentation_dbapi-0.64b0-py3-none-any.whl.metadata (2.0 kB)\n", - "#9 118.9 Collecting requests-oauthlib>=0.5.0 (from msrest>=0.6.10->azure-monitor-opentelemetry-exporter~=1.0.0b54->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 118.9 Downloading requests_oauthlib-2.0.0-py2.py3-none-any.whl.metadata (11 kB)\n", - "#9 119.8 Collecting oauthlib>=3.0.0 (from requests-oauthlib>=0.5.0->msrest>=0.6.10->azure-monitor-opentelemetry-exporter~=1.0.0b54->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 119.9 Downloading oauthlib-3.3.1-py3-none-any.whl.metadata (7.9 kB)\n", - "#9 120.1 Downloading azure_ai_agentserver_responses-1.0.0b8-py3-none-any.whl (269 kB)\n", - "#9 120.3 Downloading strands_agents-1.45.0-py3-none-any.whl (579 kB)\n", - "#9 120.4 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 579.3/579.3 kB 3.7 MB/s eta 0:00:00\n", - "#9 120.5 Downloading azure_ai_projects-2.3.0-py3-none-any.whl (349 kB)\n", - "#9 120.6 Downloading python_dotenv-1.2.2-py3-none-any.whl (22 kB)\n", - "#9 120.7 Downloading aiohttp-3.14.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (1.8 MB)\n", - "#9 121.0 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.8/1.8 MB 5.3 MB/s eta 0:00:00\n", - "#9 121.0 Downloading aws_bedrock_token_generator-1.1.0-py3-none-any.whl (10 kB)\n", - "#9 121.1 Downloading azure_ai_agentserver_core-2.0.0b7-py3-none-any.whl (35 kB)\n", - "#9 121.3 Downloading azure_core-1.41.0-py3-none-any.whl (220 kB)\n", - "#9 121.4 Downloading azure_identity-1.25.3-py3-none-any.whl (192 kB)\n", - "#9 121.7 Downloading azure_storage_blob-12.30.0-py3-none-any.whl (435 kB)\n", - "#9 122.1 Downloading boto3-1.43.42-py3-none-any.whl (140 kB)\n", - "#9 122.2 Downloading botocore-1.43.42-py3-none-any.whl (15.4 MB)\n", - "#9 124.6 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 15.4/15.4 MB 6.9 MB/s eta 0:00:00\n", - "#9 124.6 Downloading docstring_parser-0.18.0-py3-none-any.whl (22 kB)\n", - "#9 124.7 Downloading isodate-0.7.2-py3-none-any.whl (22 kB)\n", - "#9 124.9 Downloading jsonschema-4.26.0-py3-none-any.whl (90 kB)\n", - "#9 125.0 Downloading mcp-1.28.1-py3-none-any.whl (222 kB)\n", - "#9 125.2 Downloading openai-2.44.0-py3-none-any.whl (1.4 MB)\n", - "#9 125.3 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.4/1.4 MB 9.8 MB/s eta 0:00:00\n", - "#9 125.4 Downloading opentelemetry_api-1.43.0-py3-none-any.whl (61 kB)\n", - "#9 125.5 Downloading opentelemetry_instrumentation_threading-0.64b0-py3-none-any.whl (8.5 kB)\n", - "#9 125.5 Downloading opentelemetry_instrumentation-0.64b0-py3-none-any.whl (35 kB)\n", - "#9 125.6 Downloading opentelemetry_semantic_conventions-0.64b0-py3-none-any.whl (203 kB)\n", - "#9 125.8 Downloading opentelemetry_sdk-1.43.0-py3-none-any.whl (178 kB)\n", - "#9 125.9 Downloading pydantic-2.13.4-py3-none-any.whl (472 kB)\n", - "#9 126.1 Downloading pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.1 MB)\n", - "#9 126.4 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2.1/2.1 MB 6.0 MB/s eta 0:00:00\n", - "#9 126.5 Downloading pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (807 kB)\n", - "#9 126.6 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 807.9/807.9 kB 6.7 MB/s eta 0:00:00\n", - "#9 126.7 Downloading typing_extensions-4.16.0-py3-none-any.whl (45 kB)\n", - "#9 126.7 Downloading watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl (79 kB)\n", - "#9 126.8 Downloading aiohappyeyeballs-2.7.1-py3-none-any.whl (15 kB)\n", - "#9 126.9 Downloading aiosignal-1.4.0-py3-none-any.whl (7.5 kB)\n", - "#9 126.9 Downloading annotated_types-0.7.0-py3-none-any.whl (13 kB)\n", - "#9 127.0 Downloading anyio-4.14.1-py3-none-any.whl (124 kB)\n", - "#9 127.1 Downloading attrs-26.1.0-py3-none-any.whl (67 kB)\n", - "#9 127.2 Downloading cryptography-49.0.0-cp311-abi3-manylinux_2_34_x86_64.whl (4.7 MB)\n", - "#9 127.9 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 4.7/4.7 MB 7.2 MB/s eta 0:00:00\n", - "#9 127.9 Downloading distro-1.9.0-py3-none-any.whl (20 kB)\n", - "#9 128.0 Downloading frozenlist-1.8.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl (242 kB)\n", - "#9 128.2 Downloading httpx-0.28.1-py3-none-any.whl (73 kB)\n", - "#9 128.3 Downloading httpcore-1.0.9-py3-none-any.whl (78 kB)\n", - "#9 128.4 Downloading httpx_sse-0.4.3-py3-none-any.whl (9.0 kB)\n", - "#9 128.5 Downloading hypercorn-0.18.0-py3-none-any.whl (61 kB)\n", - "#9 128.6 Downloading jiter-0.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (343 kB)\n", - "#9 128.8 Downloading jmespath-1.1.0-py3-none-any.whl (20 kB)\n", - "#9 128.9 Downloading jsonschema_specifications-2025.9.1-py3-none-any.whl (18 kB)\n", - "#9 129.0 Downloading microsoft_opentelemetry-1.3.5-py3-none-any.whl (208 kB)\n", - "#9 129.1 Downloading opentelemetry_instrumentation_openai_agents_v2-0.1.0-py3-none-any.whl (25 kB)\n", - "#9 129.2 Downloading opentelemetry_instrumentation_openai_v2-2.3b0-py3-none-any.whl (18 kB)\n", - "#9 129.2 Downloading opentelemetry_util_genai-0.3b0-py3-none-any.whl (28 kB)\n", - "#9 129.3 Downloading msal-1.37.0-py3-none-any.whl (123 kB)\n", - "#9 129.4 Downloading msal_extensions-1.3.1-py3-none-any.whl (20 kB)\n", - "#9 129.5 Downloading multidict-6.7.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (256 kB)\n", - "#9 129.6 Downloading propcache-0.5.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (61 kB)\n", - "#9 129.6 Downloading pydantic_settings-2.14.2-py3-none-any.whl (61 kB)\n", - "#9 129.7 Downloading pyjwt-2.13.0-py3-none-any.whl (31 kB)\n", - "#9 129.8 Downloading python_dateutil-2.9.0.post0-py2.py3-none-any.whl (229 kB)\n", - "#9 129.9 Downloading python_multipart-0.0.32-py3-none-any.whl (30 kB)\n", - "#9 130.0 Downloading referencing-0.37.0-py3-none-any.whl (26 kB)\n", - "#9 130.0 Downloading requests-2.34.2-py3-none-any.whl (73 kB)\n", - "#9 130.1 Downloading rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (366 kB)\n", - "#9 130.2 Downloading s3transfer-0.19.0-py3-none-any.whl (90 kB)\n", - "#9 130.3 Downloading sse_starlette-3.4.5-py3-none-any.whl (16 kB)\n", - "#9 130.3 Downloading starlette-1.3.1-py3-none-any.whl (73 kB)\n", - "#9 130.4 Downloading tqdm-4.68.4-py3-none-any.whl (676 kB)\n", - "#9 130.7 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 676.6/676.6 kB 1.3 MB/s eta 0:00:00\n", - "#9 130.8 Downloading typing_inspection-0.4.2-py3-none-any.whl (14 kB)\n", - "#9 130.9 Downloading urllib3-2.7.0-py3-none-any.whl (131 kB)\n", - "#9 130.9 Downloading uvicorn-0.51.0-py3-none-any.whl (73 kB)\n", - "#9 131.0 Downloading wrapt-1.17.3-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl (88 kB)\n", - "#9 131.0 Downloading yarl-1.24.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (105 kB)\n", - "#9 131.1 Downloading sniffio-1.3.1-py3-none-any.whl (10 kB)\n", - "#9 131.1 Downloading azure_core_tracing_opentelemetry-1.0.0b13-py3-none-any.whl (12 kB)\n", - "#9 131.2 Downloading azure_monitor_opentelemetry_exporter-1.0.0b55-py2.py3-none-any.whl (251 kB)\n", - "#9 131.3 Downloading certifi-2026.6.17-py3-none-any.whl (133 kB)\n", - "#9 131.3 Downloading cffi-2.1.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (221 kB)\n", - "#9 131.4 Downloading charset_normalizer-3.4.9-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (224 kB)\n", - "#9 131.4 Downloading click-8.4.2-py3-none-any.whl (119 kB)\n", - "#9 131.5 Downloading h11-0.16.0-py3-none-any.whl (37 kB)\n", - "#9 131.5 Downloading h2-4.3.0-py3-none-any.whl (61 kB)\n", - "#9 131.6 Downloading idna-3.18-py3-none-any.whl (65 kB)\n", - "#9 131.7 Downloading opentelemetry_exporter_otlp_proto_http-1.43.0-py3-none-any.whl (21 kB)\n", - "#9 131.8 Downloading opentelemetry_exporter_otlp_proto_common-1.43.0-py3-none-any.whl (17 kB)\n", - "#9 131.8 Downloading opentelemetry_proto-1.43.0-py3-none-any.whl (72 kB)\n", - "#9 131.9 Downloading opentelemetry_instrumentation_django-0.64b0-py3-none-any.whl (18 kB)\n", - "#9 132.0 Downloading opentelemetry_instrumentation_wsgi-0.64b0-py3-none-any.whl (13 kB)\n", - "#9 132.1 Downloading opentelemetry_util_http-0.64b0-py3-none-any.whl (8.2 kB)\n", - "#9 132.1 Downloading opentelemetry_instrumentation_fastapi-0.64b0-py3-none-any.whl (13 kB)\n", - "#9 132.2 Downloading opentelemetry_instrumentation_asgi-0.64b0-py3-none-any.whl (15 kB)\n", - "#9 132.3 Downloading opentelemetry_instrumentation_flask-0.64b0-py3-none-any.whl (15 kB)\n", - "#9 132.3 Downloading opentelemetry_instrumentation_httpx-0.64b0-py3-none-any.whl (16 kB)\n", - "#9 132.4 Downloading opentelemetry_instrumentation_logging-0.64b0-py3-none-any.whl (16 kB)\n", - "#9 132.5 Downloading opentelemetry_instrumentation_psycopg2-0.64b0-py3-none-any.whl (10 kB)\n", - "#9 132.5 Downloading opentelemetry_instrumentation_dbapi-0.64b0-py3-none-any.whl (14 kB)\n", - "#9 132.6 Downloading opentelemetry_instrumentation_requests-0.64b0-py3-none-any.whl (13 kB)\n", - "#9 132.6 Downloading opentelemetry_instrumentation_urllib-0.64b0-py3-none-any.whl (13 kB)\n", - "#9 132.7 Downloading opentelemetry_instrumentation_urllib3-0.64b0-py3-none-any.whl (13 kB)\n", - "#9 132.7 Downloading opentelemetry_resource_detector_azure-0.1.5-py3-none-any.whl (14 kB)\n", - "#9 132.8 Downloading packaging-26.2-py3-none-any.whl (100 kB)\n", - "#9 132.8 Downloading six-1.17.0-py2.py3-none-any.whl (11 kB)\n", - "#9 132.9 Downloading wsproto-1.3.2-py3-none-any.whl (24 kB)\n", - "#9 132.9 Downloading priority-2.0.0-py3-none-any.whl (8.9 kB)\n", - "#9 133.0 Downloading googleapis_common_protos-1.75.0-py3-none-any.whl (300 kB)\n", - "#9 133.1 Downloading hpack-4.2.0-py3-none-any.whl (34 kB)\n", - "#9 133.1 Downloading hyperframe-6.1.0-py3-none-any.whl (13 kB)\n", - "#9 133.2 Downloading msrest-0.7.1-py3-none-any.whl (85 kB)\n", - "#9 133.2 Downloading psutil-7.2.2-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl (155 kB)\n", - "#9 133.3 Downloading pycparser-3.0-py3-none-any.whl (48 kB)\n", - "#9 133.4 Downloading asgiref-3.11.1-py3-none-any.whl (24 kB)\n", - "#9 133.5 Downloading protobuf-7.35.1-cp310-abi3-manylinux2014_x86_64.whl (327 kB)\n", - "#9 133.7 Downloading requests_oauthlib-2.0.0-py2.py3-none-any.whl (24 kB)\n", - "#9 133.8 Downloading oauthlib-3.3.1-py3-none-any.whl (160 kB)\n", - "#9 137.5 Installing collected packages: wrapt, watchdog, urllib3, typing-extensions, tqdm, sniffio, six, rpds-py, pyyaml, python-multipart, python-dotenv, pyjwt, pycparser, psutil, protobuf, propcache, priority, packaging, opentelemetry-util-http, oauthlib, multidict, jmespath, jiter, isodate, idna, hyperframe, httpx-sse, hpack, h11, frozenlist, docstring-parser, distro, click, charset_normalizer, certifi, attrs, asgiref, annotated-types, aiohappyeyeballs, yarl, wsproto, uvicorn, typing-inspection, requests, referencing, python-dateutil, pydantic-core, opentelemetry-proto, opentelemetry-api, httpcore, h2, googleapis-common-protos, cffi, anyio, aiosignal, starlette, requests-oauthlib, pydantic, opentelemetry-semantic-conventions, opentelemetry-exporter-otlp-proto-common, jsonschema-specifications, hypercorn, httpx, cryptography, botocore, azure-core, aiohttp, sse-starlette, s3transfer, pydantic-settings, opentelemetry-sdk, opentelemetry-instrumentation, openai, msrest, jsonschema, azure-storage-blob, azure-core-tracing-opentelemetry, aws-bedrock-token-generator, opentelemetry-util-genai, opentelemetry-resource-detector-azure, opentelemetry-instrumentation-wsgi, opentelemetry-instrumentation-urllib3, opentelemetry-instrumentation-urllib, opentelemetry-instrumentation-threading, opentelemetry-instrumentation-requests, opentelemetry-instrumentation-openai-v2, opentelemetry-instrumentation-logging, opentelemetry-instrumentation-httpx, opentelemetry-instrumentation-dbapi, opentelemetry-instrumentation-asgi, opentelemetry-exporter-otlp-proto-http, msal, mcp, boto3, strands-agents, opentelemetry-instrumentation-psycopg2, opentelemetry-instrumentation-openai-agents-v2, opentelemetry-instrumentation-flask, opentelemetry-instrumentation-fastapi, opentelemetry-instrumentation-django, msal-extensions, azure-identity, azure-monitor-opentelemetry-exporter, azure-ai-projects, microsoft-opentelemetry, azure-ai-agentserver-core, azure-ai-agentserver-responses\n", - "#9 213.7 Successfully installed aiohappyeyeballs-2.7.1 aiohttp-3.14.1 aiosignal-1.4.0 annotated-types-0.7.0 anyio-4.14.1 asgiref-3.11.1 attrs-26.1.0 aws-bedrock-token-generator-1.1.0 azure-ai-agentserver-core-2.0.0b7 azure-ai-agentserver-responses-1.0.0b8 azure-ai-projects-2.3.0 azure-core-1.41.0 azure-core-tracing-opentelemetry-1.0.0b13 azure-identity-1.25.3 azure-monitor-opentelemetry-exporter-1.0.0b55 azure-storage-blob-12.30.0 boto3-1.43.42 botocore-1.43.42 certifi-2026.6.17 cffi-2.1.0 charset_normalizer-3.4.9 click-8.4.2 cryptography-49.0.0 distro-1.9.0 docstring-parser-0.18.0 frozenlist-1.8.0 googleapis-common-protos-1.75.0 h11-0.16.0 h2-4.3.0 hpack-4.2.0 httpcore-1.0.9 httpx-0.28.1 httpx-sse-0.4.3 hypercorn-0.18.0 hyperframe-6.1.0 idna-3.18 isodate-0.7.2 jiter-0.16.0 jmespath-1.1.0 jsonschema-4.26.0 jsonschema-specifications-2025.9.1 mcp-1.28.1 microsoft-opentelemetry-1.3.5 msal-1.37.0 msal-extensions-1.3.1 msrest-0.7.1 multidict-6.7.1 oauthlib-3.3.1 openai-2.44.0 opentelemetry-api-1.43.0 opentelemetry-exporter-otlp-proto-common-1.43.0 opentelemetry-exporter-otlp-proto-http-1.43.0 opentelemetry-instrumentation-0.64b0 opentelemetry-instrumentation-asgi-0.64b0 opentelemetry-instrumentation-dbapi-0.64b0 opentelemetry-instrumentation-django-0.64b0 opentelemetry-instrumentation-fastapi-0.64b0 opentelemetry-instrumentation-flask-0.64b0 opentelemetry-instrumentation-httpx-0.64b0 opentelemetry-instrumentation-logging-0.64b0 opentelemetry-instrumentation-openai-agents-v2-0.1.0 opentelemetry-instrumentation-openai-v2-2.3b0 opentelemetry-instrumentation-psycopg2-0.64b0 opentelemetry-instrumentation-requests-0.64b0 opentelemetry-instrumentation-threading-0.64b0 opentelemetry-instrumentation-urllib-0.64b0 opentelemetry-instrumentation-urllib3-0.64b0 opentelemetry-instrumentation-wsgi-0.64b0 opentelemetry-proto-1.43.0 opentelemetry-resource-detector-azure-0.1.5 opentelemetry-sdk-1.43.0 opentelemetry-semantic-conventions-0.64b0 opentelemetry-util-genai-0.3b0 opentelemetry-util-http-0.64b0 packaging-26.2 priority-2.0.0 propcache-0.5.2 protobuf-7.35.1 psutil-7.2.2 pycparser-3.0 pydantic-2.13.4 pydantic-core-2.46.4 pydantic-settings-2.14.2 pyjwt-2.13.0 python-dateutil-2.9.0.post0 python-dotenv-1.2.2 python-multipart-0.0.32 pyyaml-6.0.3 referencing-0.37.0 requests-2.34.2 requests-oauthlib-2.0.0 rpds-py-2026.6.3 s3transfer-0.19.0 six-1.17.0 sniffio-1.3.1 sse-starlette-3.4.5 starlette-1.3.1 strands-agents-1.45.0 tqdm-4.68.4 typing-extensions-4.16.0 typing-inspection-0.4.2 urllib3-2.7.0 uvicorn-0.51.0 watchdog-6.0.0 wrapt-1.17.3 wsproto-1.3.2 yarl-1.24.2\n", - "#9 213.7 WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager, possibly rendering your system unusable. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv. Use the --root-user-action option if you know what you are doing and want to suppress this warning.\n", - "#9 214.6 \n", - "#9 214.6 [notice] A new release of pip is available: 25.0.1 -> 26.1.2\n", - "#9 214.6 [notice] To update, run: pip install --upgrade pip\n", - "#9 DONE 216.0s\n", - "\n", - "#10 exporting to image\n", - "#10 exporting layers\n", - "#10 exporting layers 5.9s done\n", - "#10 exporting manifest sha256:f83339a6f88c9855285a635dc6a82f3330db39d722752b5566a976a017184318 0.0s done\n", - "#10 exporting config sha256:25e26bb089b0d3fc015de4cc0e060393904941195b286ff385e949092ca55112 0.0s done\n", - "#10 exporting attestation manifest sha256:55604b7e39e2e155e90068bb085dc70c2dc6403dc306d8846a8a0755a64aaabe 0.0s done\n", - "#10 exporting manifest list sha256:696f84a1b0bae9bcb0dcc4ca855933fe86629c5b4fc201903e08e0a0cdf025e7 0.0s done\n", - "#10 naming to acrxhep4wovroziu.azurecr.io/strands-agent:1.0.0\n", - "#10 naming to acrxhep4wovroziu.azurecr.io/strands-agent:1.0.0 done\n", - "#10 DONE 6.1s\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "The push refers to repository [acrxhep4wovroziu.azurecr.io/strands-agent]\n", - "d8928a1a5156: Waiting\n", - "b32430367bf0: Waiting\n", - "920a378a0384: Waiting\n", - "4f4fb700ef54: Waiting\n", - "df79d931cd67: Waiting\n", - "e95a6c7ea7d4: Waiting\n", - "5448f2dea2bc: Waiting\n", - "aff2d9f8dc87: Waiting\n", - "8c85a4e00d52: Waiting\n", - "aff2d9f8dc87: Waiting\n", - "8c85a4e00d52: Waiting\n", - "d8928a1a5156: Waiting\n", - "b32430367bf0: Waiting\n", - "920a378a0384: Waiting\n", - "4f4fb700ef54: Waiting\n", - "df79d931cd67: Waiting\n", - "e95a6c7ea7d4: Waiting\n", - "5448f2dea2bc: Waiting\n", - "8c85a4e00d52: Waiting\n", - "d8928a1a5156: Waiting\n", - "b32430367bf0: Waiting\n", - "920a378a0384: Waiting\n", - "4f4fb700ef54: Waiting\n", - "df79d931cd67: Waiting\n", - "e95a6c7ea7d4: Waiting\n", - "5448f2dea2bc: Waiting\n", - "aff2d9f8dc87: Waiting\n", - "b32430367bf0: Waiting\n", - "920a378a0384: Waiting\n", - "4f4fb700ef54: Waiting\n", - "df79d931cd67: Waiting\n", - "e95a6c7ea7d4: Waiting\n", - "5448f2dea2bc: Waiting\n", - "aff2d9f8dc87: Waiting\n", - "8c85a4e00d52: Waiting\n", - "d8928a1a5156: Waiting\n", - "8c85a4e00d52: Waiting\n", - "d8928a1a5156: Waiting\n", - "b32430367bf0: Waiting\n", - "920a378a0384: Waiting\n", - "4f4fb700ef54: Waiting\n", - "df79d931cd67: Waiting\n", - "e95a6c7ea7d4: Waiting\n", - "5448f2dea2bc: Waiting\n", - "aff2d9f8dc87: Waiting\n", - "8c85a4e00d52: Waiting\n", - "d8928a1a5156: Waiting\n", - "b32430367bf0: Waiting\n", - "920a378a0384: Waiting\n", - "4f4fb700ef54: Waiting\n", - "df79d931cd67: Waiting\n", - "e95a6c7ea7d4: Waiting\n", - "5448f2dea2bc: Waiting\n", - "aff2d9f8dc87: Waiting\n", - "8c85a4e00d52: Waiting\n", - "d8928a1a5156: Waiting\n", - "b32430367bf0: Waiting\n", - "920a378a0384: Waiting\n", - "df79d931cd67: Waiting\n", - "5448f2dea2bc: Waiting\n", - "4f4fb700ef54: Pushed\n", - "5448f2dea2bc: Pushed\n", - "8c85a4e00d52: Pushed\n", - "b32430367bf0: Pushed\n", - "920a378a0384: Pushed\n", - "aff2d9f8dc87: Pushed\n", - "df79d931cd67: Pushed\n", - "e95a6c7ea7d4: Pushed\n", - "d8928a1a5156: Pushed\n", - "1.0.0: digest: sha256:696f84a1b0bae9bcb0dcc4ca855933fe86629c5b4fc201903e08e0a0cdf025e7 size: 856\n", - "Docker build and push completed successfully.\n" - ] - } - ], + "outputs": [], "source": [ "\n", "# Use Docker directly from the notebook\n", @@ -575,6 +105,18 @@ "print(\"Docker build and push completed successfully.\")" ] }, + { + "cell_type": "markdown", + "id": "09b0c0cc", + "metadata": {}, + "source": [ + "### Build and push your container\n", + "\n", + "This builds the Strands agent Docker image and pushes it to your ACR. The `--platform linux/amd64` flag ensures the image is compatible with Foundry's Linux-based container hosting.\n", + "\n", + "After pushing, your image will be available at `{ACR_LOGIN_SERVER}/strands-agent:1.0.0` for Foundry to pull and deploy." + ] + }, { "cell_type": "markdown", "id": "20f53916", @@ -582,219 +124,57 @@ "source": [ "## 2. Create Hosted Agent Version\n", "\n", - "This cell mirrors the logic from agent_creation.py with placeholder values only.\n", + "This section creates your Strands agent as a **Foundry Hosted Agent** using the Responses protocol v1.0.0.\n", + "\n", + "### Important notes\n", + "\n", + "- **Agent name**: Must match `hosted_agent_id` from the infrastructure deployment (without the version suffix). \n", + " - E.g., if you set `hosted_agent_id = 'strands-agent:1'` in main deployment, create the agent with name `strands-agent` here.\n", + " - Foundry auto-assigns the version suffix (`:1`, `:2`, etc.)\n", + "\n", + "- **Model endpoint**: Uses APIM **inference** API for model calls (`https://apim-{suffix}.azure-api.net/inference/models`), not the hosted-agent API.\n", "\n", - "Model authentication for this Strands agent is APIM api-key based (not managed identity).\n", - "Use the APIM inference endpoint for model calls, and ensure that API is wired to backend `foundry-models`.\n", - "`foundry-agents` is for the hosted agent Responses API/proxy, not the model inference API used by this runtime.\n", + "- **Dependencies**: Install `azure-ai-projects` and `azure-identity` to interact with Foundry APIs.\n", "\n", - "Install dependencies first if needed:\n", - "`pip install azure-ai-projects azure-identity`" + "After creation, your agent will transition through status changes. Once it reaches \"Running\", it's ready to accept requests in sections 3 and 4." ] }, { "cell_type": "code", - "execution_count": 16, + "execution_count": null, "id": "cca00471", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Collecting azure-ai-projects==2.3.0\n", - " Downloading azure_ai_projects-2.3.0-py3-none-any.whl.metadata (64 kB)\n", - "Collecting isodate>=0.6.1 (from azure-ai-projects==2.3.0)\n", - " Downloading isodate-0.7.2-py3-none-any.whl.metadata (11 kB)\n", - "Collecting azure-core>=1.37.0 (from azure-ai-projects==2.3.0)\n", - " Downloading azure_core-1.41.0-py3-none-any.whl.metadata (49 kB)\n", - "Collecting typing-extensions>=4.11 (from azure-ai-projects==2.3.0)\n", - " Downloading typing_extensions-4.16.0-py3-none-any.whl.metadata (3.3 kB)\n", - "Collecting azure-identity>=1.15.0 (from azure-ai-projects==2.3.0)\n", - " Downloading azure_identity-1.25.3-py3-none-any.whl.metadata (91 kB)\n", - "Collecting openai>=2.8.0 (from azure-ai-projects==2.3.0)\n", - " Downloading openai-2.44.0-py3-none-any.whl.metadata (34 kB)\n", - "Collecting azure-storage-blob>=12.15.0 (from azure-ai-projects==2.3.0)\n", - " Downloading azure_storage_blob-12.30.0-py3-none-any.whl.metadata (26 kB)\n", - "Collecting requests>=2.21.0 (from azure-core>=1.37.0->azure-ai-projects==2.3.0)\n", - " Downloading requests-2.34.2-py3-none-any.whl.metadata (4.8 kB)\n", - "Collecting cryptography>=2.5 (from azure-identity>=1.15.0->azure-ai-projects==2.3.0)\n", - " Downloading cryptography-49.0.0-cp311-abi3-win_amd64.whl.metadata (4.3 kB)\n", - "Collecting msal>=1.35.1 (from azure-identity>=1.15.0->azure-ai-projects==2.3.0)\n", - " Downloading msal-1.37.0-py3-none-any.whl.metadata (11 kB)\n", - "Collecting msal-extensions>=1.2.0 (from azure-identity>=1.15.0->azure-ai-projects==2.3.0)\n", - " Downloading msal_extensions-1.3.1-py3-none-any.whl.metadata (7.8 kB)\n", - "Collecting anyio<5,>=3.5.0 (from openai>=2.8.0->azure-ai-projects==2.3.0)\n", - " Downloading anyio-4.14.1-py3-none-any.whl.metadata (4.6 kB)\n", - "Collecting distro<2,>=1.7.0 (from openai>=2.8.0->azure-ai-projects==2.3.0)\n", - " Downloading distro-1.9.0-py3-none-any.whl.metadata (6.8 kB)\n", - "Collecting httpx<1,>=0.23.0 (from openai>=2.8.0->azure-ai-projects==2.3.0)\n", - " Downloading httpx-0.28.1-py3-none-any.whl.metadata (7.1 kB)\n", - "Collecting jiter<1,>=0.10.0 (from openai>=2.8.0->azure-ai-projects==2.3.0)\n", - " Downloading jiter-0.16.0-cp312-cp312-win_amd64.whl.metadata (5.3 kB)\n", - "Collecting pydantic<3,>=1.9.0 (from openai>=2.8.0->azure-ai-projects==2.3.0)\n", - " Downloading pydantic-2.13.4-py3-none-any.whl.metadata (109 kB)\n", - "Collecting sniffio (from openai>=2.8.0->azure-ai-projects==2.3.0)\n", - " Downloading sniffio-1.3.1-py3-none-any.whl.metadata (3.9 kB)\n", - "Collecting tqdm>4 (from openai>=2.8.0->azure-ai-projects==2.3.0)\n", - " Downloading tqdm-4.68.4-py3-none-any.whl.metadata (57 kB)\n", - "Collecting idna>=2.8 (from anyio<5,>=3.5.0->openai>=2.8.0->azure-ai-projects==2.3.0)\n", - " Downloading idna-3.18-py3-none-any.whl.metadata (6.1 kB)\n", - "Collecting cffi>=2.0.0 (from cryptography>=2.5->azure-identity>=1.15.0->azure-ai-projects==2.3.0)\n", - " Downloading cffi-2.1.0-cp312-cp312-win_amd64.whl.metadata (2.6 kB)\n", - "Collecting certifi (from httpx<1,>=0.23.0->openai>=2.8.0->azure-ai-projects==2.3.0)\n", - " Downloading certifi-2026.6.17-py3-none-any.whl.metadata (2.5 kB)\n", - "Collecting httpcore==1.* (from httpx<1,>=0.23.0->openai>=2.8.0->azure-ai-projects==2.3.0)\n", - " Downloading httpcore-1.0.9-py3-none-any.whl.metadata (21 kB)\n", - "Collecting h11>=0.16 (from httpcore==1.*->httpx<1,>=0.23.0->openai>=2.8.0->azure-ai-projects==2.3.0)\n", - " Downloading h11-0.16.0-py3-none-any.whl.metadata (8.3 kB)\n", - "Collecting PyJWT<3,>=1.0.0 (from PyJWT[crypto]<3,>=1.0.0->msal>=1.35.1->azure-identity>=1.15.0->azure-ai-projects==2.3.0)\n", - " Downloading pyjwt-2.13.0-py3-none-any.whl.metadata (3.4 kB)\n", - "Collecting annotated-types>=0.6.0 (from pydantic<3,>=1.9.0->openai>=2.8.0->azure-ai-projects==2.3.0)\n", - " Downloading annotated_types-0.7.0-py3-none-any.whl.metadata (15 kB)\n", - "Collecting pydantic-core==2.46.4 (from pydantic<3,>=1.9.0->openai>=2.8.0->azure-ai-projects==2.3.0)\n", - " Downloading pydantic_core-2.46.4-cp312-cp312-win_amd64.whl.metadata (6.7 kB)\n", - "Collecting typing-inspection>=0.4.2 (from pydantic<3,>=1.9.0->openai>=2.8.0->azure-ai-projects==2.3.0)\n", - " Downloading typing_inspection-0.4.2-py3-none-any.whl.metadata (2.6 kB)\n", - "Collecting charset_normalizer<4,>=2 (from requests>=2.21.0->azure-core>=1.37.0->azure-ai-projects==2.3.0)\n", - " Downloading charset_normalizer-3.4.9-cp312-cp312-win_amd64.whl.metadata (42 kB)\n", - "Collecting urllib3<3,>=1.26 (from requests>=2.21.0->azure-core>=1.37.0->azure-ai-projects==2.3.0)\n", - " Downloading urllib3-2.7.0-py3-none-any.whl.metadata (6.9 kB)\n", - "Collecting colorama (from tqdm>4->openai>=2.8.0->azure-ai-projects==2.3.0)\n", - " Downloading colorama-0.4.6-py2.py3-none-any.whl.metadata (17 kB)\n", - "Collecting pycparser (from cffi>=2.0.0->cryptography>=2.5->azure-identity>=1.15.0->azure-ai-projects==2.3.0)\n", - " Downloading pycparser-3.0-py3-none-any.whl.metadata (8.2 kB)\n", - "Downloading azure_ai_projects-2.3.0-py3-none-any.whl (349 kB)\n", - "Downloading azure_core-1.41.0-py3-none-any.whl (220 kB)\n", - "Downloading azure_identity-1.25.3-py3-none-any.whl (192 kB)\n", - "Downloading azure_storage_blob-12.30.0-py3-none-any.whl (435 kB)\n", - "Downloading isodate-0.7.2-py3-none-any.whl (22 kB)\n", - "Downloading openai-2.44.0-py3-none-any.whl (1.4 MB)\n", - " ---------------------------------------- 0.0/1.4 MB ? eta -:--:--\n", - " ----------------------- ---------------- 0.8/1.4 MB 4.8 MB/s eta 0:00:01\n", - " ---------------------------------------- 1.4/1.4 MB 3.2 MB/s eta 0:00:00\n", - "Downloading typing_extensions-4.16.0-py3-none-any.whl (45 kB)\n", - "Downloading anyio-4.14.1-py3-none-any.whl (124 kB)\n", - "Downloading cryptography-49.0.0-cp311-abi3-win_amd64.whl (3.8 MB)\n", - " ---------------------------------------- 0.0/3.8 MB ? eta -:--:--\n", - " ------------- -------------------------- 1.3/3.8 MB 6.7 MB/s eta 0:00:01\n", - " --------------------------- ------------ 2.6/3.8 MB 6.3 MB/s eta 0:00:01\n", - " ---------------------------------------- 3.8/3.8 MB 6.3 MB/s eta 0:00:00\n", - "Downloading distro-1.9.0-py3-none-any.whl (20 kB)\n", - "Downloading httpx-0.28.1-py3-none-any.whl (73 kB)\n", - "Downloading httpcore-1.0.9-py3-none-any.whl (78 kB)\n", - "Downloading jiter-0.16.0-cp312-cp312-win_amd64.whl (196 kB)\n", - "Downloading msal-1.37.0-py3-none-any.whl (123 kB)\n", - "Downloading msal_extensions-1.3.1-py3-none-any.whl (20 kB)\n", - "Downloading pydantic-2.13.4-py3-none-any.whl (472 kB)\n", - "Downloading pydantic_core-2.46.4-cp312-cp312-win_amd64.whl (2.1 MB)\n", - " ---------------------------------------- 0.0/2.1 MB ? eta -:--:--\n", - " ------------------------- -------------- 1.3/2.1 MB 6.7 MB/s eta 0:00:01\n", - " ---------------------------------------- 2.1/2.1 MB 6.4 MB/s eta 0:00:00\n", - "Downloading requests-2.34.2-py3-none-any.whl (73 kB)\n", - "Downloading tqdm-4.68.4-py3-none-any.whl (676 kB)\n", - " ---------------------------------------- 0.0/676.6 kB ? eta -:--:--\n", - " ---------------------------------------- 676.6/676.6 kB 3.3 MB/s eta 0:00:00\n", - "Downloading sniffio-1.3.1-py3-none-any.whl (10 kB)\n", - "Downloading annotated_types-0.7.0-py3-none-any.whl (13 kB)\n", - "Downloading certifi-2026.6.17-py3-none-any.whl (133 kB)\n", - "Downloading cffi-2.1.0-cp312-cp312-win_amd64.whl (185 kB)\n", - "Downloading charset_normalizer-3.4.9-cp312-cp312-win_amd64.whl (162 kB)\n", - "Downloading idna-3.18-py3-none-any.whl (65 kB)\n", - "Downloading pyjwt-2.13.0-py3-none-any.whl (31 kB)\n", - "Downloading typing_inspection-0.4.2-py3-none-any.whl (14 kB)\n", - "Downloading urllib3-2.7.0-py3-none-any.whl (131 kB)\n", - "Downloading colorama-0.4.6-py2.py3-none-any.whl (25 kB)\n", - "Downloading h11-0.16.0-py3-none-any.whl (37 kB)\n", - "Downloading pycparser-3.0-py3-none-any.whl (48 kB)\n", - "Installing collected packages: urllib3, typing-extensions, sniffio, PyJWT, pycparser, jiter, isodate, idna, h11, distro, colorama, charset_normalizer, certifi, annotated-types, typing-inspection, tqdm, requests, pydantic-core, httpcore, cffi, anyio, pydantic, httpx, cryptography, azure-core, openai, azure-storage-blob, msal, msal-extensions, azure-identity, azure-ai-projects\n", - " Attempting uninstall: urllib3\n", - " Found existing installation: urllib3 2.7.0\n", - " Uninstalling urllib3-2.7.0:\n", - " Successfully uninstalled urllib3-2.7.0\n", - " Attempting uninstall: typing-extensions\n", - " Found existing installation: typing_extensions 4.16.0\n", - " Uninstalling typing_extensions-4.16.0:\n", - " Successfully uninstalled typing_extensions-4.16.0\n", - " Attempting uninstall: sniffio\n", - " Found existing installation: sniffio 1.3.1\n", - " Uninstalling sniffio-1.3.1:\n", - " Successfully uninstalled sniffio-1.3.1\n", - " Attempting uninstall: PyJWT\n", - " Found existing installation: PyJWT 2.13.0\n", - " Uninstalling PyJWT-2.13.0:\n", - " Successfully uninstalled PyJWT-2.13.0\n", - " Attempting uninstall: pycparser\n", - " Found existing installation: pycparser 3.0\n", - " Uninstalling pycparser-3.0:\n", - " Successfully uninstalled pycparser-3.0\n", - " Attempting uninstall: jiter\n", - " Found existing installation: jiter 0.16.0\n", - " Uninstalling jiter-0.16.0:\n", - " Successfully uninstalled jiter-0.16.0\n", - " Attempting uninstall: isodate\n", - " Found existing installation: isodate 0.7.2\n", - " Uninstalling isodate-0.7.2:\n", - " Successfully uninstalled isodate-0.7.2\n", - " Attempting uninstall: idna\n", - " Found existing installation: idna 3.18\n", - " Uninstalling idna-3.18:\n", - " Successfully uninstalled idna-3.18\n", - " Attempting uninstall: h11\n", - " Found existing installation: h11 0.16.0\n", - " Uninstalling h11-0.16.0:\n", - " Successfully uninstalled h11-0.16.0\n", - " Attempting uninstall: distro\n", - " Found existing installation: distro 1.9.0\n", - " Uninstalling distro-1.9.0:\n", - " Successfully uninstalled distro-1.9.0\n", - " Attempting uninstall: colorama\n", - " Found existing installation: colorama 0.4.6\n", - " Uninstalling colorama-0.4.6:\n", - " Successfully uninstalled colorama-0.4.6\n", - "Note: you may need to restart the kernel to use updated packages.\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "WARNING: Ignoring invalid distribution ~harset-normalizer (c:\\Users\\ollisgeorge\\AppData\\Local\\Programs\\Python\\Python312-x64\\Lib\\site-packages)\n", - "WARNING: Ignoring invalid distribution ~harset-normalizer (c:\\Users\\ollisgeorge\\AppData\\Local\\Programs\\Python\\Python312-x64\\Lib\\site-packages)\n", - "WARNING: Ignoring invalid distribution ~harset-normalizer (c:\\Users\\ollisgeorge\\AppData\\Local\\Programs\\Python\\Python312-x64\\Lib\\site-packages)\n", - " WARNING: The script idna.exe is installed in 'c:\\Users\\ollisgeorge\\AppData\\Local\\Programs\\Python\\Python312-x64\\Scripts' which is not on PATH.\n", - " Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.\n", - " WARNING: The script distro.exe is installed in 'c:\\Users\\ollisgeorge\\AppData\\Local\\Programs\\Python\\Python312-x64\\Scripts' which is not on PATH.\n", - " Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.\n", - "ERROR: Could not install packages due to an OSError: [WinError 5] Access is denied: 'c:\\\\Users\\\\ollisgeorge\\\\AppData\\\\Local\\\\Programs\\\\Python\\\\Python312-x64\\\\Lib\\\\site-packages\\\\charset_normalizer\\\\cd.cp312-win_amd64.pyd'\n", - "Consider using the `--user` option or check the permissions.\n", - "\n", - "\n", - "[notice] A new release of pip is available: 25.0.1 -> 26.1.2\n", - "[notice] To update, run: python.exe -m pip install --upgrade pip\n" - ] - } - ], + "outputs": [], "source": [ "pip install azure-ai-projects==2.3.0 --force-reinstall --no-cache-dir" ] }, + { + "cell_type": "markdown", + "id": "2c7efedf", + "metadata": {}, + "source": [ + "### Create the hosted agent in Foundry\n", + "\n", + "This cell deploys your Strands container as a **Hosted Agent** in your Foundry project. \n", + "\n", + "**Key configuration:**\n", + "- **Protocol**: Responses v1.0.0 (standard for Foundry hosted agents)\n", + "- **Resources**: 1 CPU, 2Gi memory (adjust based on your agent needs)\n", + "- **Environment variables**: \n", + " - `AZURE_OPENAI_ENDPOINT`: Points to APIM inference API for your agent to call models\n", + " - `APIM_SUBSCRIPTION_KEY`: APIM subscription key for authentication\n", + " - `AZURE_OPENAI_DEPLOYMENT`: Model name to use (e.g., `gpt-5-mini`)\n", + "\n", + "The agent will be created with a version suffix (auto-assigned by Foundry). After creation, it transitions to \"Running\" state and is ready to accept requests via the Responses API." + ] + }, { "cell_type": "code", - "execution_count": 22, + "execution_count": null, "id": "89e98ee4", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "PROJECT_ENDPOINT: https://foundry-agents-xhep4wovroziu.services.ai.azure.com/api/projects/default-foundry-agents\n", - "AGENT_NAME: strands-agent\n", - "Agent created: strands-agent, version: 3, id strands-agent:3, endpomint: agent.version\n" - ] - } - ], + "outputs": [], "source": [ "from azure.ai.projects import AIProjectClient\n", "from azure.ai.projects.models import (\n", @@ -806,14 +186,14 @@ "from azure.identity import DefaultAzureCredential, AzureCliCredential\n", "\n", "# Placeholder values - update before running\n", - "PROJECT_ENDPOINT = \"https://foundry-agents-xhep4wovroziu.services.ai.azure.com/api/projects/default-foundry-agents\"\n", + "PROJECT_ENDPOINT = \"https://foundry-agents-xxxxxxx.services.ai.azure.com/api/projects/default-foundry-agents\"\n", "AGENT_NAME = \"strands-agent\"\n", "\n", "# APIM inference endpoint for model calls.\n", - "AZURE_OPENAI_ENDPOINT = \"https://apim-xhep4wovroziu.azure-api.net/inference/models\"\n", + "AZURE_OPENAI_ENDPOINT = \"https://apim-xxxxxxxxxx.azure-api.net/inference/models\"\n", "AZURE_OPENAI_API_VERSION = \"2024-05-01-preview\"\n", "AZURE_OPENAI_DEPLOYMENT = \"gpt-5-mini\"\n", - "APIM_SUBSCRIPTION_KEY = \"0ff2e5d4b7144ee7aa009eadbee3bc21\"\n", + "APIM_SUBSCRIPTION_KEY = \"xxxxxxxxx\"\n", "\n", "print(f\"PROJECT_ENDPOINT: {PROJECT_ENDPOINT}\")\n", "print(f\"AGENT_NAME: {AGENT_NAME}\")\n", @@ -854,84 +234,30 @@ "id": "faaf591d", "metadata": {}, "source": [ - "## 4. Test The Hosted Agent\n", + "## 3. Test The Hosted Agent (Direct)\n", "\n", - "Sends a request directly to the Foundry Hosted Agent Responses API using a bearer token from your CLI credential." - ] - }, - { - "cell_type": "markdown", - "id": "3ba0fe43", - "metadata": {}, - "source": [ - "## 3. Check Agent Status\n", + "**Purpose:** Validate your agent works by calling the Foundry Responses API directly using your Azure CLI credential.\n", + "\n", + "This is your baseline test—if this fails, APIM proxy tests will also fail. Use this to confirm:\n", + "- Agent reached \"Running\" status ✅\n", + "- Network connectivity to Foundry is working ✅\n", + "- Authentication with your credential works ✅\n", + "- Agent payload format is correct ✅\n", "\n", - "Wait for the hosted agent to transition to \"Running\" state before calling it." + "**How it works:**\n", + "- Endpoint: `{PROJECT_ENDPOINT}/agents/{AGENT_NAME}/endpoint/protocols/openai/responses?api-version=v1`\n", + "- Auth: Bearer token with `https://ai.azure.com/.default` audience (from your Azure CLI login)\n", + "- Headers: Includes `Foundry-Features: HostedAgents=V1Preview` (required for preview access)\n", + "\n", + "If this test succeeds, you know the agent itself is working correctly." ] }, { "cell_type": "code", - "execution_count": 30, + "execution_count": null, "id": "93be92da", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "POST https://foundry-agents-xhep4wovroziu.services.ai.azure.com/api/projects/default-foundry-agents/agents/strands-agent/endpoint/protocols/openai/responses?api-version=v1\n", - "Agent Name: strands-agent\n", - "Payload: {\n", - " \"input\": \"Hello! What can you help me with? What's the weather in Paris today?\",\n", - " \"stream\": false\n", - "}\n", - "\n", - "Status: 200\n", - "Headers: {'Content-Length': '1187', 'Content-Type': 'application/json', 'content-encoding': 'identity', 'request-context': 'appId=', 'x-ms-response-type': 'standard', 'x-request-id': '9db970915a015177e285d2d9b66cc93f,9db970915a015177e285d2d9b66cc93f', 'api-supported-versions': '1.0,2025-05-15-preview,2025-11-15-preview', 'x-agent-session-id': '23d1816e1019ada17936cbd434b60fc35826f3aac5359d1f36b9b041185497b', 'x-platform-server': 'azure-ai-agentserver-core/2.0.0b7 (python/3.12) azure-ai-agentserver-responses/1.0.0b8 (python/3.12)', 'azureml-served-by-cluster': 'hyena-swedencentral-02', 'apim-request-id': '1f0cbb12-52b6-43f6-a7a4-d57e28ee72a9', 'Strict-Transport-Security': 'max-age=31536000; includeSubDomains; preload', 'x-content-type-options': 'nosniff', 'x-ms-region': 'Sweden Central', 'Access-Control-Expose-Headers': 'Operation-Location,Location,Apim-Request-Id,x-agent-session-id,x-agent-invocation-id', 'Date': 'Wed, 08 Jul 2026 18:12:32 GMT'}\n", - "Response text (first 500 chars): {\"id\":\"caresp_e0231748c6fea86400dfbs4B5CHUWPzROuuiXS2O9TpGS2YYpM\",\"object\":\"response\",\"output\":[{\"type\":\"message\",\"id\":\"msg_e0231748c6fea86400qh5yTL1cyHak7ylRDo9iUzaGlDLJ6tHq\",\"role\":\"assistant\",\"content\":[{\"type\":\"output_text\",\"text\":\"Hi — I can help with facts and explanations, summarize or rewrite text, brainstorm and plan, solve math and coding problems, translate, and more. Ask me to dive deeper into any of those.\\n\\nCurrent weather in Paris: -2 °C (about 28.4 °F). That’s below freezing — d\n", - "\n", - "Response JSON:\n", - "{\n", - " \"id\": \"caresp_e0231748c6fea86400dfbs4B5CHUWPzROuuiXS2O9TpGS2YYpM\",\n", - " \"object\": \"response\",\n", - " \"output\": [\n", - " {\n", - " \"type\": \"message\",\n", - " \"id\": \"msg_e0231748c6fea86400qh5yTL1cyHak7ylRDo9iUzaGlDLJ6tHq\",\n", - " \"role\": \"assistant\",\n", - " \"content\": [\n", - " {\n", - " \"type\": \"output_text\",\n", - " \"text\": \"Hi \\u2014 I can help with facts and explanations, summarize or rewrite text, brainstorm and plan, solve math and coding problems, translate, and more. Ask me to dive deeper into any of those.\\n\\nCurrent weather in Paris: -2 \\u00b0C (about 28.4 \\u00b0F). That\\u2019s below freezing \\u2014 dress warmly and watch for icy spots. Would you like a forecast for today, an hourly breakdown, or weather for another city?\",\n", - " \"annotations\": [],\n", - " \"logprobs\": []\n", - " }\n", - " ],\n", - " \"status\": \"completed\",\n", - " \"response_id\": \"caresp_e0231748c6fea86400dfbs4B5CHUWPzROuuiXS2O9TpGS2YYpM\",\n", - " \"agent_reference\": {\n", - " \"type\": \"agent_reference\",\n", - " \"name\": \"strands-agent\",\n", - " \"version\": \"3\"\n", - " }\n", - " }\n", - " ],\n", - " \"created_at\": 1783534347,\n", - " \"agent_reference\": {\n", - " \"type\": \"agent_reference\",\n", - " \"name\": \"strands-agent\",\n", - " \"version\": \"3\"\n", - " },\n", - " \"status\": \"completed\",\n", - " \"completed_at\": 1783534352,\n", - " \"response_id\": \"caresp_e0231748c6fea86400dfbs4B5CHUWPzROuuiXS2O9TpGS2YYpM\",\n", - " \"model\": \"\",\n", - " \"agent_session_id\": \"23d1816e1019ada17936cbd434b60fc35826f3aac5359d1f36b9b041185497b\",\n", - " \"background\": false\n", - "}\n" - ] - } - ], + "outputs": [], "source": [ "import json\n", "import requests\n", @@ -989,78 +315,73 @@ }, { "cell_type": "markdown", - "id": "cc246a06", + "id": "ccdf6775", "metadata": {}, "source": [ - "## 5. Test Through APIM (After Deployment)\n", + "## 4. Test The Hosted Agent Via APIM\n", + "\n", + "**Purpose:** Route your request through Azure API Management instead of calling Foundry directly.\n", + "\n", + "This validates the production-like path:\n", + "- Client → APIM Gateway → Foundry Hosted Agent Responses API\n", + "\n", + "**What APIM does automatically:**\n", + "- Injects managed identity bearer token for Foundry authentication\n", + "- Enforces `Content-Type: application/json` header\n", + "- Enforces `api-version: 2025-05-15-preview` query parameter\n", + "- Injects `Foundry-Features: HostedAgents=V1Preview` header for preview access\n", + "- Your client only needs the APIM subscription key (`api-key` header)\n", "\n", - "Once you've deployed the agent and configured APIM (via the main deployment notebook with `enable_hosted_agent_responses_api=True`), call the agent through APIM instead of directly.\n", - "This ensures the full production path works: client → APIM → Foundry Agent → container." + "**Configuration details** are in [hosted-agent-policy.xml](../../hosted-agent-policy.xml)—update there if you need to change defaults.\n", + "\n", + "Compare this test result with Section 3 to ensure both paths (direct and APIM-proxied) produce consistent responses." ] }, { "cell_type": "code", - "execution_count": 31, - "id": "aa0daead", + "execution_count": null, + "id": "4cae98de", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "POST https://apim-xhep4wovroziu.azure-api.net/hosted-agent-responses/endpoint/protocols/openai/responses?api-version=v1\n", - "Agent ID: strands-agent:3\n", - "Headers (excluding key): Content-Type, api-key\n", - "Payload: {\n", - " \"input\": \"Hello from APIM!\",\n", - " \"stream\": false\n", - "}\n", - "\n", - "Status: 403\n", - "Response headers (first 500 chars): {'Content-Length': '0', 'Date': 'Wed, 08 Jul 2026 18:13:38 GMT', 'Access-Control-Expose-Headers': 'Operation-Location,Location,Apim-Request-Id,x-agent-session-id,x-agent-invocation-id', 'Strict-Transport-Security': 'max-age=31536000; includeSubDomains; preload', 'request-context': 'appId=', 'x-ms-response-type': 'standard', 'azureml-served-by-cluster': 'hyena-swedencentral-01', 'apim-request-id': 'dd903f53-4eb6-4e34-b801-f49056f454c4', 'X-Content-Type-Options': 'nosniff', 'x-ms-region': 'Sweden \n", - "\n", - "✗ Error: 403\n" - ] - } - ], + "outputs": [], "source": [ - "# After deploying the hosted agent and re-running the main deployment notebook,\n", - "# call the agent through APIM instead of directly.\n", - "#\n", - "# Values from main deployment:\n", - "# - APIM_GATEWAY_URL: from deployment outputs (e.g., https://apim-.azure-api.net)\n", - "# - APIM_SUBSCRIPTION_KEY: from the 'starter' subscription created in deployment\n", - "# - HOSTED_AGENT_ID: the agent ID from agent creation (e.g., \"strands-agent:3\")\n", + "import json\n", + "import requests\n", + "\n", + "# APIM configuration with defaults\n", + "DEFAULT_API_VERSION = \"2025-05-15-preview\"\n", + "DEFAULT_CONTENT_TYPE = \"application/json\"\n", "\n", - "# Update these values from the deployment outputs\n", - "APIM_GATEWAY_URL = \"https://apim-xhep4wovroziu.azure-api.net\" # From deployment output\n", - "HOSTED_AGENT_RESPONSES_PATH = \"hosted-agent-responses\" # From main.bicep parameter\n", - "APIM_SUBSCRIPTION_KEY = \"0ff2e5d4b7144ee7aa009eadbee3bc21\" # From deployment (APIM subscription key, not APIM Key)\n", - "HOSTED_AGENT_ID = \"strands-agent:3\" # Set this to your deployed agent ID from cell 7\n", + "# APIM endpoint and version\n", + "apim_url = f\"https://apim-{APIM_SUFFIX}.azure-api.net/hosted-agent-responses/endpoint/protocols/openai/responses\"\n", + "api_version = DEFAULT_API_VERSION\n", "\n", - "# Build APIM URL: path/endpoint/protocols/openai/responses\n", - "# The /endpoint/protocols/openai/responses portion is appended to the Foundry agent endpoint by APIM operation\n", - "apim_url = f\"{APIM_GATEWAY_URL}/{HOSTED_AGENT_RESPONSES_PATH}/endpoint/protocols/openai/responses\"\n", + "# Build the correct URL with api-version query parameter\n", + "url = f\"{apim_url}?api-version={api_version}\"\n", "\n", + "# Headers for APIM: use api-key header with subscription key\n", "headers = {\n", - " \"Content-Type\": \"application/json\",\n", - " \"api-key\": APIM_SUBSCRIPTION_KEY, # APIM subscription key for access control\n", + " \"api-key\": APIM_SUBSCRIPTION_KEY,\n", + " \"Content-Type\": DEFAULT_CONTENT_TYPE,\n", + " \"Foundry-Features\": \"HostedAgents=V1Preview\", # Required for preview\n", "}\n", "\n", "payload = {\n", - " \"input\": \"Hello from APIM!\",\n", + " \"input\": \"Hello! What can you help me with? What's the weather in Paris today?\",\n", " \"stream\": False,\n", "}\n", "\n", - "print(f\"POST {apim_url}?api-version=v1\")\n", - "print(f\"Agent ID: {HOSTED_AGENT_ID}\")\n", - "print(f\"Headers (excluding key): Content-Type, api-key\")\n", + "print(f\"POST {url}\")\n", + "print(f\"APIM Suffix: {APIM_SUFFIX}\")\n", + "print(f\"API Version: {api_version}\")\n", + "print(f\"Content-Type: {DEFAULT_CONTENT_TYPE}\")\n", + "print(f\"Headers: api-key={APIM_SUBSCRIPTION_KEY[:20]}..., Content-Type, Foundry-Features\")\n", "print(f\"Payload: {json.dumps(payload, indent=2)}\")\n", "print()\n", "\n", - "response = requests.post(apim_url, headers=headers, json=payload, params={\"api-version\": \"v1\"})\n", + "response = requests.post(url, headers=headers, json=payload)\n", "print(f\"Status: {response.status_code}\")\n", - "print(f\"Response headers (first 500 chars): {str(dict(response.headers))[:500]}\")\n", + "print(f\"Headers: {dict(response.headers)}\")\n", + "print(f\"Response text (first 500 chars): {response.text[:500]}\")\n", "print()\n", "\n", "if response.status_code == 200:\n", @@ -1069,55 +390,18 @@ " print(f\"Response JSON:\")\n", " print(json.dumps(result, indent=2))\n", " if \"output_text\" in result:\n", - " print(f\"\\n✓ Agent response via APIM:\\n{result['output_text']}\")\n", + " print(f\"\\nAgent output:\\n{result['output_text']}\")\n", " except json.JSONDecodeError as e:\n", " print(f\"Failed to parse JSON: {e}\")\n", " print(f\"Raw response: {response.text}\")\n", "else:\n", - " print(f\"✗ Error: {response.status_code}\")\n", + " print(f\"Error: {response.status_code}\")\n", " if response.text:\n", " try:\n", " print(json.dumps(response.json(), indent=2))\n", " except:\n", " print(response.text)" ] - }, - { - "cell_type": "markdown", - "id": "5927b8ad", - "metadata": {}, - "source": [ - "## APIM Configuration Checklist\n", - "\n", - "When the main deployment notebook runs with `enable_hosted_agent_responses_api=True` and a valid `hosted_agent_id`, APIM should be configured as follows:\n", - "\n", - "**API: `hosted-agent-responses-api`**\n", - "- Path: `hosted-agent-responses` (configurable via `hostedAgentResponsesApiPath`)\n", - "- Backend: `{foundry-agents-account}/agents/{hostedAgentId}` (direct Foundry endpoint)\n", - "\n", - "**Operation: `create-response`**\n", - "- Method: `POST`\n", - "- URL template: `/endpoint/protocols/openai/responses`\n", - "- Full path when called: `/hosted-agent-responses/endpoint/protocols/openai/responses`\n", - "\n", - "**Policy (inbound):**\n", - "- ✓ Authenticate using **managed identity** (audience: `https://cognitiveservices.azure.com`) — APIM calls Foundry with its identity\n", - "- ✓ Set `Authorization` header to bearer token from managed identity\n", - "- ✓ Set `api-version` query parameter to `2025-05-15-preview` (the Foundry Hosted Agent API version)\n", - "\n", - "**Authentication for client → APIM:**\n", - "- Subscription key required (`api-key` header or `?api-key=` query param)\n", - "- Subscription: `starter` (created by deployment)\n", - "\n", - "**Full request flow:**\n", - "1. Client calls: `POST https://apim-xyz.azure-api.net/hosted-agent-responses/endpoint/protocols/openai/responses?api-version=v1`\n", - "2. Client provides: `api-key: ` (from APIM subscription)\n", - "3. APIM validates subscription → extracts managed identity token\n", - "4. APIM calls Foundry: `POST https://foundry-agents-xyz.../api/projects/.../agents/{agentId}/endpoint/protocols/openai/responses?api-version=2025-05-15-preview`\n", - "5. APIM provides: `Authorization: Bearer ` (managed identity token with `https://cognitiveservices.azure.com` audience)\n", - "\n", - "If the deployment succeeded and the agent is running, the next cell will verify the APIM configuration is working." - ] } ], "metadata": { From da2f68d4418d1e1fde6801ec51c54081616d08af Mon Sep 17 00:00:00 2001 From: George Ollis Date: Wed, 8 Jul 2026 20:30:07 +0100 Subject: [PATCH 04/17] Enhance README for Strands Agent: expand setup instructions, deployment architecture, and monitoring details --- .../main.bicep | 47 +++++- .../src/responses/agents/strands/README.md | 144 +++++++++++++++--- 2 files changed, 173 insertions(+), 18 deletions(-) diff --git a/labs/ai-foundry-hosted-agents-custom-framework/main.bicep b/labs/ai-foundry-hosted-agents-custom-framework/main.bicep index f96c8ca4..5e029bc7 100644 --- a/labs/ai-foundry-hosted-agents-custom-framework/main.bicep +++ b/labs/ai-foundry-hosted-agents-custom-framework/main.bicep @@ -148,13 +148,47 @@ resource agentFoundryUserRoleAssignments 'Microsoft.Authorization/roleAssignment } }] +// Reference the Foundry projects created by the module to assign ACR roles to their managed identities. +resource modelFoundryProject 'Microsoft.CognitiveServices/accounts/projects@2024-10-01' existing = { + parent: aiFoundryAccounts[0] + name: '${foundryProjectName}-foundry-models' +} + +resource agentFoundryProject 'Microsoft.CognitiveServices/accounts/projects@2024-10-01' existing = { + parent: aiFoundryAccounts[foundryAgentAiServiceIndex] + name: '${foundryProjectName}-foundry-agents' +} + // Repository-level ACR roles (ABAC-enabled roles) var acrRepositoryReaderRoleId = resourceId('Microsoft.Authorization/roleDefinitions', 'b93aa761-3e63-49ed-ac28-beffa264f7ac') var acrRepositoryWriterRoleId = resourceId('Microsoft.Authorization/roleDefinitions', '2a1e307c-b015-4ebd-883e-5b7698a07328') var acrRepositoryCatalogListerRoleId = resourceId('Microsoft.Authorization/roleDefinitions', 'bfdb9389-c9a5-478a-bb2f-ba9ca092c3c7') var acrPullRoleId = resourceId('Microsoft.Authorization/roleDefinitions', '7f951dda-4ed3-4680-a7ca-43fe172d538d') +var foundryModelAccountName = '${aiServicesConfig[0].name}-${resourceSuffix}' var foundryAgentAccountName = '${aiServicesConfig[foundryAgentAiServiceIndex].name}-${resourceSuffix}' +// Assign AcrPull to Foundry models account for any container image pulls +resource foundryModelAcrPullRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid(resourceGroup().id, foundryModelAccountName, acrPullRoleId) + scope: containerRegistry + properties: { + roleDefinitionId: acrPullRoleId + principalId: foundryModule.outputs.extendedAIServicesConfig[0].principalId + principalType: 'ServicePrincipal' + } +} + +// Assign AcrPull to Foundry models project for container image pulls +resource foundryModelProjectAcrPullRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid(resourceGroup().id, modelFoundryProject.id, acrPullRoleId) + scope: containerRegistry + properties: { + roleDefinitionId: acrPullRoleId + principalId: modelFoundryProject.identity.principalId + principalType: 'ServicePrincipal' + } +} + resource foundryAgentAcrRepositoryReaderRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { name: guid(resourceGroup().id, foundryAgentAccountName, acrRepositoryReaderRoleId) scope: containerRegistry @@ -165,7 +199,7 @@ resource foundryAgentAcrRepositoryReaderRoleAssignment 'Microsoft.Authorization/ } } -// Assign AcrPull to Foundry project for container image pulls +// Assign AcrPull to Foundry hosted-agent account for container image pulls resource foundryAgentAcrPullRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { name: guid(resourceGroup().id, foundryAgentAccountName, acrPullRoleId) scope: containerRegistry @@ -176,6 +210,17 @@ resource foundryAgentAcrPullRoleAssignment 'Microsoft.Authorization/roleAssignme } } +// Assign AcrPull to Foundry hosted-agent project for container image pulls +resource foundryAgentProjectAcrPullRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid(resourceGroup().id, agentFoundryProject.id, acrPullRoleId) + scope: containerRegistry + properties: { + roleDefinitionId: acrPullRoleId + principalId: agentFoundryProject.identity.principalId + principalType: 'ServicePrincipal' + } +} + resource deployerAcrRepositoryWriterRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { name: guid(resourceGroup().id, deployer().objectId, containerRegistry.id, acrRepositoryWriterRoleId) scope: containerRegistry diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/README.md b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/README.md index fef9d054..78b1388d 100644 --- a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/README.md +++ b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/README.md @@ -1,32 +1,142 @@ # Strands Agent on Foundry Hosted Agents -This sample code shows you how to run a Strands agent in Foundry Hosted Agents. +This sample shows how to build, deploy, and test a **Strands-based custom agent** on Microsoft Foundry Hosted Agents using the **Responses protocol v1.0.0**. + +The agent runs in a containerized environment managed by Foundry, with full observability, RBAC identity, and optional APIM gateway integration. ![Strands Hosted Agent Sample](image.png) ## What Is Included -- `main.py`: Strands agent server implementation (Responses protocol) with tool calling and streaming. -- `Dockerfile`: Container definition for hosting the agent in Foundry Hosted Agents. -- `01_hosted_agent_strands_setup.ipynb`: End-to-end setup workbook. -- `requirements.txt`: Python dependencies. +- **`main.py`**: Strands agent server implementing the Responses protocol with tool calling and streaming. +- **`Dockerfile`**: Container image definition for Foundry Hosted Agents (builds for Linux amd64). +- **`requirements.txt`**: Python dependencies (strands, FastAPI, etc.). +- **`01_hosted_agent_strands_setup.ipynb`**: End-to-end setup and testing notebook with 4 sections: + 1. Build and push container to ACR + 2. Create hosted agent version in Foundry + 3. Test agent directly via Foundry Responses API (baseline validation) + 4. Test agent via APIM gateway (production-like path with managed identity auth) + +## How It Works + +### Responses Protocol + +Your Strands agent implements the **Responses protocol v1.0.0**, which is Foundry's standard for hosted agents: +- HTTP-based request/response model (no WebSocket or streaming required for basic cases) +- Request: `POST /endpoint/protocols/openai/responses?api-version=v1` +- Request body: `{ "input": "", "stream": false }` +- Response: `{ "output_text": "" }` (or streaming deltas) + +Your Foundry project manages the deployment, scaling, health checks, and lifecycle. + +### Deployment Architecture + +``` +Client + ↓ +APIM Gateway (managed identity injection, header/param enforcement) + ↓ +Foundry Hosted Agent (runs your Strands container) + ↓ +APIM Inference API (agent calls models via this endpoint) + ↓ +OpenAI (GPT-5-Mini) +``` + +**Authentication flow:** +- Client → APIM: Use `api-key` header (APIM subscription key) +- APIM → Foundry: APIM's managed identity fetches bearer token for `https://ai.azure.com` +- Agent → Models: Agent uses APIM inference endpoint with its own APIM subscription key ## Get Started -1. Open and run `01_hosted_agent_strands_setup.ipynb` from top to bottom. -2. Build and push the container image to your Azure Container Registry. -3. Create a hosted agent version in your Foundry project. -4. Grant required permissions (including Foundry role assignment for the hosted agent identity). -5. Test prompts against the deployed hosted agent. +### Step 1: Configure Your Setup + +Open `01_hosted_agent_strands_setup.ipynb` and fill in the configuration variables at the top: +- `ACR_NAME`: Your Azure Container Registry name +- `IMAGE_NAME`: Container image name (usually `strands-agent`) +- `IMAGE_TAG`: Semantic version (e.g., `1.0.0`) +- `PROJECT_ENDPOINT`: Foundry project endpoint (from infrastructure deployment) +- `AZURE_OPENAI_ENDPOINT`: APIM inference API endpoint +- `APIM_SUBSCRIPTION_KEY`: APIM subscription key +- `APIM_SUFFIX`: Your APIM instance suffix + +### Step 2: Build & Push Container + +Run **Section 1** of the notebook: +- Builds a Docker image: `docker build -t {ACR_URI} --platform linux/amd64 .` +- Pushes to ACR: `docker push {ACR_URI}` + +The `--platform linux/amd64` flag ensures compatibility with Foundry's Linux hosting. + +### Step 3: Create Hosted Agent + +Run **Section 2** of the notebook: +- Creates a HostedAgentDefinition with your container image +- Specifies resource allocation (1 CPU, 2Gi memory) +- Sets environment variables for your agent to reach models +- Foundry automatically pulls the image and starts your container + +Once the agent transitions to "Running" state, it's ready for testing. + +### Step 4: Validate Agent Locally + +Run **Section 3** ("Test Direct"): +- Calls Foundry's Responses API directly using your Azure CLI credential +- No APIM involvement—validates agent and basic connectivity +- Helpful for troubleshooting deployment issues + +If this test fails, check agent status in Foundry or review container logs. + +### Step 5: Test via APIM Gateway (Production Path) + +Run **Section 4** ("Test via APIM"): +- Routes through APIM gateway using `api-key` header +- APIM automatically: + - Injects managed identity bearer token + - Enforces `Content-Type: application/json` + - Enforces `api-version: 2025-05-15-preview` + - Injects `Foundry-Features: HostedAgents=V1Preview` (required for preview) +- Validates end-to-end production path + +Policy configuration is in `../../hosted-agent-policy.xml` for customization. ## Prerequisites -- Azure subscription with access to Microsoft Foundry and Azure Container Registry. -- Permission to push images to the target ACR repository. -- Permission to assign RBAC roles on the Foundry resource scope. -- Python environment with the dependencies in `requirements.txt`. +- Microsoft Foundry resources deployed (see parent [infrastructure notebook](../../ai-foundry-hosted-agents-custom-framework.ipynb)) +- Azure CLI installed and authenticated (`az login`) +- Docker Desktop installed and running +- Python 3.12+ with dependencies: `pip install azure-ai-projects azure-identity requests` +- Azure subscription with permissions to: + - Push images to ACR + - Create agent versions in Foundry + - Assign roles (for RBAC setup) + +## Key Configuration Notes + +- **Agent name**: Should match `hosted_agent_id` parameter from the infrastructure deployment (without version suffix). +- **Model endpoint**: Your agent calls the APIM **inference** API, not the hosted-agent API. +- **Token audience**: + - Direct tests use `https://ai.azure.com/.default` + - APIM uses `https://ai.azure.com` (managed identity) +- **No hard-coded API keys in agent**: The agent gets credentials through environment variables injected at deployment time. + +## Monitoring & Debugging + +- **Application Insights**: Monitor traces, dependencies, and performance +- **APIM Trace Tool**: In Azure Portal → APIM → Diagnose and solve problems → Trace + - Re-run a test while tracing to see detailed request/response flow + - Useful for debugging authentication, routing, or header issues +- **Foundry Agent Details**: View agent status, logs, and deployment history in Foundry portal + +## Testing Patterns -## Notes +**If Section 3 works but Section 4 fails:** +- APIM policy issue likely (verify `hosted-agent-policy.xml`) +- Use APIM Trace to inspect inbound/outbound traffic +- Check managed identity token generation -- This sample is configured for identity-based auth patterns (no hard-coded OpenAI API key in `main.py`). -- Use the notebook placeholders to provide your own project, registry, and deployment values. +**If both tests fail:** +- Agent may not be in "Running" state +- Check ACR image URI and permissions +- Review Foundry agent logs for startup errors From 5402df2c9d128f58da585155c5ed2d161bf4640f Mon Sep 17 00:00:00 2001 From: George Ollis Date: Wed, 8 Jul 2026 20:39:40 +0100 Subject: [PATCH 05/17] Fix YAML formatting --- .../README.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/labs/ai-foundry-hosted-agents-custom-framework/README.md b/labs/ai-foundry-hosted-agents-custom-framework/README.md index 379f0977..02929c22 100644 --- a/labs/ai-foundry-hosted-agents-custom-framework/README.md +++ b/labs/ai-foundry-hosted-agents-custom-framework/README.md @@ -2,17 +2,16 @@ name: "AI Foundry Hosted Agents (Custom Frameworks)" architectureDiagram: images/ai-foundry-hosted-agents.gif categories: - - AI Agents + - AI Agents services: - - Microsoft Foundry - - Hosted Agents - - Azure API Management - - Container Registry + - Microsoft Foundry + - Hosted Agents + - Azure API Management + - Container Registry shortDescription: Deploy AI Foundry Hosted Agents built with custom frameworks, including Pydantic AI and Strands. detailedDescription: This lab provides custom framework examples for AI Foundry Hosted Agents, showing how to package and deploy hosted agents built with Pydantic AI and Strands to Azure Container Apps. It includes a Bicep deployment for Azure API Management, Azure AI Foundry, and a GPT-5-Mini model deployment, plus end-to-end setup notebooks and Dockerfiles. authors: - - nourshaker-msft - - georgeollis + - georgeollis tags: [] --- From fdac43fd7ff27da4dde25b8553b62eea0b3f5c81 Mon Sep 17 00:00:00 2001 From: George Ollis Date: Thu, 9 Jul 2026 13:20:46 +0100 Subject: [PATCH 06/17] Refactor code structure for improved readability and maintainability --- .../README.md | 26 +- ...undry-hosted-agents-custom-framework.ipynb | 1832 ++++++++++++++++- .../hosted-agent-policy.xml | 5 - .../main.bicep | 46 +- .../01_hosted_agent_strands_setup.ipynb | 782 ++++++- 5 files changed, 2589 insertions(+), 102 deletions(-) diff --git a/labs/ai-foundry-hosted-agents-custom-framework/README.md b/labs/ai-foundry-hosted-agents-custom-framework/README.md index 02929c22..936e598b 100644 --- a/labs/ai-foundry-hosted-agents-custom-framework/README.md +++ b/labs/ai-foundry-hosted-agents-custom-framework/README.md @@ -67,7 +67,8 @@ Use this notebook first to deploy core infrastructure with Bicep. - Foundry User role assignments (`Foundry User`) for configured user object IDs across all Foundry resources **APIM Proxy Configuration** (optional, added when `enableHostedAgentResponsesApi=true`): -- Dedicated API endpoint proxying your hosted agent's Responses API +- Dedicated API endpoint proxying Foundry's Responses API +- **Dynamic Agent Routing**: Clients specify the target agent via `agent_reference` in the request body (not the URL) - Managed identity token injection (Foundry authentication) - Automatic header injection: - `Content-Type: application/json` @@ -75,6 +76,7 @@ Use this notebook first to deploy core infrastructure with Bicep. - Automatic query parameter enforcement: - `api-version: 2025-05-15-preview` - Uses APIM subscription key for client authentication (cleaner than managing bearer tokens on client side) +- **Agent-Agnostic Design**: Works with any deployed agent—no need to reconfigure APIM when you add a new agent Policy definition is in [hosted-agent-policy.xml](hosted-agent-policy.xml) for easy customization. @@ -110,26 +112,38 @@ The deployment template is in [main.bicep](main.bicep). 4. Test the agent directly via Foundry's Responses API (baseline validation) 5. Test the agent via APIM (validates the proxy gateway) -**Step 3: Enable APIM Proxy (Optional but Recommended)** -- Once your agent is deployed and running, go back to [ai-foundry-hosted-agents-custom-framework.ipynb](ai-foundry-hosted-agents-custom-framework.ipynb) -- Set `hosted_agent_id` in the config to your agent name (e.g., `'strands-agent:1'`) and re-run the deployment -- This provisions the APIM API proxy with automatic header/query-param injection +**Step 3: Test via APIM (Optional)** +- APIM is automatically configured for any deployed agent +- In the sample agent notebooks (Section 4), clients specify the target agent via `agent_reference` in the request body +- Request format: + ```json + POST https://apim-{suffix}.azure-api.net/hosted-agent-responses/responses + Headers: api-key: {subscription-key} + Body: { + "agent_reference": { "type": "agent_reference", "name": "strands-agent", "version": "1" }, + "input": "Your prompt", + "model": "gpt-5-mini" + } + ``` +- Once you deploy additional agents to Foundry, simply change `agent_reference.name` in the request—no APIM reconfiguration needed ### Test Flow Explained Each sample notebook includes three test scenarios: 1. **Direct Foundry Test** (Section 3) - - Calls the Foundry Hosted Agent Responses API directly + - Calls the Foundry Hosted Agent Responses API directly with agent name in URL - Uses your Azure CLI credential (bearer token with `https://ai.azure.com/.default` audience) - Validates the agent runtime and basic connectivity - No APIM involvement—good baseline for troubleshooting 2. **APIM Test** (Section 4) - Routes through APIM gateway using subscription key (`api-key` header) + - Specifies the target agent via `agent_reference` in the request body (not the URL) - APIM injects managed identity token to Foundry automatically - APIM enforces `Content-Type`, `Foundry-Features`, and `api-version` headers - Tests the full production-like path (client → APIM → Foundry agent) + - **Key difference**: You can change `agent_reference.name` to target different agents without reconfiguring APIM ### Clean up resources diff --git a/labs/ai-foundry-hosted-agents-custom-framework/ai-foundry-hosted-agents-custom-framework.ipynb b/labs/ai-foundry-hosted-agents-custom-framework/ai-foundry-hosted-agents-custom-framework.ipynb index 8c51078d..1db3cfac 100644 --- a/labs/ai-foundry-hosted-agents-custom-framework/ai-foundry-hosted-agents-custom-framework.ipynb +++ b/labs/ai-foundry-hosted-agents-custom-framework/ai-foundry-hosted-agents-custom-framework.ipynb @@ -47,10 +47,18 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 29, "id": "99068750", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Lab directory: c:\\GitHub\\ai-gateway\\AI-Gateway\\labs\\ai-foundry-hosted-agents-custom-framework\n" + ] + } + ], "source": [ "import json\n", "import os\n", @@ -77,14 +85,24 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 35, "id": "1c47a2ce", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Configuration ready. Set real values before running deployment.\n", + "Note: APIM is configured to support any deployed agent.\n", + "Clients specify the target agent via agent_reference in the request body.\n" + ] + } + ], "source": [ "# Update these values as needed\n", - "subscription_id = 'XXXX'\n", - "resource_group = 'rg-aigw-hosted-custom-framework'\n", + "subscription_id = 'baba41cf-c01d-4a55-b6c5-ca494b802be5'\n", + "resource_group = 'rg-aigw-hosted-custom-framework-v2'\n", "location = 'swedencentral'\n", "deployment_name = 'deploy-hosted-custom-framework'\n", "\n", @@ -128,23 +146,37 @@ "]\n", "\n", "# Deploy Foundry infrastructure and APIM with hosted agent responses API support.\n", - "# The hosted agent ID should match what you will deploy in the Strands notebook.\n", - "# Format: \"agent-name:version\" (version is auto-assigned by Foundry)\n", - "# For now, use a placeholder that will be updated after you see the actual agent version\n", + "# APIM will accept requests with 'agent_reference' in the request body,\n", + "# allowing you to target any deployed agent without changing the APIM configuration.\n", "enable_hosted_agent_responses_api = True\n", - "hosted_agent_id = 'strands-agent:1' # Update this after deploying the agent in Strands notebook, then redeploy\n", "\n", "print('Configuration ready. Set real values before running deployment.')\n", - "print(f'Note: hosted_agent_id is set to \"{hosted_agent_id}\". After deploying in the Strands notebook,')\n", - "print('update this to the actual agent version (e.g., \"strands-agent:3\") and redeploy to finalize APIM routing.')" + "print('Note: APIM is configured to support any deployed agent.')\n", + "print('Clients specify the target agent via agent_reference in the request body.')" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 36, "id": "91b2888b", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "$ cmd /c C:\\Program Files\\Microsoft SDKs\\Azure\\CLI2\\wbin\\az.cmd ad signed-in-user show --query id -o tsv\n", + "13f94c0d-8a51-492a-928b-59392c23c1ac\n", + "\n", + "Foundry user object IDs:\n", + "[\n", + " \"13f94c0d-8a51-492a-928b-59392c23c1ac\"\n", + "]\n", + "Saved to: c:\\GitHub\\ai-gateway\\AI-Gateway\\labs\\ai-foundry-hosted-agents-custom-framework\\foundry-user-object-ids.json\n" + ] + } + ], "source": [ "from pathlib import Path\n", "import json\n", @@ -187,10 +219,1745 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 39, "id": "3c1be18b", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "$ cmd /c C:\\Program Files\\Microsoft SDKs\\Azure\\CLI2\\wbin\\az.cmd account set --subscription baba41cf-c01d-4a55-b6c5-ca494b802be5\n", + "\n", + "$ cmd /c C:\\Program Files\\Microsoft SDKs\\Azure\\CLI2\\wbin\\az.cmd group create --name rg-aigw-hosted-custom-framework-v2 --location swedencentral\n", + "{\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2\",\n", + " \"location\": \"swedencentral\",\n", + " \"managedBy\": null,\n", + " \"name\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"properties\": {\n", + " \"provisioningState\": \"Succeeded\"\n", + " },\n", + " \"tags\": null,\n", + " \"type\": \"Microsoft.Resources/resourceGroups\"\n", + "}\n", + "\n", + "Wrote parameters: c:\\GitHub\\ai-gateway\\AI-Gateway\\labs\\ai-foundry-hosted-agents-custom-framework\\main.parameters.generated.json\n", + "\n", + "$ cmd /c C:\\Program Files\\Microsoft SDKs\\Azure\\CLI2\\wbin\\az.cmd bicep install\n", + "Bicep CLI is already installed at 'C:\\Users\\ollisgeorge\\.azure\\bin\\bicep.exe'. Skipping installation as no specific version was requested.\n", + "\n", + "\n", + "$ cmd /c C:\\Program Files\\Microsoft SDKs\\Azure\\CLI2\\wbin\\az.cmd deployment group validate --resource-group rg-aigw-hosted-custom-framework-v2 --template-file C:\\GitHub\\ai-gateway\\AI-Gateway\\labs\\ai-foundry-hosted-agents-custom-framework\\main.bicep --parameters @C:\\GitHub\\ai-gateway\\AI-Gateway\\labs\\ai-foundry-hosted-agents-custom-framework\\main.parameters.generated.json --only-show-errors\n", + "{\n", + " \"error\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/main\",\n", + " \"name\": \"main\",\n", + " \"properties\": {\n", + " \"correlationId\": \"fc01c748-2075-4a07-a5e0-84f41a330abb\",\n", + " \"debugSetting\": null,\n", + " \"dependencies\": [\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/foundryModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"foundryModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-models-yxz4ztnhs2gd4/projects/default-foundry-models\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"foundry-models-yxz4ztnhs2gd4/default-foundry-models\",\n", + " \"resourceType\": \"Microsoft.CognitiveServices/accounts/projects\"\n", + " },\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/foundryModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"foundryModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-agents-yxz4ztnhs2gd4/projects/default-foundry-agents\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"foundry-agents-yxz4ztnhs2gd4/default-foundry-agents\",\n", + " \"resourceType\": \"Microsoft.CognitiveServices/accounts/projects\"\n", + " },\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"acryxz4ztnhs2gd4\",\n", + " \"resourceType\": \"Microsoft.ContainerRegistry/registries\"\n", + " },\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/foundryModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"foundryModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/22772208-617f-5e2a-a6b2-54fc8f9e266a\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"22772208-617f-5e2a-a6b2-54fc8f9e266a\",\n", + " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", + " },\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"acryxz4ztnhs2gd4\",\n", + " \"resourceType\": \"Microsoft.ContainerRegistry/registries\"\n", + " },\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/foundryModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"foundryModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " },\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-models-yxz4ztnhs2gd4/projects/default-foundry-models\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"foundry-models-yxz4ztnhs2gd4/default-foundry-models\",\n", + " \"resourceType\": \"Microsoft.CognitiveServices/accounts/projects\"\n", + " },\n", + " {\n", + " \"apiVersion\": \"2025-04-01-preview\",\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-models-yxz4ztnhs2gd4/projects/default-foundry-models\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"foundry-models-yxz4ztnhs2gd4/default-foundry-models\",\n", + " \"resourceType\": \"Microsoft.CognitiveServices/accounts/projects\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/d106d8d7-7d30-5168-bd6f-4b3f07e87cfe\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"d106d8d7-7d30-5168-bd6f-4b3f07e87cfe\",\n", + " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", + " },\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"acryxz4ztnhs2gd4\",\n", + " \"resourceType\": \"Microsoft.ContainerRegistry/registries\"\n", + " },\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/foundryModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"foundryModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/94db8588-bfb9-5498-ade3-6f2e83b34ea4\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"94db8588-bfb9-5498-ade3-6f2e83b34ea4\",\n", + " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", + " },\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"acryxz4ztnhs2gd4\",\n", + " \"resourceType\": \"Microsoft.ContainerRegistry/registries\"\n", + " },\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/foundryModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"foundryModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/287399b4-a485-5e81-91b5-642b7b0611c6\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"287399b4-a485-5e81-91b5-642b7b0611c6\",\n", + " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", + " },\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-agents-yxz4ztnhs2gd4/projects/default-foundry-agents\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"foundry-agents-yxz4ztnhs2gd4/default-foundry-agents\",\n", + " \"resourceType\": \"Microsoft.CognitiveServices/accounts/projects\"\n", + " },\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"acryxz4ztnhs2gd4\",\n", + " \"resourceType\": \"Microsoft.ContainerRegistry/registries\"\n", + " },\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/foundryModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"foundryModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " },\n", + " {\n", + " \"apiVersion\": \"2025-04-01-preview\",\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-agents-yxz4ztnhs2gd4/projects/default-foundry-agents\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"foundry-agents-yxz4ztnhs2gd4/default-foundry-agents\",\n", + " \"resourceType\": \"Microsoft.CognitiveServices/accounts/projects\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/5cd3021a-9d23-5cde-8978-b5d478bd4dc1\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"5cd3021a-9d23-5cde-8978-b5d478bd4dc1\",\n", + " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", + " },\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"acryxz4ztnhs2gd4\",\n", + " \"resourceType\": \"Microsoft.ContainerRegistry/registries\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/941f7566-c405-5201-929e-29bfe676fa27\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"941f7566-c405-5201-929e-29bfe676fa27\",\n", + " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", + " },\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"acryxz4ztnhs2gd4\",\n", + " \"resourceType\": \"Microsoft.ContainerRegistry/registries\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/73a770d5-7324-58bf-89ad-0020ab023a16\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"73a770d5-7324-58bf-89ad-0020ab023a16\",\n", + " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", + " },\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/apimModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"apimModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " },\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/foundryModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"foundryModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4/apis/hosted-agent-responses-api\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"apim-yxz4ztnhs2gd4/hosted-agent-responses-api\",\n", + " \"resourceType\": \"Microsoft.ApiManagement/service/apis\"\n", + " },\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4/apis/hosted-agent-responses-api\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"apim-yxz4ztnhs2gd4/hosted-agent-responses-api\",\n", + " \"resourceType\": \"Microsoft.ApiManagement/service/apis\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4/apis/hosted-agent-responses-api/operations/create-response\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"apim-yxz4ztnhs2gd4/hosted-agent-responses-api/create-response\",\n", + " \"resourceType\": \"Microsoft.ApiManagement/service/apis/operations\"\n", + " },\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4/apis/hosted-agent-responses-api\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"apim-yxz4ztnhs2gd4/hosted-agent-responses-api\",\n", + " \"resourceType\": \"Microsoft.ApiManagement/service/apis\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4/apis/hosted-agent-responses-api/policies/policy\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"apim-yxz4ztnhs2gd4/hosted-agent-responses-api/policy\",\n", + " \"resourceType\": \"Microsoft.ApiManagement/service/apis/policies\"\n", + " },\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/lawModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"lawModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/appInsightsModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"appInsightsModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " },\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/appInsightsModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"appInsightsModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " },\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/lawModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"lawModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/apimModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"apimModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " },\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/apimModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"apimModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " },\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/appInsightsModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"appInsightsModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/foundryModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"foundryModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " },\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/apimModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"apimModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " },\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/appInsightsModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"appInsightsModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " },\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/foundryModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"foundryModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/inferenceAPIModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"inferenceAPIModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " },\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/foundryModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"foundryModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-models-yxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/58ab3a23-7cc7-5f77-ac1f-abc3771bca77\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"58ab3a23-7cc7-5f77-ac1f-abc3771bca77\",\n", + " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", + " },\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/foundryModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"foundryModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-agents-yxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/757d48fe-4b02-501f-aa26-dc072a3df0ec\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"757d48fe-4b02-501f-aa26-dc072a3df0ec\",\n", + " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", + " }\n", + " ],\n", + " \"diagnostics\": [\n", + " {\n", + " \"additionalInfo\": null,\n", + " \"code\": \"NestedDeploymentShortCircuited\",\n", + " \"level\": \"Warning\",\n", + " \"message\": \"A nested deployment got short-circuited and all its resources got skipped from validation. This is due to a nested template having a parameter that was not fully evaluated (e.g. contains a reference() function). Please see https://aka.ms/WhatIfEvalStopped for more guidance.\",\n", + " \"target\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/appInsightsModule\"\n", + " },\n", + " {\n", + " \"additionalInfo\": null,\n", + " \"code\": \"NestedDeploymentShortCircuited\",\n", + " \"level\": \"Warning\",\n", + " \"message\": \"A nested deployment got short-circuited and all its resources got skipped from validation. This is due to a nested template having a parameter that was not fully evaluated (e.g. contains a reference() function). Please see https://aka.ms/WhatIfEvalStopped for more guidance.\",\n", + " \"target\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/apimModule\"\n", + " },\n", + " {\n", + " \"additionalInfo\": null,\n", + " \"code\": \"NestedDeploymentShortCircuited\",\n", + " \"level\": \"Warning\",\n", + " \"message\": \"A nested deployment got short-circuited and all its resources got skipped from validation. This is due to a nested template having a parameter that was not fully evaluated (e.g. contains a reference() function). Please see https://aka.ms/WhatIfEvalStopped for more guidance.\",\n", + " \"target\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/foundryModule\"\n", + " },\n", + " {\n", + " \"additionalInfo\": null,\n", + " \"code\": \"NestedDeploymentShortCircuited\",\n", + " \"level\": \"Warning\",\n", + " \"message\": \"A nested deployment got short-circuited and all its resources got skipped from validation. This is due to a nested template having a parameter that was not fully evaluated (e.g. contains a reference() function). Please see https://aka.ms/WhatIfEvalStopped for more guidance.\",\n", + " \"target\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/inferenceAPIModule\"\n", + " }\n", + " ],\n", + " \"duration\": \"PT0S\",\n", + " \"error\": null,\n", + " \"extensions\": [],\n", + " \"mode\": \"Incremental\",\n", + " \"onErrorDeployment\": null,\n", + " \"outputResources\": null,\n", + " \"outputs\": null,\n", + " \"parameters\": {\n", + " \"aiServicesConfig\": {\n", + " \"type\": \"Array\",\n", + " \"value\": [\n", + " {\n", + " \"location\": \"swedencentral\",\n", + " \"name\": \"foundry-models\",\n", + " \"priority\": 1,\n", + " \"weight\": 100\n", + " },\n", + " {\n", + " \"location\": \"swedencentral\",\n", + " \"name\": \"foundry-agents\",\n", + " \"priority\": 1,\n", + " \"weight\": 100\n", + " }\n", + " ]\n", + " },\n", + " \"apimSku\": {\n", + " \"type\": \"String\",\n", + " \"value\": \"Basicv2\"\n", + " },\n", + " \"apimSubscriptionsConfig\": {\n", + " \"type\": \"Array\",\n", + " \"value\": [\n", + " {\n", + " \"displayName\": \"Starter\",\n", + " \"name\": \"starter\",\n", + " \"scope\": \"/apis\"\n", + " }\n", + " ]\n", + " },\n", + " \"enableHostedAgentResponsesApi\": {\n", + " \"type\": \"Bool\",\n", + " \"value\": true\n", + " },\n", + " \"foundryAgentAiServiceIndex\": {\n", + " \"type\": \"Int\",\n", + " \"value\": 1\n", + " },\n", + " \"foundryProjectName\": {\n", + " \"type\": \"String\",\n", + " \"value\": \"default\"\n", + " },\n", + " \"foundryUserObjectIds\": {\n", + " \"type\": \"Array\",\n", + " \"value\": [\n", + " \"13f94c0d-8a51-492a-928b-59392c23c1ac\"\n", + " ]\n", + " },\n", + " \"hostedAgentResponsesApiPath\": {\n", + " \"type\": \"String\",\n", + " \"value\": \"hosted-agent-responses\"\n", + " },\n", + " \"inferenceAPIPath\": {\n", + " \"type\": \"String\",\n", + " \"value\": \"inference\"\n", + " },\n", + " \"inferenceAPIType\": {\n", + " \"type\": \"String\",\n", + " \"value\": \"AzureAI\"\n", + " },\n", + " \"modelsConfig\": {\n", + " \"type\": \"Array\",\n", + " \"value\": [\n", + " {\n", + " \"aiservice\": \"foundry-models\",\n", + " \"capacity\": 10,\n", + " \"name\": \"gpt-5-mini\",\n", + " \"publisher\": \"OpenAI\",\n", + " \"sku\": \"GlobalStandard\",\n", + " \"version\": \"2025-08-07\"\n", + " }\n", + " ]\n", + " }\n", + " },\n", + " \"parametersLink\": null,\n", + " \"providers\": [\n", + " {\n", + " \"id\": null,\n", + " \"namespace\": \"Microsoft.ContainerRegistry\",\n", + " \"providerAuthorizationConsentState\": null,\n", + " \"registrationPolicy\": null,\n", + " \"registrationState\": null,\n", + " \"resourceTypes\": [\n", + " {\n", + " \"aliases\": null,\n", + " \"apiProfiles\": null,\n", + " \"apiVersions\": null,\n", + " \"capabilities\": null,\n", + " \"defaultApiVersion\": null,\n", + " \"locationMappings\": null,\n", + " \"locations\": [\n", + " \"swedencentral\"\n", + " ],\n", + " \"properties\": null,\n", + " \"resourceType\": \"registries\",\n", + " \"zoneMappings\": null\n", + " }\n", + " ]\n", + " },\n", + " {\n", + " \"id\": null,\n", + " \"namespace\": \"Microsoft.CognitiveServices\",\n", + " \"providerAuthorizationConsentState\": null,\n", + " \"registrationPolicy\": null,\n", + " \"registrationState\": null,\n", + " \"resourceTypes\": [\n", + " {\n", + " \"aliases\": null,\n", + " \"apiProfiles\": null,\n", + " \"apiVersions\": null,\n", + " \"capabilities\": null,\n", + " \"defaultApiVersion\": null,\n", + " \"locationMappings\": null,\n", + " \"locations\": [\n", + " null\n", + " ],\n", + " \"properties\": null,\n", + " \"resourceType\": \"accounts/projects\",\n", + " \"zoneMappings\": null\n", + " }\n", + " ]\n", + " },\n", + " {\n", + " \"id\": null,\n", + " \"namespace\": \"Microsoft.Authorization\",\n", + " \"providerAuthorizationConsentState\": null,\n", + " \"registrationPolicy\": null,\n", + " \"registrationState\": null,\n", + " \"resourceTypes\": [\n", + " {\n", + " \"aliases\": null,\n", + " \"apiProfiles\": null,\n", + " \"apiVersions\": null,\n", + " \"capabilities\": null,\n", + " \"defaultApiVersion\": null,\n", + " \"locationMappings\": null,\n", + " \"locations\": [\n", + " null\n", + " ],\n", + " \"properties\": null,\n", + " \"resourceType\": \"roleAssignments\",\n", + " \"zoneMappings\": null\n", + " }\n", + " ]\n", + " },\n", + " {\n", + " \"id\": null,\n", + " \"namespace\": \"Microsoft.ApiManagement\",\n", + " \"providerAuthorizationConsentState\": null,\n", + " \"registrationPolicy\": null,\n", + " \"registrationState\": null,\n", + " \"resourceTypes\": [\n", + " {\n", + " \"aliases\": null,\n", + " \"apiProfiles\": null,\n", + " \"apiVersions\": null,\n", + " \"capabilities\": null,\n", + " \"defaultApiVersion\": null,\n", + " \"locationMappings\": null,\n", + " \"locations\": [\n", + " null\n", + " ],\n", + " \"properties\": null,\n", + " \"resourceType\": \"service/apis\",\n", + " \"zoneMappings\": null\n", + " },\n", + " {\n", + " \"aliases\": null,\n", + " \"apiProfiles\": null,\n", + " \"apiVersions\": null,\n", + " \"capabilities\": null,\n", + " \"defaultApiVersion\": null,\n", + " \"locationMappings\": null,\n", + " \"locations\": [\n", + " null\n", + " ],\n", + " \"properties\": null,\n", + " \"resourceType\": \"service/apis/operations\",\n", + " \"zoneMappings\": null\n", + " },\n", + " {\n", + " \"aliases\": null,\n", + " \"apiProfiles\": null,\n", + " \"apiVersions\": null,\n", + " \"capabilities\": null,\n", + " \"defaultApiVersion\": null,\n", + " \"locationMappings\": null,\n", + " \"locations\": [\n", + " null\n", + " ],\n", + " \"properties\": null,\n", + " \"resourceType\": \"service/apis/policies\",\n", + " \"zoneMappings\": null\n", + " }\n", + " ]\n", + " },\n", + " {\n", + " \"id\": null,\n", + " \"namespace\": \"Microsoft.Resources\",\n", + " \"providerAuthorizationConsentState\": null,\n", + " \"registrationPolicy\": null,\n", + " \"registrationState\": null,\n", + " \"resourceTypes\": [\n", + " {\n", + " \"aliases\": null,\n", + " \"apiProfiles\": null,\n", + " \"apiVersions\": null,\n", + " \"capabilities\": null,\n", + " \"defaultApiVersion\": null,\n", + " \"locationMappings\": null,\n", + " \"locations\": [\n", + " null\n", + " ],\n", + " \"properties\": null,\n", + " \"resourceType\": \"deployments\",\n", + " \"zoneMappings\": null\n", + " }\n", + " ]\n", + " }\n", + " ],\n", + " \"provisioningState\": \"Succeeded\",\n", + " \"templateHash\": \"944749034799081610\",\n", + " \"templateLink\": null,\n", + " \"timestamp\": \"2026-07-09T09:31:29.019113+00:00\",\n", + " \"validatedResources\": [\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4/apis/hosted-agent-responses-api\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": null\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4/apis/hosted-agent-responses-api/operations/create-response\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": null\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4/apis/hosted-agent-responses-api/policies/policy\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": null\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-agents-yxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/757d48fe-4b02-501f-aa26-dc072a3df0ec\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": null\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-models-yxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/58ab3a23-7cc7-5f77-ac1f-abc3771bca77\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": null\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": null\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/22772208-617f-5e2a-a6b2-54fc8f9e266a\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": null\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/287399b4-a485-5e81-91b5-642b7b0611c6\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": null\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/5cd3021a-9d23-5cde-8978-b5d478bd4dc1\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": null\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/73a770d5-7324-58bf-89ad-0020ab023a16\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": null\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/941f7566-c405-5201-929e-29bfe676fa27\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": null\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/94db8588-bfb9-5498-ade3-6f2e83b34ea4\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": null\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/d106d8d7-7d30-5168-bd6f-4b3f07e87cfe\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": null\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.OperationalInsights/workspaces/workspace-yxz4ztnhs2gd4\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": null\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/apimModule\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": null\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/appInsightsModule\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": null\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/foundryModule\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": null\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/inferenceAPIModule\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": null\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/lawModule\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": null\n", + " }\n", + " ],\n", + " \"validationLevel\": null\n", + " },\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"type\": \"Microsoft.Resources/deployments\"\n", + "}\n", + "\n", + "\n", + "$ cmd /c C:\\Program Files\\Microsoft SDKs\\Azure\\CLI2\\wbin\\az.cmd deployment group create --resource-group rg-aigw-hosted-custom-framework-v2 --name deploy-hosted-custom-framework --template-file C:\\GitHub\\ai-gateway\\AI-Gateway\\labs\\ai-foundry-hosted-agents-custom-framework\\main.bicep --parameters @C:\\GitHub\\ai-gateway\\AI-Gateway\\labs\\ai-foundry-hosted-agents-custom-framework\\main.parameters.generated.json --only-show-errors\n", + "{\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/deploy-hosted-custom-framework\",\n", + " \"location\": null,\n", + " \"name\": \"deploy-hosted-custom-framework\",\n", + " \"properties\": {\n", + " \"correlationId\": \"df19d468-d64d-477b-b007-538918bf8e04\",\n", + " \"debugSetting\": null,\n", + " \"dependencies\": [\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/foundryModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"foundryModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-models-yxz4ztnhs2gd4/projects/default-foundry-models\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"foundry-models-yxz4ztnhs2gd4/default-foundry-models\",\n", + " \"resourceType\": \"Microsoft.CognitiveServices/accounts/projects\"\n", + " },\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/foundryModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"foundryModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-agents-yxz4ztnhs2gd4/projects/default-foundry-agents\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"foundry-agents-yxz4ztnhs2gd4/default-foundry-agents\",\n", + " \"resourceType\": \"Microsoft.CognitiveServices/accounts/projects\"\n", + " },\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"acryxz4ztnhs2gd4\",\n", + " \"resourceType\": \"Microsoft.ContainerRegistry/registries\"\n", + " },\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/foundryModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"foundryModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/22772208-617f-5e2a-a6b2-54fc8f9e266a\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"22772208-617f-5e2a-a6b2-54fc8f9e266a\",\n", + " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", + " },\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"acryxz4ztnhs2gd4\",\n", + " \"resourceType\": \"Microsoft.ContainerRegistry/registries\"\n", + " },\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/foundryModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"foundryModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " },\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-models-yxz4ztnhs2gd4/projects/default-foundry-models\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"foundry-models-yxz4ztnhs2gd4/default-foundry-models\",\n", + " \"resourceType\": \"Microsoft.CognitiveServices/accounts/projects\"\n", + " },\n", + " {\n", + " \"apiVersion\": \"2025-04-01-preview\",\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-models-yxz4ztnhs2gd4/projects/default-foundry-models\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"foundry-models-yxz4ztnhs2gd4/default-foundry-models\",\n", + " \"resourceType\": \"Microsoft.CognitiveServices/accounts/projects\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/d106d8d7-7d30-5168-bd6f-4b3f07e87cfe\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"d106d8d7-7d30-5168-bd6f-4b3f07e87cfe\",\n", + " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", + " },\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"acryxz4ztnhs2gd4\",\n", + " \"resourceType\": \"Microsoft.ContainerRegistry/registries\"\n", + " },\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/foundryModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"foundryModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/94db8588-bfb9-5498-ade3-6f2e83b34ea4\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"94db8588-bfb9-5498-ade3-6f2e83b34ea4\",\n", + " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", + " },\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"acryxz4ztnhs2gd4\",\n", + " \"resourceType\": \"Microsoft.ContainerRegistry/registries\"\n", + " },\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/foundryModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"foundryModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/287399b4-a485-5e81-91b5-642b7b0611c6\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"287399b4-a485-5e81-91b5-642b7b0611c6\",\n", + " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", + " },\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-agents-yxz4ztnhs2gd4/projects/default-foundry-agents\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"foundry-agents-yxz4ztnhs2gd4/default-foundry-agents\",\n", + " \"resourceType\": \"Microsoft.CognitiveServices/accounts/projects\"\n", + " },\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"acryxz4ztnhs2gd4\",\n", + " \"resourceType\": \"Microsoft.ContainerRegistry/registries\"\n", + " },\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/foundryModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"foundryModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " },\n", + " {\n", + " \"apiVersion\": \"2025-04-01-preview\",\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-agents-yxz4ztnhs2gd4/projects/default-foundry-agents\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"foundry-agents-yxz4ztnhs2gd4/default-foundry-agents\",\n", + " \"resourceType\": \"Microsoft.CognitiveServices/accounts/projects\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/5cd3021a-9d23-5cde-8978-b5d478bd4dc1\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"5cd3021a-9d23-5cde-8978-b5d478bd4dc1\",\n", + " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", + " },\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"acryxz4ztnhs2gd4\",\n", + " \"resourceType\": \"Microsoft.ContainerRegistry/registries\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/941f7566-c405-5201-929e-29bfe676fa27\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"941f7566-c405-5201-929e-29bfe676fa27\",\n", + " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", + " },\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"acryxz4ztnhs2gd4\",\n", + " \"resourceType\": \"Microsoft.ContainerRegistry/registries\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/73a770d5-7324-58bf-89ad-0020ab023a16\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"73a770d5-7324-58bf-89ad-0020ab023a16\",\n", + " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", + " },\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/apimModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"apimModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " },\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/foundryModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"foundryModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4/apis/hosted-agent-responses-api\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"apim-yxz4ztnhs2gd4/hosted-agent-responses-api\",\n", + " \"resourceType\": \"Microsoft.ApiManagement/service/apis\"\n", + " },\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4/apis/hosted-agent-responses-api\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"apim-yxz4ztnhs2gd4/hosted-agent-responses-api\",\n", + " \"resourceType\": \"Microsoft.ApiManagement/service/apis\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4/apis/hosted-agent-responses-api/operations/create-response\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"apim-yxz4ztnhs2gd4/hosted-agent-responses-api/create-response\",\n", + " \"resourceType\": \"Microsoft.ApiManagement/service/apis/operations\"\n", + " },\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4/apis/hosted-agent-responses-api\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"apim-yxz4ztnhs2gd4/hosted-agent-responses-api\",\n", + " \"resourceType\": \"Microsoft.ApiManagement/service/apis\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4/apis/hosted-agent-responses-api/policies/policy\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"apim-yxz4ztnhs2gd4/hosted-agent-responses-api/policy\",\n", + " \"resourceType\": \"Microsoft.ApiManagement/service/apis/policies\"\n", + " },\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/lawModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"lawModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/appInsightsModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"appInsightsModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " },\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/appInsightsModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"appInsightsModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " },\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/lawModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"lawModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/apimModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"apimModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " },\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/apimModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"apimModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " },\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/appInsightsModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"appInsightsModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/foundryModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"foundryModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " },\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/apimModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"apimModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " },\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/appInsightsModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"appInsightsModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " },\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/foundryModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"foundryModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/inferenceAPIModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"inferenceAPIModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " },\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/foundryModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"foundryModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-models-yxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/58ab3a23-7cc7-5f77-ac1f-abc3771bca77\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"58ab3a23-7cc7-5f77-ac1f-abc3771bca77\",\n", + " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", + " },\n", + " {\n", + " \"dependsOn\": [\n", + " {\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/foundryModule\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"foundryModule\",\n", + " \"resourceType\": \"Microsoft.Resources/deployments\"\n", + " }\n", + " ],\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-agents-yxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/757d48fe-4b02-501f-aa26-dc072a3df0ec\",\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceName\": \"757d48fe-4b02-501f-aa26-dc072a3df0ec\",\n", + " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", + " }\n", + " ],\n", + " \"diagnostics\": null,\n", + " \"duration\": \"PT2M2.3055919S\",\n", + " \"error\": null,\n", + " \"extensions\": [],\n", + " \"mode\": \"Incremental\",\n", + " \"onErrorDeployment\": null,\n", + " \"outputResources\": [\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": \"Microsoft.ApiManagement/service\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4/apis/hosted-agent-responses-api\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": \"Microsoft.ApiManagement/service/apis\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4/apis/hosted-agent-responses-api/operations/create-response\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": \"Microsoft.ApiManagement/service/apis/operations\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4/apis/hosted-agent-responses-api/policies/policy\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": \"Microsoft.ApiManagement/service/apis/policies\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4/apis/inference-api\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": \"Microsoft.ApiManagement/service/apis\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4/apis/inference-api/diagnostics/applicationinsights\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": \"Microsoft.ApiManagement/service/apis/diagnostics\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4/apis/inference-api/diagnostics/azuremonitor\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": \"Microsoft.ApiManagement/service/apis/diagnostics\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4/apis/inference-api/policies/policy\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": \"Microsoft.ApiManagement/service/apis/policies\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4/backends/foundry-models\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": \"Microsoft.ApiManagement/service/backends\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4/loggers/appinsights-logger\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": \"Microsoft.ApiManagement/service/loggers\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4/loggers/azuremonitor\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": \"Microsoft.ApiManagement/service/loggers\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4/providers/Microsoft.Insights/diagnosticSettings/apimDiagnosticSettings\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": \"Microsoft.Insights/diagnosticSettings\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4/subscriptions/starter\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": \"Microsoft.ApiManagement/service/subscriptions\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-agents-yxz4ztnhs2gd4\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": \"Microsoft.CognitiveServices/accounts\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-agents-yxz4ztnhs2gd4/connections/foundry-agents-yxz4ztnhs2gd4-appInsights-connection\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": \"Microsoft.CognitiveServices/accounts/connections\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-agents-yxz4ztnhs2gd4/projects/default-foundry-agents\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": \"Microsoft.CognitiveServices/accounts/projects\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-agents-yxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/1956dcf8-77d7-591d-a940-6564ee8ba21e\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-agents-yxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/757d48fe-4b02-501f-aa26-dc072a3df0ec\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-agents-yxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/e689c10f-239d-52af-9c10-7b01d61cae15\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-models-yxz4ztnhs2gd4\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": \"Microsoft.CognitiveServices/accounts\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-models-yxz4ztnhs2gd4/connections/foundry-models-yxz4ztnhs2gd4-appInsights-connection\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": \"Microsoft.CognitiveServices/accounts/connections\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-models-yxz4ztnhs2gd4/deployments/gpt-5-mini\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": \"Microsoft.CognitiveServices/accounts/deployments\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-models-yxz4ztnhs2gd4/projects/default-foundry-models\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": \"Microsoft.CognitiveServices/accounts/projects\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-models-yxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/58ab3a23-7cc7-5f77-ac1f-abc3771bca77\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-models-yxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/7c4e7696-3e5d-5b71-8a44-de468b930e9d\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-models-yxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/803cc8f7-4801-5149-9676-6312f1b651ad\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": \"Microsoft.ContainerRegistry/registries\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/22772208-617f-5e2a-a6b2-54fc8f9e266a\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/287399b4-a485-5e81-91b5-642b7b0611c6\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/5cd3021a-9d23-5cde-8978-b5d478bd4dc1\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/73a770d5-7324-58bf-89ad-0020ab023a16\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/941f7566-c405-5201-929e-29bfe676fa27\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/94db8588-bfb9-5498-ade3-6f2e83b34ea4\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/d106d8d7-7d30-5168-bd6f-4b3f07e87cfe\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Insights/components/insights-yxz4ztnhs2gd4\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": \"Microsoft.Insights/components\"\n", + " },\n", + " {\n", + " \"apiVersion\": null,\n", + " \"extension\": null,\n", + " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.OperationalInsights/workspaces/workspace-yxz4ztnhs2gd4\",\n", + " \"identifiers\": null,\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"resourceType\": \"Microsoft.OperationalInsights/workspaces\"\n", + " }\n", + " ],\n", + " \"outputs\": {\n", + " \"aiGatewayUrl\": {\n", + " \"type\": \"String\",\n", + " \"value\": \"https://apim-yxz4ztnhs2gd4.azure-api.net/inference\"\n", + " },\n", + " \"apimGatewayUrl\": {\n", + " \"type\": \"String\",\n", + " \"value\": \"https://apim-yxz4ztnhs2gd4.azure-api.net\"\n", + " },\n", + " \"apimServiceId\": {\n", + " \"type\": \"String\",\n", + " \"value\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4\"\n", + " },\n", + " \"apimSubscriptions\": {\n", + " \"type\": \"Array\",\n", + " \"value\": [\n", + " {\n", + " \"displayName\": \"Starter\",\n", + " \"key\": \"d758c99aca6b4231980d5c0ff6917c59\",\n", + " \"name\": \"starter\"\n", + " }\n", + " ]\n", + " },\n", + " \"containerRegistryLoginServer\": {\n", + " \"type\": \"String\",\n", + " \"value\": \"acryxz4ztnhs2gd4.azurecr.io\"\n", + " },\n", + " \"containerRegistryName\": {\n", + " \"type\": \"String\",\n", + " \"value\": \"acryxz4ztnhs2gd4\"\n", + " },\n", + " \"foundryAgentAiServicesEndpoint\": {\n", + " \"type\": \"String\",\n", + " \"value\": \"https://foundry-agents-yxz4ztnhs2gd4.cognitiveservices.azure.com/\"\n", + " },\n", + " \"foundryAgentProjectEndpoint\": {\n", + " \"type\": \"String\",\n", + " \"value\": \"https://foundry-agents-yxz4ztnhs2gd4.services.ai.azure.com/api/projects/default-foundry-agents\"\n", + " },\n", + " \"foundryAiServicesEndpoint\": {\n", + " \"type\": \"String\",\n", + " \"value\": \"https://foundry-models-yxz4ztnhs2gd4.cognitiveservices.azure.com/\"\n", + " },\n", + " \"foundryProjectEndpoint\": {\n", + " \"type\": \"String\",\n", + " \"value\": \"https://foundry-models-yxz4ztnhs2gd4.services.ai.azure.com/api/projects/default-foundry-models\"\n", + " },\n", + " \"hostedAgentResponsesApimPath\": {\n", + " \"type\": \"String\",\n", + " \"value\": \"https://apim-yxz4ztnhs2gd4.azure-api.net/hosted-agent-responses/responses\"\n", + " },\n", + " \"logAnalyticsWorkspaceId\": {\n", + " \"type\": \"String\",\n", + " \"value\": \"3a0ebd2e-444f-4fea-95a4-c0816d17c6f2\"\n", + " }\n", + " },\n", + " \"parameters\": {\n", + " \"aiServicesConfig\": {\n", + " \"type\": \"Array\",\n", + " \"value\": [\n", + " {\n", + " \"location\": \"swedencentral\",\n", + " \"name\": \"foundry-models\",\n", + " \"priority\": 1,\n", + " \"weight\": 100\n", + " },\n", + " {\n", + " \"location\": \"swedencentral\",\n", + " \"name\": \"foundry-agents\",\n", + " \"priority\": 1,\n", + " \"weight\": 100\n", + " }\n", + " ]\n", + " },\n", + " \"apimSku\": {\n", + " \"type\": \"String\",\n", + " \"value\": \"Basicv2\"\n", + " },\n", + " \"apimSubscriptionsConfig\": {\n", + " \"type\": \"Array\",\n", + " \"value\": [\n", + " {\n", + " \"displayName\": \"Starter\",\n", + " \"name\": \"starter\",\n", + " \"scope\": \"/apis\"\n", + " }\n", + " ]\n", + " },\n", + " \"enableHostedAgentResponsesApi\": {\n", + " \"type\": \"Bool\",\n", + " \"value\": true\n", + " },\n", + " \"foundryAgentAiServiceIndex\": {\n", + " \"type\": \"Int\",\n", + " \"value\": 1\n", + " },\n", + " \"foundryProjectName\": {\n", + " \"type\": \"String\",\n", + " \"value\": \"default\"\n", + " },\n", + " \"foundryUserObjectIds\": {\n", + " \"type\": \"Array\",\n", + " \"value\": [\n", + " \"13f94c0d-8a51-492a-928b-59392c23c1ac\"\n", + " ]\n", + " },\n", + " \"hostedAgentResponsesApiPath\": {\n", + " \"type\": \"String\",\n", + " \"value\": \"hosted-agent-responses\"\n", + " },\n", + " \"inferenceAPIPath\": {\n", + " \"type\": \"String\",\n", + " \"value\": \"inference\"\n", + " },\n", + " \"inferenceAPIType\": {\n", + " \"type\": \"String\",\n", + " \"value\": \"AzureAI\"\n", + " },\n", + " \"modelsConfig\": {\n", + " \"type\": \"Array\",\n", + " \"value\": [\n", + " {\n", + " \"aiservice\": \"foundry-models\",\n", + " \"capacity\": 10,\n", + " \"name\": \"gpt-5-mini\",\n", + " \"publisher\": \"OpenAI\",\n", + " \"sku\": \"GlobalStandard\",\n", + " \"version\": \"2025-08-07\"\n", + " }\n", + " ]\n", + " }\n", + " },\n", + " \"parametersLink\": null,\n", + " \"providers\": [\n", + " {\n", + " \"id\": null,\n", + " \"namespace\": \"Microsoft.ContainerRegistry\",\n", + " \"providerAuthorizationConsentState\": null,\n", + " \"registrationPolicy\": null,\n", + " \"registrationState\": null,\n", + " \"resourceTypes\": [\n", + " {\n", + " \"aliases\": null,\n", + " \"apiProfiles\": null,\n", + " \"apiVersions\": null,\n", + " \"capabilities\": null,\n", + " \"defaultApiVersion\": null,\n", + " \"locationMappings\": null,\n", + " \"locations\": [\n", + " \"swedencentral\"\n", + " ],\n", + " \"properties\": null,\n", + " \"resourceType\": \"registries\",\n", + " \"zoneMappings\": null\n", + " }\n", + " ]\n", + " },\n", + " {\n", + " \"id\": null,\n", + " \"namespace\": \"Microsoft.CognitiveServices\",\n", + " \"providerAuthorizationConsentState\": null,\n", + " \"registrationPolicy\": null,\n", + " \"registrationState\": null,\n", + " \"resourceTypes\": [\n", + " {\n", + " \"aliases\": null,\n", + " \"apiProfiles\": null,\n", + " \"apiVersions\": null,\n", + " \"capabilities\": null,\n", + " \"defaultApiVersion\": null,\n", + " \"locationMappings\": null,\n", + " \"locations\": [\n", + " null\n", + " ],\n", + " \"properties\": null,\n", + " \"resourceType\": \"accounts/projects\",\n", + " \"zoneMappings\": null\n", + " }\n", + " ]\n", + " },\n", + " {\n", + " \"id\": null,\n", + " \"namespace\": \"Microsoft.Authorization\",\n", + " \"providerAuthorizationConsentState\": null,\n", + " \"registrationPolicy\": null,\n", + " \"registrationState\": null,\n", + " \"resourceTypes\": [\n", + " {\n", + " \"aliases\": null,\n", + " \"apiProfiles\": null,\n", + " \"apiVersions\": null,\n", + " \"capabilities\": null,\n", + " \"defaultApiVersion\": null,\n", + " \"locationMappings\": null,\n", + " \"locations\": [\n", + " null\n", + " ],\n", + " \"properties\": null,\n", + " \"resourceType\": \"roleAssignments\",\n", + " \"zoneMappings\": null\n", + " }\n", + " ]\n", + " },\n", + " {\n", + " \"id\": null,\n", + " \"namespace\": \"Microsoft.ApiManagement\",\n", + " \"providerAuthorizationConsentState\": null,\n", + " \"registrationPolicy\": null,\n", + " \"registrationState\": null,\n", + " \"resourceTypes\": [\n", + " {\n", + " \"aliases\": null,\n", + " \"apiProfiles\": null,\n", + " \"apiVersions\": null,\n", + " \"capabilities\": null,\n", + " \"defaultApiVersion\": null,\n", + " \"locationMappings\": null,\n", + " \"locations\": [\n", + " null\n", + " ],\n", + " \"properties\": null,\n", + " \"resourceType\": \"service/apis\",\n", + " \"zoneMappings\": null\n", + " },\n", + " {\n", + " \"aliases\": null,\n", + " \"apiProfiles\": null,\n", + " \"apiVersions\": null,\n", + " \"capabilities\": null,\n", + " \"defaultApiVersion\": null,\n", + " \"locationMappings\": null,\n", + " \"locations\": [\n", + " null\n", + " ],\n", + " \"properties\": null,\n", + " \"resourceType\": \"service/apis/operations\",\n", + " \"zoneMappings\": null\n", + " },\n", + " {\n", + " \"aliases\": null,\n", + " \"apiProfiles\": null,\n", + " \"apiVersions\": null,\n", + " \"capabilities\": null,\n", + " \"defaultApiVersion\": null,\n", + " \"locationMappings\": null,\n", + " \"locations\": [\n", + " null\n", + " ],\n", + " \"properties\": null,\n", + " \"resourceType\": \"service/apis/policies\",\n", + " \"zoneMappings\": null\n", + " }\n", + " ]\n", + " },\n", + " {\n", + " \"id\": null,\n", + " \"namespace\": \"Microsoft.Resources\",\n", + " \"providerAuthorizationConsentState\": null,\n", + " \"registrationPolicy\": null,\n", + " \"registrationState\": null,\n", + " \"resourceTypes\": [\n", + " {\n", + " \"aliases\": null,\n", + " \"apiProfiles\": null,\n", + " \"apiVersions\": null,\n", + " \"capabilities\": null,\n", + " \"defaultApiVersion\": null,\n", + " \"locationMappings\": null,\n", + " \"locations\": [\n", + " null\n", + " ],\n", + " \"properties\": null,\n", + " \"resourceType\": \"deployments\",\n", + " \"zoneMappings\": null\n", + " }\n", + " ]\n", + " }\n", + " ],\n", + " \"provisioningState\": \"Succeeded\",\n", + " \"templateHash\": \"944749034799081610\",\n", + " \"templateLink\": null,\n", + " \"timestamp\": \"2026-07-09T09:33:58.842701+00:00\",\n", + " \"validatedResources\": null,\n", + " \"validationLevel\": null\n", + " },\n", + " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", + " \"tags\": null,\n", + " \"type\": \"Microsoft.Resources/deployments\"\n", + "}\n", + "\n" + ] + } + ], "source": [ "# Create resource group and deploy Bicep\n", "# Ensure Azure CLI directory is available to subprocess calls in this kernel\n", @@ -223,9 +1990,7 @@ " 'foundryAgentAiServiceIndex': {'value': 1},\n", " 'foundryUserObjectIds': {'value': foundry_user_object_ids},\n", " 'enableHostedAgentResponsesApi': {'value': enable_hosted_agent_responses_api},\n", - " 'hostedAgentId': {'value': hosted_agent_id},\n", - " 'hostedAgentResponsesApiPath': {'value': 'hosted-agent-responses'},\n", - " 'hostedAgentResponsesApiVersion': {'value': '2025-05-15-preview'}\n", + " 'hostedAgentResponsesApiPath': {'value': 'hosted-agent-responses'}\n", " }\n", "}\n", "\n", @@ -289,25 +2054,34 @@ "\n", "1. Run this notebook to deploy all Foundry and APIM infrastructure at once\n", " - Foundry resources (models + agents)\n", - " - APIM with inference API and hosted agent responses API\n", + " - APIM with inference API and dynamic hosted agent responses API\n", " - All role assignments\n", " \n", "**Then proceed to framework-specific setup:**\n", "\n", "2. Use one of the framework notebooks under `src/responses/agents/` to build, push, and deploy the hosted agent:\n", " - `src/responses/agents/strands/01_hosted_agent_strands_setup.ipynb`\n", - " - The agent will be created with a name and version (e.g., `strands-agent:3`)\n", + " - The agent will be created with a name and version (e.g., `strands-agent:1`)\n", " \n", - "**If the agent version doesn't match the hosted_agent_id:**\n", + "**Agent routing via APIM:**\n", + "\n", + "Foundry Hosted Agents require the **agent name in the URL path** (not in the request body):\n", + "\n", + "**The hosted agent responses API will be available at:**\n", + "```\n", + "POST https://apim-{suffix}.azure-api.net/hosted-agent-responses/agents/{agentName}/endpoint/protocols/openai/responses?api-version=v1\n", + "```\n", + "\n", + "- `{agentName}`: The name of your deployed Foundry agent (e.g., `strands-agent`, `pydantic-ai`, etc.)\n", + "- Header: `api-key: {subscription-key-from-outputs}`\n", + "- Header: `Content-Type: application/json`\n", + "- Query parameter: `api-version=v1`\n", "\n", - "3. If the deployed agent version differs from `hosted_agent_id` in the config above:\n", - " - Update `hosted_agent_id` to match (e.g., change from `strands-agent:1` to `strands-agent:3`)\n", - " - Re-run this deployment notebook to update APIM routing\n", - " - This is optional—APIM will route correctly once you update the backend ID\n", + "**To use multiple agents:**\n", "\n", - "**The agent responses API will be available at:**\n", - "- `POST https://apim-{suffix}.azure-api.net/hosted-agent-responses/endpoint/protocols/openai/responses?api-version=v1`\n", - "- With header: `api-key: {subscription-key-from-outputs}`" + "1. Deploy another agent to Foundry using the framework-specific setup notebook\n", + "2. Update the `{agentName}` in the APIM URL path for each agent call\n", + "3. APIM automatically routes to the correct agent based on the URL path—no reconfiguration needed" ] } ], diff --git a/labs/ai-foundry-hosted-agents-custom-framework/hosted-agent-policy.xml b/labs/ai-foundry-hosted-agents-custom-framework/hosted-agent-policy.xml index 40d90de2..0ea1e5ea 100644 --- a/labs/ai-foundry-hosted-agents-custom-framework/hosted-agent-policy.xml +++ b/labs/ai-foundry-hosted-agents-custom-framework/hosted-agent-policy.xml @@ -18,11 +18,6 @@ HostedAgents=V1Preview - - - - 2025-05-15-preview - diff --git a/labs/ai-foundry-hosted-agents-custom-framework/main.bicep b/labs/ai-foundry-hosted-agents-custom-framework/main.bicep index 5e029bc7..eb1f9861 100644 --- a/labs/ai-foundry-hosted-agents-custom-framework/main.bicep +++ b/labs/ai-foundry-hosted-agents-custom-framework/main.bicep @@ -29,18 +29,12 @@ param foundryAgentAiServiceIndex int = 1 @description('Microsoft Entra object IDs to assign Foundry User (Azure AI User) across all Foundry resources in this deployment.') param foundryUserObjectIds array = [] -@description('Enable APIM proxy API for a deployed Hosted Agent Responses endpoint.') +@description('Enable APIM proxy API for Foundry Hosted Agent Responses. Clients specify agent via agent_reference in request body.') param enableHostedAgentResponsesApi bool = false -@description('Hosted Agent ID to proxy via APIM (required when enableHostedAgentResponsesApi=true).') -param hostedAgentId string = '' - @description('APIM path for hosted agent responses API.') param hostedAgentResponsesApiPath string = 'hosted-agent-responses' -@description('Hosted Agent Responses API version appended by APIM policy.') -param hostedAgentResponsesApiVersion string = '2025-05-15-preview' - // ------------------ // VARIABLES // ------------------ @@ -149,12 +143,12 @@ resource agentFoundryUserRoleAssignments 'Microsoft.Authorization/roleAssignment }] // Reference the Foundry projects created by the module to assign ACR roles to their managed identities. -resource modelFoundryProject 'Microsoft.CognitiveServices/accounts/projects@2024-10-01' existing = { +resource modelFoundryProject 'Microsoft.CognitiveServices/accounts/projects@2025-04-01-preview' existing = { parent: aiFoundryAccounts[0] name: '${foundryProjectName}-foundry-models' } -resource agentFoundryProject 'Microsoft.CognitiveServices/accounts/projects@2024-10-01' existing = { +resource agentFoundryProject 'Microsoft.CognitiveServices/accounts/projects@2025-04-01-preview' existing = { parent: aiFoundryAccounts[foundryAgentAiServiceIndex] name: '${foundryProjectName}-foundry-agents' } @@ -247,19 +241,20 @@ resource apimService 'Microsoft.ApiManagement/service@2024-06-01-preview' existi ] } -// Proxy Hosted Agent Responses API through APIM once a hosted agent is deployed. -resource hostedAgentResponsesApi 'Microsoft.ApiManagement/service/apis@2024-06-01-preview' = if(enableHostedAgentResponsesApi && !empty(hostedAgentId)) { +// Proxy Foundry Responses API through APIM for any deployed hosted agent. +// Clients specify the target agent via the agent name in the URL path: /agents/{agentName}/endpoint/protocols/openai/responses +resource hostedAgentResponsesApi 'Microsoft.ApiManagement/service/apis@2024-06-01-preview' = if(enableHostedAgentResponsesApi) { name: 'hosted-agent-responses-api' parent: apimService properties: { apiType: 'http' - description: 'Proxy for Azure AI Foundry Hosted Agent Responses API' - displayName: 'Hosted Agent Responses API' + description: 'Proxy for Azure AI Foundry Responses API - routes requests to specific hosted agents by agent name in URL path' + displayName: 'Foundry Responses API' path: hostedAgentResponsesApiPath protocols: [ 'https' ] - serviceUrl: '${foundryModule.outputs.extendedAIServicesConfig[foundryAgentAiServiceIndex].foundryProjectEndpoint}/agents/${split(hostedAgentId, ':')[0]}' + serviceUrl: '${foundryModule.outputs.extendedAIServicesConfig[foundryAgentAiServiceIndex].foundryProjectEndpoint}' subscriptionKeyParameterNames: { header: 'api-key' query: 'api-key' @@ -269,24 +264,33 @@ resource hostedAgentResponsesApi 'Microsoft.ApiManagement/service/apis@2024-06-0 } } -resource hostedAgentResponsesOperation 'Microsoft.ApiManagement/service/apis/operations@2024-06-01-preview' = if(enableHostedAgentResponsesApi && !empty(hostedAgentId)) { +resource hostedAgentResponsesOperation 'Microsoft.ApiManagement/service/apis/operations@2024-06-01-preview' = if(enableHostedAgentResponsesApi) { name: 'create-response' parent: hostedAgentResponsesApi properties: { - displayName: 'Create Hosted Agent Response' + displayName: 'Create Response' + description: 'Create a model response using a specific hosted agent. Agent name must be specified in the URL path.' method: 'POST' - urlTemplate: '/endpoint/protocols/openai/responses' - templateParameters: [] + urlTemplate: '/agents/{agentName}/endpoint/protocols/openai/responses' + templateParameters: [ + { + name: 'agentName' + description: 'Name of the hosted agent to invoke' + type: 'string' + required: true + values: [] + } + ] responses: [ { statusCode: 200 - description: 'Successful response' + description: 'Successful response from the agent' } ] } } -resource hostedAgentResponsesApiPolicy 'Microsoft.ApiManagement/service/apis/policies@2024-06-01-preview' = if(enableHostedAgentResponsesApi && !empty(hostedAgentId)) { +resource hostedAgentResponsesApiPolicy 'Microsoft.ApiManagement/service/apis/policies@2024-06-01-preview' = if(enableHostedAgentResponsesApi) { name: 'policy' parent: hostedAgentResponsesApi properties: { @@ -310,4 +314,4 @@ output foundryAgentProjectEndpoint string = foundryModule.outputs.extendedAIServ output foundryAgentAiServicesEndpoint string = foundryModule.outputs.extendedAIServicesConfig[foundryAgentAiServiceIndex].endpoint output containerRegistryName string = containerRegistry.name output containerRegistryLoginServer string = containerRegistry.properties.loginServer -output hostedAgentResponsesApimPath string = enableHostedAgentResponsesApi && !empty(hostedAgentId) ? '${apimModule.outputs.gatewayUrl}/${hostedAgentResponsesApiPath}/responses' : '' +output hostedAgentResponsesApimPath string = enableHostedAgentResponsesApi ? '${apimModule.outputs.gatewayUrl}/${hostedAgentResponsesApiPath}/responses' : '' diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/01_hosted_agent_strands_setup.ipynb b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/01_hosted_agent_strands_setup.ipynb index fb0c6cae..0cf07f25 100644 --- a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/01_hosted_agent_strands_setup.ipynb +++ b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/01_hosted_agent_strands_setup.ipynb @@ -42,13 +42,25 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 44, "id": "1cc7246e", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "ACR_NAME=acryxz4ztnhs2gd4\n", + "ACR_LOGIN_SERVER=acryxz4ztnhs2gd4.azurecr.io\n", + "IMAGE_NAME=strands-agent\n", + "IMAGE_TAG=1.0.0\n", + "IMAGE_URI=acryxz4ztnhs2gd4.azurecr.io/strands-agent:1.0.0\n" + ] + } + ], "source": [ "# Set these placeholders\n", - "ACR_NAME = \"xxxx\"\n", + "ACR_NAME = \"acryxz4ztnhs2gd4\"\n", "IMAGE_NAME = \"strands-agent\"\n", "IMAGE_TAG = \"1.0.0\"\n", "ACR_LOGIN_SERVER = f\"{ACR_NAME}.azurecr.io\"\n", @@ -78,10 +90,18 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 45, "id": "702db155", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Login Succeeded\n" + ] + } + ], "source": [ "# Ensure Docker is running\n", "!az acr login --name {ACR_NAME}" @@ -89,10 +109,483 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 46, "id": "3126aa58", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running: docker build -t acryxz4ztnhs2gd4.azurecr.io/strands-agent:1.0.0 .\n", + "Running: docker push acryxz4ztnhs2gd4.azurecr.io/strands-agent:1.0.0\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "#0 building with \"desktop-linux\" instance using docker driver\n", + "\n", + "#1 [internal] load build definition from Dockerfile\n", + "#1 transferring dockerfile: 233B 0.0s done\n", + "#1 DONE 0.0s\n", + "\n", + "#2 [internal] load metadata for docker.io/library/python:3.12-slim\n", + "#2 DONE 0.9s\n", + "\n", + "#3 [internal] load .dockerignore\n", + "#3 transferring context: 341B 0.0s done\n", + "#3 DONE 0.0s\n", + "\n", + "#4 [1/5] FROM docker.io/library/python:3.12-slim@sha256:423ed6ab25b1921a477529254bfeeabf5855151dc2c3141699a1bfc852199fbf\n", + "#4 resolve docker.io/library/python:3.12-slim@sha256:423ed6ab25b1921a477529254bfeeabf5855151dc2c3141699a1bfc852199fbf 0.0s done\n", + "#4 DONE 0.0s\n", + "\n", + "#5 [internal] load build context\n", + "#5 transferring context: 17.61kB 0.0s done\n", + "#5 DONE 0.0s\n", + "\n", + "#6 [2/5] WORKDIR /app\n", + "#6 CACHED\n", + "\n", + "#7 [3/5] COPY . user_agent/\n", + "#7 DONE 0.0s\n", + "\n", + "#8 [4/5] WORKDIR /app/user_agent\n", + "#8 DONE 0.0s\n", + "\n", + "#9 [5/5] RUN if [ -f requirements.txt ]; then pip install -r requirements.txt; fi\n", + "#9 17.38 Collecting azure-ai-agentserver-responses==1.0.0b8 (from -r requirements.txt (line 1))\n", + "#9 17.65 Downloading azure_ai_agentserver_responses-1.0.0b8-py3-none-any.whl.metadata (13 kB)\n", + "#9 17.93 Collecting strands-agents==1.45.0 (from strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 17.97 Downloading strands_agents-1.45.0-py3-none-any.whl.metadata (19 kB)\n", + "#9 18.45 Collecting python-dotenv (from -r requirements.txt (line 3))\n", + "#9 18.48 Downloading python_dotenv-1.2.2-py3-none-any.whl.metadata (27 kB)\n", + "#9 18.63 Collecting azure-ai-projects==2.3.0 (from -r requirements.txt (line 4))\n", + "#9 18.67 Downloading azure_ai_projects-2.3.0-py3-none-any.whl.metadata (64 kB)\n", + "#9 18.95 Collecting azure-ai-agentserver-core>=2.0.0b7 (from azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 18.98 Downloading azure_ai_agentserver_core-2.0.0b7-py3-none-any.whl.metadata (7.8 kB)\n", + "#9 19.23 Collecting azure-core>=1.30.0 (from azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 19.27 Downloading azure_core-1.41.0-py3-none-any.whl.metadata (49 kB)\n", + "#9 19.43 Collecting isodate>=0.6.1 (from azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 19.47 Downloading isodate-0.7.2-py3-none-any.whl.metadata (11 kB)\n", + "#9 25.11 Collecting aiohttp<4.0.0,>=3.10.0 (from azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 25.16 Downloading aiohttp-3.14.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (8.3 kB)\n", + "#9 30.88 Collecting boto3<2.0.0,>=1.26.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 30.92 Downloading boto3-1.43.44-py3-none-any.whl.metadata (6.6 kB)\n", + "#9 36.61 Collecting botocore<2.0.0,>=1.29.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 36.65 Downloading botocore-1.43.44-py3-none-any.whl.metadata (5.6 kB)\n", + "#9 36.78 Collecting docstring-parser<1.0,>=0.15 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 36.81 Downloading docstring_parser-0.18.0-py3-none-any.whl.metadata (3.5 kB)\n", + "#9 37.20 Collecting jsonschema<5.0.0,>=4.0.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 37.23 Downloading jsonschema-4.26.0-py3-none-any.whl.metadata (7.6 kB)\n", + "#9 37.47 Collecting mcp<2.0.0,>=1.23.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 37.54 Downloading mcp-1.28.1-py3-none-any.whl.metadata (9.4 kB)\n", + "#9 37.85 Collecting opentelemetry-api<2.0.0,>=1.30.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 37.88 Downloading opentelemetry_api-1.43.0-py3-none-any.whl.metadata (1.4 kB)\n", + "#9 38.09 Collecting opentelemetry-instrumentation-threading<1.00b0,>=0.51b0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 38.13 Downloading opentelemetry_instrumentation_threading-0.64b0-py3-none-any.whl.metadata (2.1 kB)\n", + "#9 38.40 Collecting opentelemetry-sdk<2.0.0,>=1.30.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 38.43 Downloading opentelemetry_sdk-1.43.0-py3-none-any.whl.metadata (1.7 kB)\n", + "#9 39.84 Collecting pydantic<3.0.0,>=2.4.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 39.87 Downloading pydantic-2.13.4-py3-none-any.whl.metadata (109 kB)\n", + "#9 40.38 Collecting pyyaml<7.0.0,>=6.0.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 40.41 Downloading pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (2.4 kB)\n", + "#9 40.61 Collecting typing-extensions<5.0.0,>=4.13.2 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 40.64 Downloading typing_extensions-4.16.0-py3-none-any.whl.metadata (3.3 kB)\n", + "#9 41.15 Collecting watchdog<7.0.0,>=6.0.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 41.18 Downloading watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl.metadata (44 kB)\n", + "#9 41.79 Collecting azure-identity>=1.15.0 (from azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", + "#9 41.83 Downloading azure_identity-1.25.3-py3-none-any.whl.metadata (91 kB)\n", + "#9 42.72 Collecting openai>=2.8.0 (from azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", + "#9 42.75 Downloading openai-2.44.0-py3-none-any.whl.metadata (34 kB)\n", + "#9 43.13 Collecting azure-storage-blob>=12.15.0 (from azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", + "#9 43.17 Downloading azure_storage_blob-12.30.0-py3-none-any.whl.metadata (26 kB)\n", + "#9 43.41 Collecting aws-bedrock-token-generator<2.0.0,>=1.1.0 (from strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 43.45 Downloading aws_bedrock_token_generator-1.1.0-py3-none-any.whl.metadata (7.5 kB)\n", + "#9 44.21 Collecting aiohappyeyeballs>=2.5.0 (from aiohttp<4.0.0,>=3.10.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 44.24 Downloading aiohappyeyeballs-2.7.1-py3-none-any.whl.metadata (5.9 kB)\n", + "#9 44.35 Collecting aiosignal>=1.4.0 (from aiohttp<4.0.0,>=3.10.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 44.38 Downloading aiosignal-1.4.0-py3-none-any.whl.metadata (3.7 kB)\n", + "#9 44.56 Collecting attrs>=17.3.0 (from aiohttp<4.0.0,>=3.10.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 44.59 Downloading attrs-26.1.0-py3-none-any.whl.metadata (8.8 kB)\n", + "#9 45.31 Collecting frozenlist>=1.1.1 (from aiohttp<4.0.0,>=3.10.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 45.36 Downloading frozenlist-1.8.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl.metadata (20 kB)\n", + "#9 48.06 Collecting multidict<7.0,>=4.5 (from aiohttp<4.0.0,>=3.10.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 48.10 Downloading multidict-6.7.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (5.3 kB)\n", + "#9 48.79 Collecting propcache>=0.2.0 (from aiohttp<4.0.0,>=3.10.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 48.82 Downloading propcache-0.5.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (16 kB)\n", + "#9 51.93 Collecting yarl<2.0,>=1.17.0 (from aiohttp<4.0.0,>=3.10.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 51.97 Downloading yarl-1.24.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (94 kB)\n", + "#9 55.94 Collecting starlette>=0.45.0 (from azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 55.97 Downloading starlette-1.3.1-py3-none-any.whl.metadata (6.4 kB)\n", + "#9 56.21 Collecting hypercorn>=0.17.0 (from azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 56.24 Downloading hypercorn-0.18.0-py3-none-any.whl.metadata (5.1 kB)\n", + "#9 56.64 Collecting microsoft-opentelemetry>=1.0.0 (from azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 56.67 Downloading microsoft_opentelemetry-1.3.5-py3-none-any.whl.metadata (23 kB)\n", + "#9 57.07 Collecting requests>=2.21.0 (from azure-core>=1.30.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 57.10 Downloading requests-2.34.2-py3-none-any.whl.metadata (4.8 kB)\n", + "#9 59.61 Collecting cryptography>=2.5 (from azure-identity>=1.15.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", + "#9 59.64 Downloading cryptography-49.0.0-cp311-abi3-manylinux_2_34_x86_64.whl.metadata (4.3 kB)\n", + "#9 59.86 Collecting msal>=1.35.1 (from azure-identity>=1.15.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", + "#9 59.89 Downloading msal-1.37.0-py3-none-any.whl.metadata (11 kB)\n", + "#9 60.06 Collecting msal-extensions>=1.2.0 (from azure-identity>=1.15.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", + "#9 60.12 Downloading msal_extensions-1.3.1-py3-none-any.whl.metadata (7.8 kB)\n", + "#9 62.93 Collecting jmespath<2.0.0,>=0.7.1 (from boto3<2.0.0,>=1.26.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 62.97 Downloading jmespath-1.1.0-py3-none-any.whl.metadata (7.6 kB)\n", + "#9 63.20 Collecting s3transfer<0.20.0,>=0.19.0 (from boto3<2.0.0,>=1.26.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 63.23 Downloading s3transfer-0.19.0-py3-none-any.whl.metadata (1.7 kB)\n", + "#9 63.41 Collecting python-dateutil<3.0.0,>=2.1 (from botocore<2.0.0,>=1.29.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 63.45 Downloading python_dateutil-2.9.0.post0-py2.py3-none-any.whl.metadata (8.4 kB)\n", + "#9 63.90 Collecting urllib3!=2.2.0,<3,>=1.25.4 (from botocore<2.0.0,>=1.29.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 63.93 Downloading urllib3-2.7.0-py3-none-any.whl.metadata (6.9 kB)\n", + "#9 64.18 Collecting jsonschema-specifications>=2023.03.6 (from jsonschema<5.0.0,>=4.0.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 64.22 Downloading jsonschema_specifications-2025.9.1-py3-none-any.whl.metadata (2.9 kB)\n", + "#9 64.55 Collecting referencing>=0.28.4 (from jsonschema<5.0.0,>=4.0.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 64.58 Downloading referencing-0.37.0-py3-none-any.whl.metadata (2.8 kB)\n", + "#9 67.54 Collecting rpds-py>=0.25.0 (from jsonschema<5.0.0,>=4.0.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 67.58 Downloading rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (4.1 kB)\n", + "#9 67.85 Collecting anyio>=4.5 (from mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 67.89 Downloading anyio-4.14.1-py3-none-any.whl.metadata (4.6 kB)\n", + "#9 68.01 Collecting httpx-sse>=0.4 (from mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 68.04 Downloading httpx_sse-0.4.3-py3-none-any.whl.metadata (9.7 kB)\n", + "#9 68.27 Collecting httpx<1.0.0,>=0.27.1 (from mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 68.31 Downloading httpx-0.28.1-py3-none-any.whl.metadata (7.1 kB)\n", + "#9 68.60 Collecting pydantic-settings>=2.5.2 (from mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 68.63 Downloading pydantic_settings-2.14.2-py3-none-any.whl.metadata (3.4 kB)\n", + "#9 69.28 Collecting pyjwt>=2.10.1 (from pyjwt[crypto]>=2.10.1->mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 69.31 Downloading pyjwt-2.13.0-py3-none-any.whl.metadata (3.4 kB)\n", + "#9 69.48 Collecting python-multipart>=0.0.9 (from mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 69.51 Downloading python_multipart-0.0.32-py3-none-any.whl.metadata (2.1 kB)\n", + "#9 69.74 Collecting sse-starlette>=1.6.1 (from mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 69.78 Downloading sse_starlette-3.4.5-py3-none-any.whl.metadata (15 kB)\n", + "#9 70.18 Collecting typing-inspection>=0.4.1 (from mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 70.21 Downloading typing_inspection-0.4.2-py3-none-any.whl.metadata (2.6 kB)\n", + "#9 70.58 Collecting uvicorn>=0.31.1 (from mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 70.61 Downloading uvicorn-0.51.0-py3-none-any.whl.metadata (6.6 kB)\n", + "#9 70.88 Collecting distro<2,>=1.7.0 (from openai>=2.8.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", + "#9 70.91 Downloading distro-1.9.0-py3-none-any.whl.metadata (6.8 kB)\n", + "#9 71.94 Collecting jiter<1,>=0.10.0 (from openai>=2.8.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", + "#9 71.99 Downloading jiter-0.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (5.2 kB)\n", + "#9 72.45 Collecting sniffio (from openai>=2.8.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", + "#9 72.48 Downloading sniffio-1.3.1-py3-none-any.whl.metadata (3.9 kB)\n", + "#9 72.92 Collecting tqdm>4 (from openai>=2.8.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", + "#9 72.96 Downloading tqdm-4.68.4-py3-none-any.whl.metadata (57 kB)\n", + "#9 73.58 Collecting opentelemetry-instrumentation==0.64b0 (from opentelemetry-instrumentation-threading<1.00b0,>=0.51b0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 73.61 Downloading opentelemetry_instrumentation-0.64b0-py3-none-any.whl.metadata (7.2 kB)\n", + "#9 76.31 Collecting wrapt<3.0.0,>=1.0.0 (from opentelemetry-instrumentation-threading<1.00b0,>=0.51b0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 76.35 Downloading wrapt-2.2.2-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl.metadata (7.4 kB)\n", + "#9 76.77 Collecting opentelemetry-semantic-conventions==0.64b0 (from opentelemetry-instrumentation==0.64b0->opentelemetry-instrumentation-threading<1.00b0,>=0.51b0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 76.80 Downloading opentelemetry_semantic_conventions-0.64b0-py3-none-any.whl.metadata (2.4 kB)\n", + "#9 77.00 Collecting packaging>=18.0 (from opentelemetry-instrumentation==0.64b0->opentelemetry-instrumentation-threading<1.00b0,>=0.51b0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 77.03 Downloading packaging-26.2-py3-none-any.whl.metadata (3.5 kB)\n", + "#9 77.39 Collecting annotated-types>=0.6.0 (from pydantic<3.0.0,>=2.4.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 77.42 Downloading annotated_types-0.7.0-py3-none-any.whl.metadata (15 kB)\n", + "#9 85.08 Collecting pydantic-core==2.46.4 (from pydantic<3.0.0,>=2.4.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 85.11 Downloading pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (6.6 kB)\n", + "#9 85.65 Collecting idna>=2.8 (from anyio>=4.5->mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 85.68 Downloading idna-3.18-py3-none-any.whl.metadata (6.1 kB)\n", + "#9 86.89 Collecting cffi>=2.0.0 (from cryptography>=2.5->azure-identity>=1.15.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", + "#9 86.92 Downloading cffi-2.1.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.metadata (2.5 kB)\n", + "#9 87.23 Collecting certifi (from httpx<1.0.0,>=0.27.1->mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 87.26 Downloading certifi-2026.6.17-py3-none-any.whl.metadata (2.5 kB)\n", + "#9 87.50 Collecting httpcore==1.* (from httpx<1.0.0,>=0.27.1->mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 87.53 Downloading httpcore-1.0.9-py3-none-any.whl.metadata (21 kB)\n", + "#9 87.73 Collecting h11>=0.16 (from httpcore==1.*->httpx<1.0.0,>=0.27.1->mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 87.76 Downloading h11-0.16.0-py3-none-any.whl.metadata (8.3 kB)\n", + "#9 88.02 Collecting h2>=4.3.0 (from hypercorn>=0.17.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 88.06 Downloading h2-4.3.0-py3-none-any.whl.metadata (5.1 kB)\n", + "#9 88.16 Collecting priority (from hypercorn>=0.17.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 88.20 Downloading priority-2.0.0-py3-none-any.whl.metadata (6.6 kB)\n", + "#9 88.32 Collecting wsproto>=0.14.0 (from hypercorn>=0.17.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 88.36 Downloading wsproto-1.3.2-py3-none-any.whl.metadata (5.2 kB)\n", + "#9 88.82 Collecting azure-core-tracing-opentelemetry~=1.0.0b11 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 88.85 Downloading azure_core_tracing_opentelemetry-1.0.0b13-py3-none-any.whl.metadata (11 kB)\n", + "#9 89.08 Collecting azure-monitor-opentelemetry-exporter~=1.0.0b54 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 89.12 Downloading azure_monitor_opentelemetry_exporter-1.0.0b55-py2.py3-none-any.whl.metadata (33 kB)\n", + "#9 89.65 Collecting opentelemetry-exporter-otlp-proto-http~=1.43.0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 89.69 Downloading opentelemetry_exporter_otlp_proto_http-1.43.0-py3-none-any.whl.metadata (2.4 kB)\n", + "#9 90.07 Collecting opentelemetry-instrumentation-django<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 90.10 Downloading opentelemetry_instrumentation_django-0.64b0-py3-none-any.whl.metadata (2.3 kB)\n", + "#9 90.39 Collecting opentelemetry-instrumentation-fastapi<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 90.43 Downloading opentelemetry_instrumentation_fastapi-0.64b0-py3-none-any.whl.metadata (2.2 kB)\n", + "#9 90.71 Collecting opentelemetry-instrumentation-flask<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 90.74 Downloading opentelemetry_instrumentation_flask-0.64b0-py3-none-any.whl.metadata (2.2 kB)\n", + "#9 91.00 Collecting opentelemetry-instrumentation-httpx<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 91.03 Downloading opentelemetry_instrumentation_httpx-0.64b0-py3-none-any.whl.metadata (7.3 kB)\n", + "#9 91.30 Collecting opentelemetry-instrumentation-psycopg2<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 91.34 Downloading opentelemetry_instrumentation_psycopg2-0.64b0-py3-none-any.whl.metadata (2.1 kB)\n", + "#9 91.64 Collecting opentelemetry-instrumentation-requests<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 91.67 Downloading opentelemetry_instrumentation_requests-0.64b0-py3-none-any.whl.metadata (2.6 kB)\n", + "#9 91.95 Collecting opentelemetry-instrumentation-urllib<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 92.00 Downloading opentelemetry_instrumentation_urllib-0.64b0-py3-none-any.whl.metadata (3.4 kB)\n", + "#9 92.31 Collecting opentelemetry-instrumentation-urllib3<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 92.34 Downloading opentelemetry_instrumentation_urllib3-0.64b0-py3-none-any.whl.metadata (4.2 kB)\n", + "#9 92.59 Collecting opentelemetry-instrumentation-logging<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 92.63 Downloading opentelemetry_instrumentation_logging-0.64b0-py3-none-any.whl.metadata (1.9 kB)\n", + "#9 92.83 Collecting opentelemetry-instrumentation-openai-agents-v2==0.1.0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 92.87 Downloading opentelemetry_instrumentation_openai_agents_v2-0.1.0-py3-none-any.whl.metadata (1.3 kB)\n", + "#9 92.98 Collecting opentelemetry-instrumentation-openai-v2==2.3b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 93.03 Downloading opentelemetry_instrumentation_openai_v2-2.3b0-py3-none-any.whl.metadata (5.2 kB)\n", + "#9 93.14 Collecting opentelemetry-resource-detector-azure<1.0.0,>=0.1.5 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 93.17 Downloading opentelemetry_resource_detector_azure-0.1.5-py3-none-any.whl.metadata (5.3 kB)\n", + "#9 93.36 Collecting wrapt<3.0.0,>=1.0.0 (from opentelemetry-instrumentation-threading<1.00b0,>=0.51b0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 93.40 Downloading wrapt-1.17.3-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl.metadata (6.4 kB)\n", + "#9 93.61 Collecting opentelemetry-util-genai==0.3b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 93.64 Downloading opentelemetry_util_genai-0.3b0-py3-none-any.whl.metadata (4.6 kB)\n", + "#9 97.09 Collecting six>=1.5 (from python-dateutil<3.0.0,>=2.1->botocore<2.0.0,>=1.29.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 97.12 Downloading six-1.17.0-py2.py3-none-any.whl.metadata (1.7 kB)\n", + "#9 98.80 Collecting charset_normalizer<4,>=2 (from requests>=2.21.0->azure-core>=1.30.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 98.86 Downloading charset_normalizer-3.4.9-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (41 kB)\n", + "#9 102.5 Collecting click>=7.0 (from uvicorn>=0.31.1->mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", + "#9 102.6 Downloading click-8.4.2-py3-none-any.whl.metadata (2.6 kB)\n", + "#9 103.7 Collecting msrest>=0.6.10 (from azure-monitor-opentelemetry-exporter~=1.0.0b54->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 103.7 Downloading msrest-0.7.1-py3-none-any.whl.metadata (21 kB)\n", + "#9 104.6 Collecting psutil<8,>=5.9 (from azure-monitor-opentelemetry-exporter~=1.0.0b54->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 104.7 Downloading psutil-7.2.2-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl.metadata (22 kB)\n", + "#9 104.9 Collecting pycparser (from cffi>=2.0.0->cryptography>=2.5->azure-identity>=1.15.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", + "#9 105.0 Downloading pycparser-3.0-py3-none-any.whl.metadata (8.2 kB)\n", + "#9 105.2 Collecting hyperframe<7,>=6.1 (from h2>=4.3.0->hypercorn>=0.17.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 105.3 Downloading hyperframe-6.1.0-py3-none-any.whl.metadata (4.3 kB)\n", + "#9 105.4 Collecting hpack<5,>=4.1 (from h2>=4.3.0->hypercorn>=0.17.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 105.5 Downloading hpack-4.2.0-py3-none-any.whl.metadata (3.3 kB)\n", + "#9 105.8 Collecting googleapis-common-protos~=1.52 (from opentelemetry-exporter-otlp-proto-http~=1.43.0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 105.8 Downloading googleapis_common_protos-1.75.0-py3-none-any.whl.metadata (8.6 kB)\n", + "#9 106.2 Collecting opentelemetry-exporter-otlp-proto-common==1.43.0 (from opentelemetry-exporter-otlp-proto-http~=1.43.0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 106.2 Downloading opentelemetry_exporter_otlp_proto_common-1.43.0-py3-none-any.whl.metadata (1.8 kB)\n", + "#9 106.5 Collecting opentelemetry-proto==1.43.0 (from opentelemetry-exporter-otlp-proto-http~=1.43.0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 106.5 Downloading opentelemetry_proto-1.43.0-py3-none-any.whl.metadata (2.3 kB)\n", + "#9 108.9 Collecting protobuf<8.0,>=5.0 (from opentelemetry-proto==1.43.0->opentelemetry-exporter-otlp-proto-http~=1.43.0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 109.0 Downloading protobuf-7.35.1-cp310-abi3-manylinux2014_x86_64.whl.metadata (595 bytes)\n", + "#9 109.3 Collecting opentelemetry-instrumentation-wsgi==0.64b0 (from opentelemetry-instrumentation-django<0.65b0,>=0.64b0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 109.3 Downloading opentelemetry_instrumentation_wsgi-0.64b0-py3-none-any.whl.metadata (2.1 kB)\n", + "#9 109.6 Collecting opentelemetry-util-http==0.64b0 (from opentelemetry-instrumentation-django<0.65b0,>=0.64b0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 109.6 Downloading opentelemetry_util_http-0.64b0-py3-none-any.whl.metadata (2.6 kB)\n", + "#9 110.0 Collecting opentelemetry-instrumentation-asgi==0.64b0 (from opentelemetry-instrumentation-fastapi<0.65b0,>=0.64b0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 110.0 Downloading opentelemetry_instrumentation_asgi-0.64b0-py3-none-any.whl.metadata (2.0 kB)\n", + "#9 110.4 Collecting asgiref~=3.0 (from opentelemetry-instrumentation-asgi==0.64b0->opentelemetry-instrumentation-fastapi<0.65b0,>=0.64b0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 110.4 Downloading asgiref-3.11.1-py3-none-any.whl.metadata (9.3 kB)\n", + "#9 110.9 Collecting opentelemetry-instrumentation-dbapi==0.64b0 (from opentelemetry-instrumentation-psycopg2<0.65b0,>=0.64b0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 110.9 Downloading opentelemetry_instrumentation_dbapi-0.64b0-py3-none-any.whl.metadata (2.0 kB)\n", + "#9 112.3 Collecting requests-oauthlib>=0.5.0 (from msrest>=0.6.10->azure-monitor-opentelemetry-exporter~=1.0.0b54->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 112.3 Downloading requests_oauthlib-2.0.0-py2.py3-none-any.whl.metadata (11 kB)\n", + "#9 113.2 Collecting oauthlib>=3.0.0 (from requests-oauthlib>=0.5.0->msrest>=0.6.10->azure-monitor-opentelemetry-exporter~=1.0.0b54->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", + "#9 113.3 Downloading oauthlib-3.3.1-py3-none-any.whl.metadata (7.9 kB)\n", + "#9 113.5 Downloading azure_ai_agentserver_responses-1.0.0b8-py3-none-any.whl (269 kB)\n", + "#9 113.5 Downloading strands_agents-1.45.0-py3-none-any.whl (579 kB)\n", + "#9 113.6 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 579.3/579.3 kB 10.4 MB/s eta 0:00:00\n", + "#9 113.6 Downloading azure_ai_projects-2.3.0-py3-none-any.whl (349 kB)\n", + "#9 113.7 Downloading python_dotenv-1.2.2-py3-none-any.whl (22 kB)\n", + "#9 113.8 Downloading aiohttp-3.14.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (1.8 MB)\n", + "#9 113.9 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.8/1.8 MB 19.4 MB/s eta 0:00:00\n", + "#9 113.9 Downloading aws_bedrock_token_generator-1.1.0-py3-none-any.whl (10 kB)\n", + "#9 114.0 Downloading azure_ai_agentserver_core-2.0.0b7-py3-none-any.whl (35 kB)\n", + "#9 114.0 Downloading azure_core-1.41.0-py3-none-any.whl (220 kB)\n", + "#9 114.1 Downloading azure_identity-1.25.3-py3-none-any.whl (192 kB)\n", + "#9 114.1 Downloading azure_storage_blob-12.30.0-py3-none-any.whl (435 kB)\n", + "#9 114.2 Downloading boto3-1.43.44-py3-none-any.whl (140 kB)\n", + "#9 114.3 Downloading botocore-1.43.44-py3-none-any.whl (15.4 MB)\n", + "#9 115.1 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 15.4/15.4 MB 18.4 MB/s eta 0:00:00\n", + "#9 115.2 Downloading docstring_parser-0.18.0-py3-none-any.whl (22 kB)\n", + "#9 115.2 Downloading isodate-0.7.2-py3-none-any.whl (22 kB)\n", + "#9 115.2 Downloading jsonschema-4.26.0-py3-none-any.whl (90 kB)\n", + "#9 115.3 Downloading mcp-1.28.1-py3-none-any.whl (222 kB)\n", + "#9 115.4 Downloading openai-2.44.0-py3-none-any.whl (1.4 MB)\n", + "#9 115.4 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.4/1.4 MB 20.5 MB/s eta 0:00:00\n", + "#9 115.5 Downloading opentelemetry_api-1.43.0-py3-none-any.whl (61 kB)\n", + "#9 115.5 Downloading opentelemetry_instrumentation_threading-0.64b0-py3-none-any.whl (8.5 kB)\n", + "#9 115.6 Downloading opentelemetry_instrumentation-0.64b0-py3-none-any.whl (35 kB)\n", + "#9 115.6 Downloading opentelemetry_semantic_conventions-0.64b0-py3-none-any.whl (203 kB)\n", + "#9 115.7 Downloading opentelemetry_sdk-1.43.0-py3-none-any.whl (178 kB)\n", + "#9 115.8 Downloading pydantic-2.13.4-py3-none-any.whl (472 kB)\n", + "#9 115.8 Downloading pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.1 MB)\n", + "#9 116.0 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2.1/2.1 MB 16.3 MB/s eta 0:00:00\n", + "#9 116.0 Downloading pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (807 kB)\n", + "#9 116.1 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 807.9/807.9 kB 15.7 MB/s eta 0:00:00\n", + "#9 116.1 Downloading typing_extensions-4.16.0-py3-none-any.whl (45 kB)\n", + "#9 116.1 Downloading watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl (79 kB)\n", + "#9 116.2 Downloading aiohappyeyeballs-2.7.1-py3-none-any.whl (15 kB)\n", + "#9 116.3 Downloading aiosignal-1.4.0-py3-none-any.whl (7.5 kB)\n", + "#9 116.3 Downloading annotated_types-0.7.0-py3-none-any.whl (13 kB)\n", + "#9 116.4 Downloading anyio-4.14.1-py3-none-any.whl (124 kB)\n", + "#9 116.4 Downloading attrs-26.1.0-py3-none-any.whl (67 kB)\n", + "#9 116.5 Downloading cryptography-49.0.0-cp311-abi3-manylinux_2_34_x86_64.whl (4.7 MB)\n", + "#9 116.8 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 4.7/4.7 MB 16.2 MB/s eta 0:00:00\n", + "#9 116.8 Downloading distro-1.9.0-py3-none-any.whl (20 kB)\n", + "#9 116.9 Downloading frozenlist-1.8.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl (242 kB)\n", + "#9 117.0 Downloading httpx-0.28.1-py3-none-any.whl (73 kB)\n", + "#9 117.0 Downloading httpcore-1.0.9-py3-none-any.whl (78 kB)\n", + "#9 117.1 Downloading httpx_sse-0.4.3-py3-none-any.whl (9.0 kB)\n", + "#9 117.1 Downloading hypercorn-0.18.0-py3-none-any.whl (61 kB)\n", + "#9 117.2 Downloading jiter-0.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (343 kB)\n", + "#9 117.2 Downloading jmespath-1.1.0-py3-none-any.whl (20 kB)\n", + "#9 117.3 Downloading jsonschema_specifications-2025.9.1-py3-none-any.whl (18 kB)\n", + "#9 117.4 Downloading microsoft_opentelemetry-1.3.5-py3-none-any.whl (208 kB)\n", + "#9 117.4 Downloading opentelemetry_instrumentation_openai_agents_v2-0.1.0-py3-none-any.whl (25 kB)\n", + "#9 117.5 Downloading opentelemetry_instrumentation_openai_v2-2.3b0-py3-none-any.whl (18 kB)\n", + "#9 117.6 Downloading opentelemetry_util_genai-0.3b0-py3-none-any.whl (28 kB)\n", + "#9 117.6 Downloading msal-1.37.0-py3-none-any.whl (123 kB)\n", + "#9 117.7 Downloading msal_extensions-1.3.1-py3-none-any.whl (20 kB)\n", + "#9 117.7 Downloading multidict-6.7.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (256 kB)\n", + "#9 117.8 Downloading propcache-0.5.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (61 kB)\n", + "#9 117.9 Downloading pydantic_settings-2.14.2-py3-none-any.whl (61 kB)\n", + "#9 117.9 Downloading pyjwt-2.13.0-py3-none-any.whl (31 kB)\n", + "#9 117.9 Downloading python_dateutil-2.9.0.post0-py2.py3-none-any.whl (229 kB)\n", + "#9 118.0 Downloading python_multipart-0.0.32-py3-none-any.whl (30 kB)\n", + "#9 118.1 Downloading referencing-0.37.0-py3-none-any.whl (26 kB)\n", + "#9 118.1 Downloading requests-2.34.2-py3-none-any.whl (73 kB)\n", + "#9 118.2 Downloading rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (366 kB)\n", + "#9 118.2 Downloading s3transfer-0.19.0-py3-none-any.whl (90 kB)\n", + "#9 118.3 Downloading sse_starlette-3.4.5-py3-none-any.whl (16 kB)\n", + "#9 118.3 Downloading starlette-1.3.1-py3-none-any.whl (73 kB)\n", + "#9 118.4 Downloading tqdm-4.68.4-py3-none-any.whl (676 kB)\n", + "#9 118.4 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 676.6/676.6 kB 15.0 MB/s eta 0:00:00\n", + "#9 118.5 Downloading typing_inspection-0.4.2-py3-none-any.whl (14 kB)\n", + "#9 118.5 Downloading urllib3-2.7.0-py3-none-any.whl (131 kB)\n", + "#9 118.6 Downloading uvicorn-0.51.0-py3-none-any.whl (73 kB)\n", + "#9 118.6 Downloading wrapt-1.17.3-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl (88 kB)\n", + "#9 118.7 Downloading yarl-1.24.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (105 kB)\n", + "#9 118.8 Downloading sniffio-1.3.1-py3-none-any.whl (10 kB)\n", + "#9 118.8 Downloading azure_core_tracing_opentelemetry-1.0.0b13-py3-none-any.whl (12 kB)\n", + "#9 118.9 Downloading azure_monitor_opentelemetry_exporter-1.0.0b55-py2.py3-none-any.whl (251 kB)\n", + "#9 119.0 Downloading certifi-2026.6.17-py3-none-any.whl (133 kB)\n", + "#9 119.0 Downloading cffi-2.1.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (221 kB)\n", + "#9 119.1 Downloading charset_normalizer-3.4.9-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (224 kB)\n", + "#9 119.2 Downloading click-8.4.2-py3-none-any.whl (119 kB)\n", + "#9 119.2 Downloading h11-0.16.0-py3-none-any.whl (37 kB)\n", + "#9 119.3 Downloading h2-4.3.0-py3-none-any.whl (61 kB)\n", + "#9 119.4 Downloading idna-3.18-py3-none-any.whl (65 kB)\n", + "#9 119.4 Downloading opentelemetry_exporter_otlp_proto_http-1.43.0-py3-none-any.whl (21 kB)\n", + "#9 119.5 Downloading opentelemetry_exporter_otlp_proto_common-1.43.0-py3-none-any.whl (17 kB)\n", + "#9 119.5 Downloading opentelemetry_proto-1.43.0-py3-none-any.whl (72 kB)\n", + "#9 119.6 Downloading opentelemetry_instrumentation_django-0.64b0-py3-none-any.whl (18 kB)\n", + "#9 119.7 Downloading opentelemetry_instrumentation_wsgi-0.64b0-py3-none-any.whl (13 kB)\n", + "#9 119.7 Downloading opentelemetry_util_http-0.64b0-py3-none-any.whl (8.2 kB)\n", + "#9 119.8 Downloading opentelemetry_instrumentation_fastapi-0.64b0-py3-none-any.whl (13 kB)\n", + "#9 119.8 Downloading opentelemetry_instrumentation_asgi-0.64b0-py3-none-any.whl (15 kB)\n", + "#9 119.9 Downloading opentelemetry_instrumentation_flask-0.64b0-py3-none-any.whl (15 kB)\n", + "#9 119.9 Downloading opentelemetry_instrumentation_httpx-0.64b0-py3-none-any.whl (16 kB)\n", + "#9 120.0 Downloading opentelemetry_instrumentation_logging-0.64b0-py3-none-any.whl (16 kB)\n", + "#9 120.0 Downloading opentelemetry_instrumentation_psycopg2-0.64b0-py3-none-any.whl (10 kB)\n", + "#9 120.1 Downloading opentelemetry_instrumentation_dbapi-0.64b0-py3-none-any.whl (14 kB)\n", + "#9 120.1 Downloading opentelemetry_instrumentation_requests-0.64b0-py3-none-any.whl (13 kB)\n", + "#9 120.2 Downloading opentelemetry_instrumentation_urllib-0.64b0-py3-none-any.whl (13 kB)\n", + "#9 120.2 Downloading opentelemetry_instrumentation_urllib3-0.64b0-py3-none-any.whl (13 kB)\n", + "#9 120.3 Downloading opentelemetry_resource_detector_azure-0.1.5-py3-none-any.whl (14 kB)\n", + "#9 120.3 Downloading packaging-26.2-py3-none-any.whl (100 kB)\n", + "#9 120.4 Downloading six-1.17.0-py2.py3-none-any.whl (11 kB)\n", + "#9 120.4 Downloading wsproto-1.3.2-py3-none-any.whl (24 kB)\n", + "#9 120.5 Downloading priority-2.0.0-py3-none-any.whl (8.9 kB)\n", + "#9 120.5 Downloading googleapis_common_protos-1.75.0-py3-none-any.whl (300 kB)\n", + "#9 120.6 Downloading hpack-4.2.0-py3-none-any.whl (34 kB)\n", + "#9 120.7 Downloading hyperframe-6.1.0-py3-none-any.whl (13 kB)\n", + "#9 120.7 Downloading msrest-0.7.1-py3-none-any.whl (85 kB)\n", + "#9 120.8 Downloading psutil-7.2.2-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl (155 kB)\n", + "#9 120.8 Downloading pycparser-3.0-py3-none-any.whl (48 kB)\n", + "#9 120.9 Downloading asgiref-3.11.1-py3-none-any.whl (24 kB)\n", + "#9 120.9 Downloading protobuf-7.35.1-cp310-abi3-manylinux2014_x86_64.whl (327 kB)\n", + "#9 121.0 Downloading requests_oauthlib-2.0.0-py2.py3-none-any.whl (24 kB)\n", + "#9 121.1 Downloading oauthlib-3.3.1-py3-none-any.whl (160 kB)\n", + "#9 125.1 Installing collected packages: wrapt, watchdog, urllib3, typing-extensions, tqdm, sniffio, six, rpds-py, pyyaml, python-multipart, python-dotenv, pyjwt, pycparser, psutil, protobuf, propcache, priority, packaging, opentelemetry-util-http, oauthlib, multidict, jmespath, jiter, isodate, idna, hyperframe, httpx-sse, hpack, h11, frozenlist, docstring-parser, distro, click, charset_normalizer, certifi, attrs, asgiref, annotated-types, aiohappyeyeballs, yarl, wsproto, uvicorn, typing-inspection, requests, referencing, python-dateutil, pydantic-core, opentelemetry-proto, opentelemetry-api, httpcore, h2, googleapis-common-protos, cffi, anyio, aiosignal, starlette, requests-oauthlib, pydantic, opentelemetry-semantic-conventions, opentelemetry-exporter-otlp-proto-common, jsonschema-specifications, hypercorn, httpx, cryptography, botocore, azure-core, aiohttp, sse-starlette, s3transfer, pydantic-settings, opentelemetry-sdk, opentelemetry-instrumentation, openai, msrest, jsonschema, azure-storage-blob, azure-core-tracing-opentelemetry, aws-bedrock-token-generator, opentelemetry-util-genai, opentelemetry-resource-detector-azure, opentelemetry-instrumentation-wsgi, opentelemetry-instrumentation-urllib3, opentelemetry-instrumentation-urllib, opentelemetry-instrumentation-threading, opentelemetry-instrumentation-requests, opentelemetry-instrumentation-openai-v2, opentelemetry-instrumentation-logging, opentelemetry-instrumentation-httpx, opentelemetry-instrumentation-dbapi, opentelemetry-instrumentation-asgi, opentelemetry-exporter-otlp-proto-http, msal, mcp, boto3, strands-agents, opentelemetry-instrumentation-psycopg2, opentelemetry-instrumentation-openai-agents-v2, opentelemetry-instrumentation-flask, opentelemetry-instrumentation-fastapi, opentelemetry-instrumentation-django, msal-extensions, azure-identity, azure-monitor-opentelemetry-exporter, azure-ai-projects, microsoft-opentelemetry, azure-ai-agentserver-core, azure-ai-agentserver-responses\n", + "#9 202.1 Successfully installed aiohappyeyeballs-2.7.1 aiohttp-3.14.1 aiosignal-1.4.0 annotated-types-0.7.0 anyio-4.14.1 asgiref-3.11.1 attrs-26.1.0 aws-bedrock-token-generator-1.1.0 azure-ai-agentserver-core-2.0.0b7 azure-ai-agentserver-responses-1.0.0b8 azure-ai-projects-2.3.0 azure-core-1.41.0 azure-core-tracing-opentelemetry-1.0.0b13 azure-identity-1.25.3 azure-monitor-opentelemetry-exporter-1.0.0b55 azure-storage-blob-12.30.0 boto3-1.43.44 botocore-1.43.44 certifi-2026.6.17 cffi-2.1.0 charset_normalizer-3.4.9 click-8.4.2 cryptography-49.0.0 distro-1.9.0 docstring-parser-0.18.0 frozenlist-1.8.0 googleapis-common-protos-1.75.0 h11-0.16.0 h2-4.3.0 hpack-4.2.0 httpcore-1.0.9 httpx-0.28.1 httpx-sse-0.4.3 hypercorn-0.18.0 hyperframe-6.1.0 idna-3.18 isodate-0.7.2 jiter-0.16.0 jmespath-1.1.0 jsonschema-4.26.0 jsonschema-specifications-2025.9.1 mcp-1.28.1 microsoft-opentelemetry-1.3.5 msal-1.37.0 msal-extensions-1.3.1 msrest-0.7.1 multidict-6.7.1 oauthlib-3.3.1 openai-2.44.0 opentelemetry-api-1.43.0 opentelemetry-exporter-otlp-proto-common-1.43.0 opentelemetry-exporter-otlp-proto-http-1.43.0 opentelemetry-instrumentation-0.64b0 opentelemetry-instrumentation-asgi-0.64b0 opentelemetry-instrumentation-dbapi-0.64b0 opentelemetry-instrumentation-django-0.64b0 opentelemetry-instrumentation-fastapi-0.64b0 opentelemetry-instrumentation-flask-0.64b0 opentelemetry-instrumentation-httpx-0.64b0 opentelemetry-instrumentation-logging-0.64b0 opentelemetry-instrumentation-openai-agents-v2-0.1.0 opentelemetry-instrumentation-openai-v2-2.3b0 opentelemetry-instrumentation-psycopg2-0.64b0 opentelemetry-instrumentation-requests-0.64b0 opentelemetry-instrumentation-threading-0.64b0 opentelemetry-instrumentation-urllib-0.64b0 opentelemetry-instrumentation-urllib3-0.64b0 opentelemetry-instrumentation-wsgi-0.64b0 opentelemetry-proto-1.43.0 opentelemetry-resource-detector-azure-0.1.5 opentelemetry-sdk-1.43.0 opentelemetry-semantic-conventions-0.64b0 opentelemetry-util-genai-0.3b0 opentelemetry-util-http-0.64b0 packaging-26.2 priority-2.0.0 propcache-0.5.2 protobuf-7.35.1 psutil-7.2.2 pycparser-3.0 pydantic-2.13.4 pydantic-core-2.46.4 pydantic-settings-2.14.2 pyjwt-2.13.0 python-dateutil-2.9.0.post0 python-dotenv-1.2.2 python-multipart-0.0.32 pyyaml-6.0.3 referencing-0.37.0 requests-2.34.2 requests-oauthlib-2.0.0 rpds-py-2026.6.3 s3transfer-0.19.0 six-1.17.0 sniffio-1.3.1 sse-starlette-3.4.5 starlette-1.3.1 strands-agents-1.45.0 tqdm-4.68.4 typing-extensions-4.16.0 typing-inspection-0.4.2 urllib3-2.7.0 uvicorn-0.51.0 watchdog-6.0.0 wrapt-1.17.3 wsproto-1.3.2 yarl-1.24.2\n", + "#9 202.1 WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager, possibly rendering your system unusable. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv. Use the --root-user-action option if you know what you are doing and want to suppress this warning.\n", + "#9 203.0 \n", + "#9 203.0 [notice] A new release of pip is available: 25.0.1 -> 26.1.2\n", + "#9 203.0 [notice] To update, run: pip install --upgrade pip\n", + "#9 DONE 204.6s\n", + "\n", + "#10 exporting to image\n", + "#10 exporting layers\n", + "#10 exporting layers 6.2s done\n", + "#10 exporting manifest sha256:6e66f34839f2d439deecd9b72f3eab9407391d7100f64d6e9cb38e5464dcb708 0.0s done\n", + "#10 exporting config sha256:0b0004e7fa124d2dd03d23878212de60a777d40947368474544907c14bd89f88 0.0s done\n", + "#10 exporting attestation manifest sha256:a59b4b305d17be987ca52477626cae41ed02c66346e7ae4ecc47c759946675f6 0.0s done\n", + "#10 exporting manifest list sha256:3fc11d28ec016df6b53b0c3f262c4592a8b3aa2021b670962f5d77eee0ba9725 0.0s done\n", + "#10 naming to acryxz4ztnhs2gd4.azurecr.io/strands-agent:1.0.0 done\n", + "#10 DONE 6.4s\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The push refers to repository [acryxz4ztnhs2gd4.azurecr.io/strands-agent]\n", + "020b426aa498: Waiting\n", + "69ecc8fe6c93: Waiting\n", + "df79d931cd67: Waiting\n", + "4f4fb700ef54: Waiting\n", + "e95a6c7ea7d4: Waiting\n", + "5448f2dea2bc: Waiting\n", + "d60f381e3e0c: Waiting\n", + "b32430367bf0: Waiting\n", + "aff2d9f8dc87: Waiting\n", + "020b426aa498: Waiting\n", + "69ecc8fe6c93: Waiting\n", + "df79d931cd67: Waiting\n", + "4f4fb700ef54: Waiting\n", + "e95a6c7ea7d4: Waiting\n", + "5448f2dea2bc: Waiting\n", + "d60f381e3e0c: Waiting\n", + "b32430367bf0: Waiting\n", + "aff2d9f8dc87: Waiting\n", + "5448f2dea2bc: Waiting\n", + "d60f381e3e0c: Waiting\n", + "b32430367bf0: Waiting\n", + "aff2d9f8dc87: Waiting\n", + "020b426aa498: Waiting\n", + "69ecc8fe6c93: Waiting\n", + "df79d931cd67: Waiting\n", + "4f4fb700ef54: Waiting\n", + "e95a6c7ea7d4: Waiting\n", + "5448f2dea2bc: Waiting\n", + "d60f381e3e0c: Waiting\n", + "b32430367bf0: Waiting\n", + "aff2d9f8dc87: Waiting\n", + "020b426aa498: Waiting\n", + "69ecc8fe6c93: Waiting\n", + "df79d931cd67: Waiting\n", + "4f4fb700ef54: Waiting\n", + "e95a6c7ea7d4: Waiting\n", + "4f4fb700ef54: Waiting\n", + "e95a6c7ea7d4: Waiting\n", + "5448f2dea2bc: Waiting\n", + "d60f381e3e0c: Waiting\n", + "b32430367bf0: Waiting\n", + "aff2d9f8dc87: Waiting\n", + "020b426aa498: Waiting\n", + "69ecc8fe6c93: Waiting\n", + "df79d931cd67: Waiting\n", + "020b426aa498: Waiting\n", + "69ecc8fe6c93: Waiting\n", + "df79d931cd67: Waiting\n", + "4f4fb700ef54: Waiting\n", + "e95a6c7ea7d4: Waiting\n", + "5448f2dea2bc: Waiting\n", + "d60f381e3e0c: Waiting\n", + "b32430367bf0: Waiting\n", + "aff2d9f8dc87: Waiting\n", + "69ecc8fe6c93: Waiting\n", + "df79d931cd67: Waiting\n", + "e95a6c7ea7d4: Waiting\n", + "5448f2dea2bc: Waiting\n", + "d60f381e3e0c: Waiting\n", + "b32430367bf0: Waiting\n", + "aff2d9f8dc87: Waiting\n", + "020b426aa498: Pushed\n", + "b32430367bf0: Pushed\n", + "4f4fb700ef54: Pushed\n", + "5448f2dea2bc: Pushed\n", + "d60f381e3e0c: Pushed\n", + "aff2d9f8dc87: Pushed\n", + "df79d931cd67: Pushed\n", + "e95a6c7ea7d4: Pushed\n", + "69ecc8fe6c93: Pushed\n", + "1.0.0: digest: sha256:3fc11d28ec016df6b53b0c3f262c4592a8b3aa2021b670962f5d77eee0ba9725 size: 856\n", + "Docker build and push completed successfully.\n" + ] + } + ], "source": [ "\n", "# Use Docker directly from the notebook\n", @@ -128,9 +621,9 @@ "\n", "### Important notes\n", "\n", - "- **Agent name**: Must match `hosted_agent_id` from the infrastructure deployment (without the version suffix). \n", - " - E.g., if you set `hosted_agent_id = 'strands-agent:1'` in main deployment, create the agent with name `strands-agent` here.\n", - " - Foundry auto-assigns the version suffix (`:1`, `:2`, etc.)\n", + "- **Agent name**: Choose any name you want (e.g., `strands-agent`, `my-agent`, etc.). \n", + " - Foundry auto-assigns the version suffix (`:1`, `:2`, etc.) when you create versions\n", + " - This name will be used in the APIM URL path to invoke the agent: `/agents/{agentName}/endpoint/protocols/openai/responses`\n", "\n", "- **Model endpoint**: Uses APIM **inference** API for model calls (`https://apim-{suffix}.azure-api.net/inference/models`), not the hosted-agent API.\n", "\n", @@ -171,10 +664,20 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 65, "id": "89e98ee4", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "PROJECT_ENDPOINT: https://foundry-agents-yxz4ztnhs2gd4.services.ai.azure.com/api/projects/default-foundry-agents\n", + "AGENT_NAME: strands-agent2\n", + "Agent created: strands-agent2, version: 1, id strands-agent2:1\n" + ] + } + ], "source": [ "from azure.ai.projects import AIProjectClient\n", "from azure.ai.projects.models import (\n", @@ -186,14 +689,14 @@ "from azure.identity import DefaultAzureCredential, AzureCliCredential\n", "\n", "# Placeholder values - update before running\n", - "PROJECT_ENDPOINT = \"https://foundry-agents-xxxxxxx.services.ai.azure.com/api/projects/default-foundry-agents\"\n", - "AGENT_NAME = \"strands-agent\"\n", + "PROJECT_ENDPOINT = \"https://foundry-agents-yxz4ztnhs2gd4.services.ai.azure.com/api/projects/default-foundry-agents\"\n", + "AGENT_NAME = \"strands-agent2\"\n", "\n", "# APIM inference endpoint for model calls.\n", - "AZURE_OPENAI_ENDPOINT = \"https://apim-xxxxxxxxxx.azure-api.net/inference/models\"\n", + "AZURE_OPENAI_ENDPOINT = \"https://apim-yxz4ztnhs2gd4.azure-api.net/inference/models\"\n", "AZURE_OPENAI_API_VERSION = \"2024-05-01-preview\"\n", "AZURE_OPENAI_DEPLOYMENT = \"gpt-5-mini\"\n", - "APIM_SUBSCRIPTION_KEY = \"xxxxxxxxx\"\n", + "APIM_SUBSCRIPTION_KEY = \"d758c99aca6b4231980d5c0ff6917c59\"\n", "\n", "print(f\"PROJECT_ENDPOINT: {PROJECT_ENDPOINT}\")\n", "print(f\"AGENT_NAME: {AGENT_NAME}\")\n", @@ -254,10 +757,67 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 66, "id": "93be92da", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "POST https://foundry-agents-yxz4ztnhs2gd4.services.ai.azure.com/api/projects/default-foundry-agents/agents/strands-agent2/endpoint/protocols/openai/responses?api-version=v1\n", + "Agent Name: strands-agent2\n", + "Payload: {\n", + " \"input\": \"Hello! What can you help me with? What's the weather in Paris today?\",\n", + " \"stream\": false\n", + "}\n", + "\n", + "Status: 200\n", + "Headers: {'Content-Length': '1215', 'Content-Type': 'application/json', 'content-encoding': 'identity', 'request-context': 'appId=', 'x-ms-response-type': 'standard', 'x-request-id': '29b495c75664973add72be850196fe06,29b495c75664973add72be850196fe06', 'api-supported-versions': '1.0,2025-05-15-preview,2025-11-15-preview', 'x-agent-session-id': '22a21b2cf5f64e1a7fff8e75bcf6d488e5127d871ed888fcdd9905317fd6068', 'x-platform-server': 'azure-ai-agentserver-core/2.0.0b7 (python/3.12) azure-ai-agentserver-responses/1.0.0b8 (python/3.12)', 'azureml-served-by-cluster': 'hyena-swedencentral-02', 'apim-request-id': 'eac7dff9-7f81-434f-8db0-cc29f5a04c4a', 'Strict-Transport-Security': 'max-age=31536000; includeSubDomains; preload', 'x-content-type-options': 'nosniff', 'x-ms-region': 'Sweden Central', 'Access-Control-Expose-Headers': 'Operation-Location,Location,Apim-Request-Id,x-agent-session-id,x-agent-invocation-id', 'Date': 'Thu, 09 Jul 2026 12:02:02 GMT'}\n", + "Response text (first 500 chars): {\"id\":\"caresp_238be47fdb64c77100zdjo2jUZYlUk52TtiUhT2zARN3LhiQuI\",\"object\":\"response\",\"output\":[{\"type\":\"message\",\"id\":\"msg_238be47fdb64c77100lYxe4zTgvtBmOS3p08emUKpObYutwfil\",\"role\":\"assistant\",\"content\":[{\"type\":\"output_text\",\"text\":\"Hi — I can help with questions, explanations, writing/editing, code, calculations, planning, translations, summarizing text, troubleshooting, and more. I can also look up current weather, convert units, or fetch other data when available.\\n\\nCurrent weather in Par\n", + "\n", + "Response JSON:\n", + "{\n", + " \"id\": \"caresp_238be47fdb64c77100zdjo2jUZYlUk52TtiUhT2zARN3LhiQuI\",\n", + " \"object\": \"response\",\n", + " \"output\": [\n", + " {\n", + " \"type\": \"message\",\n", + " \"id\": \"msg_238be47fdb64c77100lYxe4zTgvtBmOS3p08emUKpObYutwfil\",\n", + " \"role\": \"assistant\",\n", + " \"content\": [\n", + " {\n", + " \"type\": \"output_text\",\n", + " \"text\": \"Hi \\u2014 I can help with questions, explanations, writing/editing, code, calculations, planning, translations, summarizing text, troubleshooting, and more. I can also look up current weather, convert units, or fetch other data when available.\\n\\nCurrent weather in Paris: 12\\u00b0C (about 53.6\\u00b0F). That\\u2019s fairly cool \\u2014 you might want a light jacket. Would you like a forecast, chance of rain, or humidity/wind information?\",\n", + " \"annotations\": [],\n", + " \"logprobs\": []\n", + " }\n", + " ],\n", + " \"status\": \"completed\",\n", + " \"response_id\": \"caresp_238be47fdb64c77100zdjo2jUZYlUk52TtiUhT2zARN3LhiQuI\",\n", + " \"agent_reference\": {\n", + " \"type\": \"agent_reference\",\n", + " \"name\": \"strands-agent2\",\n", + " \"version\": \"1\"\n", + " }\n", + " }\n", + " ],\n", + " \"created_at\": 1783598516,\n", + " \"agent_reference\": {\n", + " \"type\": \"agent_reference\",\n", + " \"name\": \"strands-agent2\",\n", + " \"version\": \"1\"\n", + " },\n", + " \"status\": \"completed\",\n", + " \"completed_at\": 1783598523,\n", + " \"response_id\": \"caresp_238be47fdb64c77100zdjo2jUZYlUk52TtiUhT2zARN3LhiQuI\",\n", + " \"model\": \"\",\n", + " \"agent_session_id\": \"22a21b2cf5f64e1a7fff8e75bcf6d488e5127d871ed888fcdd9905317fd6068\",\n", + " \"background\": false\n", + "}\n" + ] + } + ], "source": [ "import json\n", "import requests\n", @@ -323,40 +883,158 @@ "**Purpose:** Route your request through Azure API Management instead of calling Foundry directly.\n", "\n", "This validates the production-like path:\n", - "- Client → APIM Gateway → Foundry Hosted Agent Responses API\n", + "- Client → APIM Gateway (subscription key auth) → Foundry Responses API\n", + "\n", + "**Important: Agent-Specific Routing**\n", + "\n", + "Foundry Hosted Agents **require** the agent name in the URL path. There is no generic `/responses` endpoint that accepts `agent_reference` in the request body. Each agent must have its own URL path:\n", + "\n", + "```\n", + "POST https://apim-{APIM_SUFFIX}.azure-api.net/hosted-agent-responses/agents/{AGENT_NAME}/endpoint/protocols/openai/responses\n", + "```\n", "\n", "**What APIM does automatically:**\n", - "- Injects managed identity bearer token for Foundry authentication\n", + "- Injects managed identity bearer token for Foundry authentication (audience: `https://ai.azure.com`)\n", "- Enforces `Content-Type: application/json` header\n", - "- Enforces `api-version: 2025-05-15-preview` query parameter\n", "- Injects `Foundry-Features: HostedAgents=V1Preview` header for preview access\n", "- Your client only needs the APIM subscription key (`api-key` header)\n", "\n", + "**Comparison: Direct vs APIM**\n", + "- **Direct (Section 3):** `https://foundry-agents-{suffix}.services.ai.azure.com/api/projects/default-foundry-agents/agents/{AGENT_NAME}/endpoint/protocols/openai/responses` + Bearer token\n", + "- **APIM (Section 4):** `https://apim-{suffix}.azure-api.net/hosted-agent-responses/agents/{AGENT_NAME}/endpoint/protocols/openai/responses` + API key\n", + "\n", "**Configuration details** are in [hosted-agent-policy.xml](../../hosted-agent-policy.xml)—update there if you need to change defaults.\n", "\n", "Compare this test result with Section 3 to ensure both paths (direct and APIM-proxied) produce consistent responses." ] }, + { + "cell_type": "markdown", + "id": "6bbb399b", + "metadata": {}, + "source": [ + "### Get deployment outputs\n", + "\n", + "Before testing via APIM, retrieve the outputs from your infrastructure deployment notebook:\n", + "\n", + "1. Run the deployment notebook and copy the outputs\n", + "2. Fill in these values below:\n", + " - `APIM_SUFFIX`: The unique suffix for your APIM instance (e.g., `xhep4wovroziu`)\n", + " - `APIM_SUBSCRIPTION_KEY`: The starter subscription key from APIM outputs\n", + " - `PROJECT_ENDPOINT`: The Foundry agents project endpoint\n", + "\n", + "These are already set in cell 2 of the infrastructure deployment notebook—just copy them here.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 67, + "id": "ee7e33e1", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "APIM_SUFFIX: yxz4ztnhs2gd4\n", + "APIM_SUBSCRIPTION_KEY: d758c99aca6b4231980d...\n", + "PROJECT_ENDPOINT: https://foundry-agents-yxz4ztnhs2gd4.services.ai.azure.com/api/projects/default-foundry-agents\n", + "\n", + "⚠️ If these are still placeholders, run the infrastructure deployment notebook first!\n" + ] + } + ], + "source": [ + "APIM_SUFFIX = \"yxz4ztnhs2gd4\" # ⚠️ REPLACE with actual APIM suffix from deployment outputs\n", + "APIM_SUBSCRIPTION_KEY = \"d758c99aca6b4231980d5c0ff6917c59\" # ⚠️ REPLACE with starter subscription key\n", + "PROJECT_ENDPOINT = \"https://foundry-agents-yxz4ztnhs2gd4.services.ai.azure.com/api/projects/default-foundry-agents\" # ⚠️ REPLACE with actual endpoint\n", + "\n", + "print(f\"APIM_SUFFIX: {APIM_SUFFIX}\")\n", + "print(f\"APIM_SUBSCRIPTION_KEY: {APIM_SUBSCRIPTION_KEY[:20]}...\" if len(APIM_SUBSCRIPTION_KEY) > 20 else f\"APIM_SUBSCRIPTION_KEY: {APIM_SUBSCRIPTION_KEY}\")\n", + "print(f\"PROJECT_ENDPOINT: {PROJECT_ENDPOINT}\")\n", + "print()\n", + "print(\"⚠️ If these are still placeholders, run the infrastructure deployment notebook first!\")" + ] + }, { "cell_type": "code", "execution_count": null, "id": "4cae98de", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "POST https://apim-yxz4ztnhs2gd4.azure-api.net/hosted-agent-responses/agents/strands-agent2/endpoint/protocols/openai/responses?api-version=v1\n", + "APIM Suffix: yxz4ztnhs2gd4\n", + "Agent Name (in URL path): strands-agent2\n", + "Content-Type: application/json\n", + "Headers: api-key=d758c99aca6b4231980d..., Content-Type, Foundry-Features\n", + "Payload: {\n", + " \"input\": \"Hello! What can you help me with? What's the weather in Paris today?\",\n", + " \"stream\": false\n", + "}\n", + "\n", + "Status: 200\n", + "Response text (first 500 chars): {\"id\":\"caresp_1f2f3736b8cfafb100xx2tyeCuWfTMn3414ZYYTOGImCDFg201\",\"object\":\"response\",\"output\":[{\"type\":\"message\",\"id\":\"msg_1f2f3736b8cfafb100lYSym1CzirQBAL264ippHQvbyVyjR23o\",\"role\":\"assistant\",\"content\":[{\"type\":\"output_text\",\"text\":\"Hi — I can help with a lot of things, for example:\\n- Answer questions and explain concepts (science, history, tech, etc.)\\n- Write, edit, or summarize text (emails, essays, code, reports)\\n- Help with programming, math, data analysis, and debugging\\n- Translate l\n", + "\n", + "Response JSON:\n", + "{\n", + " \"id\": \"caresp_1f2f3736b8cfafb100xx2tyeCuWfTMn3414ZYYTOGImCDFg201\",\n", + " \"object\": \"response\",\n", + " \"output\": [\n", + " {\n", + " \"type\": \"message\",\n", + " \"id\": \"msg_1f2f3736b8cfafb100lYSym1CzirQBAL264ippHQvbyVyjR23o\",\n", + " \"role\": \"assistant\",\n", + " \"content\": [\n", + " {\n", + " \"type\": \"output_text\",\n", + " \"text\": \"Hi \\u2014 I can help with a lot of things, for example:\\n- Answer questions and explain concepts (science, history, tech, etc.)\\n- Write, edit, or summarize text (emails, essays, code, reports)\\n- Help with programming, math, data analysis, and debugging\\n- Translate languages, generate ideas, or plan projects/trips\\n- Look up current weather (and some other live info) or show internal debug info when needed\\n\\nCurrent weather in Paris today: 18\\u00b0C (about 64.4\\u00b0F).\\n\\nWould you like a short forecast, clothing suggestions for that temperature, or the weather for a different place?\",\n", + " \"annotations\": [],\n", + " \"logprobs\": []\n", + " }\n", + " ],\n", + " \"status\": \"completed\",\n", + " \"response_id\": \"caresp_1f2f3736b8cfafb100xx2tyeCuWfTMn3414ZYYTOGImCDFg201\",\n", + " \"agent_reference\": {\n", + " \"type\": \"agent_reference\",\n", + " \"name\": \"strands-agent2\",\n", + " \"version\": \"1\"\n", + " }\n", + " }\n", + " ],\n", + " \"created_at\": 1783598603,\n", + " \"agent_reference\": {\n", + " \"type\": \"agent_reference\",\n", + " \"name\": \"strands-agent2\",\n", + " \"version\": \"1\"\n", + " },\n", + " \"status\": \"completed\",\n", + " \"completed_at\": 1783598608,\n", + " \"response_id\": \"caresp_1f2f3736b8cfafb100xx2tyeCuWfTMn3414ZYYTOGImCDFg201\",\n", + " \"model\": \"\",\n", + " \"agent_session_id\": \"4e22b594e0e8c976fb97fbd08e8f882665b1ff2f6f06a14866a0c0d508e0118\",\n", + " \"background\": false\n", + "}\n", + "\n", + "Extracted response stored in 'apim_response' variable for use in subsequent cells\n" + ] + } + ], "source": [ "import json\n", "import requests\n", "\n", - "# APIM configuration with defaults\n", - "DEFAULT_API_VERSION = \"2025-05-15-preview\"\n", + "# APIM configuration\n", "DEFAULT_CONTENT_TYPE = \"application/json\"\n", + "API_VERSION = \"v1\"\n", "\n", - "# APIM endpoint and version\n", - "apim_url = f\"https://apim-{APIM_SUFFIX}.azure-api.net/hosted-agent-responses/endpoint/protocols/openai/responses\"\n", - "api_version = DEFAULT_API_VERSION\n", - "\n", - "# Build the correct URL with api-version query parameter\n", - "url = f\"{apim_url}?api-version={api_version}\"\n", + "# APIM endpoint: agent-specific URL path (Foundry requires agent name in path, not in body)\n", + "# Format: https://apim-{suffix}.azure-api.net/hosted-agent-responses/agents/{agent}/endpoint/protocols/openai/responses\n", + "apim_url = f\"https://apim-{APIM_SUFFIX}.azure-api.net/hosted-agent-responses/agents/{AGENT_NAME}/endpoint/protocols/openai/responses\"\n", + "url = apim_url\n", "\n", "# Headers for APIM: use api-key header with subscription key\n", "headers = {\n", @@ -365,32 +1043,50 @@ " \"Foundry-Features\": \"HostedAgents=V1Preview\", # Required for preview\n", "}\n", "\n", + "# Foundry Hosted Agents do NOT support agent_reference in request body\n", + "# The agent name must be in the URL path (handled above)\n", "payload = {\n", " \"input\": \"Hello! What can you help me with? What's the weather in Paris today?\",\n", " \"stream\": False,\n", "}\n", "\n", - "print(f\"POST {url}\")\n", + "print(f\"POST {url}?api-version={API_VERSION}\")\n", "print(f\"APIM Suffix: {APIM_SUFFIX}\")\n", - "print(f\"API Version: {api_version}\")\n", + "print(f\"Agent Name (in URL path): {AGENT_NAME}\")\n", "print(f\"Content-Type: {DEFAULT_CONTENT_TYPE}\")\n", "print(f\"Headers: api-key={APIM_SUBSCRIPTION_KEY[:20]}..., Content-Type, Foundry-Features\")\n", "print(f\"Payload: {json.dumps(payload, indent=2)}\")\n", "print()\n", "\n", - "response = requests.post(url, headers=headers, json=payload)\n", + "response = requests.post(url, headers=headers, json=payload, params={\"api-version\": API_VERSION})\n", "print(f\"Status: {response.status_code}\")\n", - "print(f\"Headers: {dict(response.headers)}\")\n", - "print(f\"Response text (first 500 chars): {response.text[:500]}\")\n", "print()\n", "\n", + "# Extract response from payload\n", + "apim_response = None\n", + "agent_text = None\n", + "\n", "if response.status_code == 200:\n", " try:\n", " result = response.json()\n", - " print(f\"Response JSON:\")\n", - " print(json.dumps(result, indent=2))\n", - " if \"output_text\" in result:\n", - " print(f\"\\nAgent output:\\n{result['output_text']}\")\n", + " apim_response = result\n", + " \n", + " # Extract agent text from nested structure\n", + " if \"output\" in result and len(result[\"output\"]) > 0:\n", + " message = result[\"output\"][0]\n", + " if \"content\" in message and len(message[\"content\"]) > 0:\n", + " agent_text = message[\"content\"][0].get(\"text\", \"\")\n", + " \n", + " print(\"=\" * 80)\n", + " print(f\"AGENT RESPONSE (via APIM):\")\n", + " print(\"=\" * 80)\n", + " if agent_text:\n", + " print(agent_text)\n", + " else:\n", + " print(\"Full response:\")\n", + " print(json.dumps(result, indent=2))\n", + " print(\"=\" * 80)\n", + " \n", " except json.JSONDecodeError as e:\n", " print(f\"Failed to parse JSON: {e}\")\n", " print(f\"Raw response: {response.text}\")\n", @@ -398,9 +1094,13 @@ " print(f\"Error: {response.status_code}\")\n", " if response.text:\n", " try:\n", - " print(json.dumps(response.json(), indent=2))\n", + " apim_response = response.json()\n", + " print(json.dumps(apim_response, indent=2))\n", " except:\n", - " print(response.text)" + " print(response.text)\n", + "\n", + "print(f\"\\nExtracted response stored in 'apim_response' variable\")\n", + "print(f\"Agent text stored in 'agent_text' variable\")" ] } ], From 97cf936ca943396e56ba33066f60b0a2b9770ccd Mon Sep 17 00:00:00 2001 From: George Ollis Date: Thu, 9 Jul 2026 15:29:29 +0100 Subject: [PATCH 07/17] Implement code changes to enhance functionality and improve performance --- ...undry-hosted-agents-custom-framework.ipynb | 1785 +---------------- 1 file changed, 8 insertions(+), 1777 deletions(-) diff --git a/labs/ai-foundry-hosted-agents-custom-framework/ai-foundry-hosted-agents-custom-framework.ipynb b/labs/ai-foundry-hosted-agents-custom-framework/ai-foundry-hosted-agents-custom-framework.ipynb index 1db3cfac..dd153f06 100644 --- a/labs/ai-foundry-hosted-agents-custom-framework/ai-foundry-hosted-agents-custom-framework.ipynb +++ b/labs/ai-foundry-hosted-agents-custom-framework/ai-foundry-hosted-agents-custom-framework.ipynb @@ -47,18 +47,10 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": null, "id": "99068750", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Lab directory: c:\\GitHub\\ai-gateway\\AI-Gateway\\labs\\ai-foundry-hosted-agents-custom-framework\n" - ] - } - ], + "outputs": [], "source": [ "import json\n", "import os\n", @@ -85,20 +77,10 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": null, "id": "1c47a2ce", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Configuration ready. Set real values before running deployment.\n", - "Note: APIM is configured to support any deployed agent.\n", - "Clients specify the target agent via agent_reference in the request body.\n" - ] - } - ], + "outputs": [], "source": [ "# Update these values as needed\n", "subscription_id = 'baba41cf-c01d-4a55-b6c5-ca494b802be5'\n", @@ -157,26 +139,10 @@ }, { "cell_type": "code", - "execution_count": 36, + "execution_count": null, "id": "91b2888b", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "$ cmd /c C:\\Program Files\\Microsoft SDKs\\Azure\\CLI2\\wbin\\az.cmd ad signed-in-user show --query id -o tsv\n", - "13f94c0d-8a51-492a-928b-59392c23c1ac\n", - "\n", - "Foundry user object IDs:\n", - "[\n", - " \"13f94c0d-8a51-492a-928b-59392c23c1ac\"\n", - "]\n", - "Saved to: c:\\GitHub\\ai-gateway\\AI-Gateway\\labs\\ai-foundry-hosted-agents-custom-framework\\foundry-user-object-ids.json\n" - ] - } - ], + "outputs": [], "source": [ "from pathlib import Path\n", "import json\n", @@ -219,1745 +185,10 @@ }, { "cell_type": "code", - "execution_count": 39, + "execution_count": null, "id": "3c1be18b", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "$ cmd /c C:\\Program Files\\Microsoft SDKs\\Azure\\CLI2\\wbin\\az.cmd account set --subscription baba41cf-c01d-4a55-b6c5-ca494b802be5\n", - "\n", - "$ cmd /c C:\\Program Files\\Microsoft SDKs\\Azure\\CLI2\\wbin\\az.cmd group create --name rg-aigw-hosted-custom-framework-v2 --location swedencentral\n", - "{\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2\",\n", - " \"location\": \"swedencentral\",\n", - " \"managedBy\": null,\n", - " \"name\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"properties\": {\n", - " \"provisioningState\": \"Succeeded\"\n", - " },\n", - " \"tags\": null,\n", - " \"type\": \"Microsoft.Resources/resourceGroups\"\n", - "}\n", - "\n", - "Wrote parameters: c:\\GitHub\\ai-gateway\\AI-Gateway\\labs\\ai-foundry-hosted-agents-custom-framework\\main.parameters.generated.json\n", - "\n", - "$ cmd /c C:\\Program Files\\Microsoft SDKs\\Azure\\CLI2\\wbin\\az.cmd bicep install\n", - "Bicep CLI is already installed at 'C:\\Users\\ollisgeorge\\.azure\\bin\\bicep.exe'. Skipping installation as no specific version was requested.\n", - "\n", - "\n", - "$ cmd /c C:\\Program Files\\Microsoft SDKs\\Azure\\CLI2\\wbin\\az.cmd deployment group validate --resource-group rg-aigw-hosted-custom-framework-v2 --template-file C:\\GitHub\\ai-gateway\\AI-Gateway\\labs\\ai-foundry-hosted-agents-custom-framework\\main.bicep --parameters @C:\\GitHub\\ai-gateway\\AI-Gateway\\labs\\ai-foundry-hosted-agents-custom-framework\\main.parameters.generated.json --only-show-errors\n", - "{\n", - " \"error\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/main\",\n", - " \"name\": \"main\",\n", - " \"properties\": {\n", - " \"correlationId\": \"fc01c748-2075-4a07-a5e0-84f41a330abb\",\n", - " \"debugSetting\": null,\n", - " \"dependencies\": [\n", - " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/foundryModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"foundryModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-models-yxz4ztnhs2gd4/projects/default-foundry-models\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"foundry-models-yxz4ztnhs2gd4/default-foundry-models\",\n", - " \"resourceType\": \"Microsoft.CognitiveServices/accounts/projects\"\n", - " },\n", - " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/foundryModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"foundryModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-agents-yxz4ztnhs2gd4/projects/default-foundry-agents\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"foundry-agents-yxz4ztnhs2gd4/default-foundry-agents\",\n", - " \"resourceType\": \"Microsoft.CognitiveServices/accounts/projects\"\n", - " },\n", - " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"acryxz4ztnhs2gd4\",\n", - " \"resourceType\": \"Microsoft.ContainerRegistry/registries\"\n", - " },\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/foundryModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"foundryModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/22772208-617f-5e2a-a6b2-54fc8f9e266a\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"22772208-617f-5e2a-a6b2-54fc8f9e266a\",\n", - " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", - " },\n", - " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"acryxz4ztnhs2gd4\",\n", - " \"resourceType\": \"Microsoft.ContainerRegistry/registries\"\n", - " },\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/foundryModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"foundryModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " },\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-models-yxz4ztnhs2gd4/projects/default-foundry-models\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"foundry-models-yxz4ztnhs2gd4/default-foundry-models\",\n", - " \"resourceType\": \"Microsoft.CognitiveServices/accounts/projects\"\n", - " },\n", - " {\n", - " \"apiVersion\": \"2025-04-01-preview\",\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-models-yxz4ztnhs2gd4/projects/default-foundry-models\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"foundry-models-yxz4ztnhs2gd4/default-foundry-models\",\n", - " \"resourceType\": \"Microsoft.CognitiveServices/accounts/projects\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/d106d8d7-7d30-5168-bd6f-4b3f07e87cfe\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"d106d8d7-7d30-5168-bd6f-4b3f07e87cfe\",\n", - " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", - " },\n", - " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"acryxz4ztnhs2gd4\",\n", - " \"resourceType\": \"Microsoft.ContainerRegistry/registries\"\n", - " },\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/foundryModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"foundryModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/94db8588-bfb9-5498-ade3-6f2e83b34ea4\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"94db8588-bfb9-5498-ade3-6f2e83b34ea4\",\n", - " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", - " },\n", - " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"acryxz4ztnhs2gd4\",\n", - " \"resourceType\": \"Microsoft.ContainerRegistry/registries\"\n", - " },\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/foundryModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"foundryModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/287399b4-a485-5e81-91b5-642b7b0611c6\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"287399b4-a485-5e81-91b5-642b7b0611c6\",\n", - " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", - " },\n", - " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-agents-yxz4ztnhs2gd4/projects/default-foundry-agents\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"foundry-agents-yxz4ztnhs2gd4/default-foundry-agents\",\n", - " \"resourceType\": \"Microsoft.CognitiveServices/accounts/projects\"\n", - " },\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"acryxz4ztnhs2gd4\",\n", - " \"resourceType\": \"Microsoft.ContainerRegistry/registries\"\n", - " },\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/foundryModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"foundryModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " },\n", - " {\n", - " \"apiVersion\": \"2025-04-01-preview\",\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-agents-yxz4ztnhs2gd4/projects/default-foundry-agents\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"foundry-agents-yxz4ztnhs2gd4/default-foundry-agents\",\n", - " \"resourceType\": \"Microsoft.CognitiveServices/accounts/projects\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/5cd3021a-9d23-5cde-8978-b5d478bd4dc1\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"5cd3021a-9d23-5cde-8978-b5d478bd4dc1\",\n", - " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", - " },\n", - " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"acryxz4ztnhs2gd4\",\n", - " \"resourceType\": \"Microsoft.ContainerRegistry/registries\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/941f7566-c405-5201-929e-29bfe676fa27\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"941f7566-c405-5201-929e-29bfe676fa27\",\n", - " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", - " },\n", - " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"acryxz4ztnhs2gd4\",\n", - " \"resourceType\": \"Microsoft.ContainerRegistry/registries\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/73a770d5-7324-58bf-89ad-0020ab023a16\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"73a770d5-7324-58bf-89ad-0020ab023a16\",\n", - " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", - " },\n", - " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/apimModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"apimModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " },\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/foundryModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"foundryModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4/apis/hosted-agent-responses-api\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"apim-yxz4ztnhs2gd4/hosted-agent-responses-api\",\n", - " \"resourceType\": \"Microsoft.ApiManagement/service/apis\"\n", - " },\n", - " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4/apis/hosted-agent-responses-api\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"apim-yxz4ztnhs2gd4/hosted-agent-responses-api\",\n", - " \"resourceType\": \"Microsoft.ApiManagement/service/apis\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4/apis/hosted-agent-responses-api/operations/create-response\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"apim-yxz4ztnhs2gd4/hosted-agent-responses-api/create-response\",\n", - " \"resourceType\": \"Microsoft.ApiManagement/service/apis/operations\"\n", - " },\n", - " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4/apis/hosted-agent-responses-api\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"apim-yxz4ztnhs2gd4/hosted-agent-responses-api\",\n", - " \"resourceType\": \"Microsoft.ApiManagement/service/apis\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4/apis/hosted-agent-responses-api/policies/policy\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"apim-yxz4ztnhs2gd4/hosted-agent-responses-api/policy\",\n", - " \"resourceType\": \"Microsoft.ApiManagement/service/apis/policies\"\n", - " },\n", - " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/lawModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"lawModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/appInsightsModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"appInsightsModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " },\n", - " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/appInsightsModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"appInsightsModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " },\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/lawModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"lawModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/apimModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"apimModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " },\n", - " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/apimModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"apimModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " },\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/appInsightsModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"appInsightsModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/foundryModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"foundryModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " },\n", - " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/apimModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"apimModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " },\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/appInsightsModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"appInsightsModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " },\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/foundryModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"foundryModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/inferenceAPIModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"inferenceAPIModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " },\n", - " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/foundryModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"foundryModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-models-yxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/58ab3a23-7cc7-5f77-ac1f-abc3771bca77\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"58ab3a23-7cc7-5f77-ac1f-abc3771bca77\",\n", - " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", - " },\n", - " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/foundryModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"foundryModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-agents-yxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/757d48fe-4b02-501f-aa26-dc072a3df0ec\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"757d48fe-4b02-501f-aa26-dc072a3df0ec\",\n", - " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", - " }\n", - " ],\n", - " \"diagnostics\": [\n", - " {\n", - " \"additionalInfo\": null,\n", - " \"code\": \"NestedDeploymentShortCircuited\",\n", - " \"level\": \"Warning\",\n", - " \"message\": \"A nested deployment got short-circuited and all its resources got skipped from validation. This is due to a nested template having a parameter that was not fully evaluated (e.g. contains a reference() function). Please see https://aka.ms/WhatIfEvalStopped for more guidance.\",\n", - " \"target\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/appInsightsModule\"\n", - " },\n", - " {\n", - " \"additionalInfo\": null,\n", - " \"code\": \"NestedDeploymentShortCircuited\",\n", - " \"level\": \"Warning\",\n", - " \"message\": \"A nested deployment got short-circuited and all its resources got skipped from validation. This is due to a nested template having a parameter that was not fully evaluated (e.g. contains a reference() function). Please see https://aka.ms/WhatIfEvalStopped for more guidance.\",\n", - " \"target\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/apimModule\"\n", - " },\n", - " {\n", - " \"additionalInfo\": null,\n", - " \"code\": \"NestedDeploymentShortCircuited\",\n", - " \"level\": \"Warning\",\n", - " \"message\": \"A nested deployment got short-circuited and all its resources got skipped from validation. This is due to a nested template having a parameter that was not fully evaluated (e.g. contains a reference() function). Please see https://aka.ms/WhatIfEvalStopped for more guidance.\",\n", - " \"target\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/foundryModule\"\n", - " },\n", - " {\n", - " \"additionalInfo\": null,\n", - " \"code\": \"NestedDeploymentShortCircuited\",\n", - " \"level\": \"Warning\",\n", - " \"message\": \"A nested deployment got short-circuited and all its resources got skipped from validation. This is due to a nested template having a parameter that was not fully evaluated (e.g. contains a reference() function). Please see https://aka.ms/WhatIfEvalStopped for more guidance.\",\n", - " \"target\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/inferenceAPIModule\"\n", - " }\n", - " ],\n", - " \"duration\": \"PT0S\",\n", - " \"error\": null,\n", - " \"extensions\": [],\n", - " \"mode\": \"Incremental\",\n", - " \"onErrorDeployment\": null,\n", - " \"outputResources\": null,\n", - " \"outputs\": null,\n", - " \"parameters\": {\n", - " \"aiServicesConfig\": {\n", - " \"type\": \"Array\",\n", - " \"value\": [\n", - " {\n", - " \"location\": \"swedencentral\",\n", - " \"name\": \"foundry-models\",\n", - " \"priority\": 1,\n", - " \"weight\": 100\n", - " },\n", - " {\n", - " \"location\": \"swedencentral\",\n", - " \"name\": \"foundry-agents\",\n", - " \"priority\": 1,\n", - " \"weight\": 100\n", - " }\n", - " ]\n", - " },\n", - " \"apimSku\": {\n", - " \"type\": \"String\",\n", - " \"value\": \"Basicv2\"\n", - " },\n", - " \"apimSubscriptionsConfig\": {\n", - " \"type\": \"Array\",\n", - " \"value\": [\n", - " {\n", - " \"displayName\": \"Starter\",\n", - " \"name\": \"starter\",\n", - " \"scope\": \"/apis\"\n", - " }\n", - " ]\n", - " },\n", - " \"enableHostedAgentResponsesApi\": {\n", - " \"type\": \"Bool\",\n", - " \"value\": true\n", - " },\n", - " \"foundryAgentAiServiceIndex\": {\n", - " \"type\": \"Int\",\n", - " \"value\": 1\n", - " },\n", - " \"foundryProjectName\": {\n", - " \"type\": \"String\",\n", - " \"value\": \"default\"\n", - " },\n", - " \"foundryUserObjectIds\": {\n", - " \"type\": \"Array\",\n", - " \"value\": [\n", - " \"13f94c0d-8a51-492a-928b-59392c23c1ac\"\n", - " ]\n", - " },\n", - " \"hostedAgentResponsesApiPath\": {\n", - " \"type\": \"String\",\n", - " \"value\": \"hosted-agent-responses\"\n", - " },\n", - " \"inferenceAPIPath\": {\n", - " \"type\": \"String\",\n", - " \"value\": \"inference\"\n", - " },\n", - " \"inferenceAPIType\": {\n", - " \"type\": \"String\",\n", - " \"value\": \"AzureAI\"\n", - " },\n", - " \"modelsConfig\": {\n", - " \"type\": \"Array\",\n", - " \"value\": [\n", - " {\n", - " \"aiservice\": \"foundry-models\",\n", - " \"capacity\": 10,\n", - " \"name\": \"gpt-5-mini\",\n", - " \"publisher\": \"OpenAI\",\n", - " \"sku\": \"GlobalStandard\",\n", - " \"version\": \"2025-08-07\"\n", - " }\n", - " ]\n", - " }\n", - " },\n", - " \"parametersLink\": null,\n", - " \"providers\": [\n", - " {\n", - " \"id\": null,\n", - " \"namespace\": \"Microsoft.ContainerRegistry\",\n", - " \"providerAuthorizationConsentState\": null,\n", - " \"registrationPolicy\": null,\n", - " \"registrationState\": null,\n", - " \"resourceTypes\": [\n", - " {\n", - " \"aliases\": null,\n", - " \"apiProfiles\": null,\n", - " \"apiVersions\": null,\n", - " \"capabilities\": null,\n", - " \"defaultApiVersion\": null,\n", - " \"locationMappings\": null,\n", - " \"locations\": [\n", - " \"swedencentral\"\n", - " ],\n", - " \"properties\": null,\n", - " \"resourceType\": \"registries\",\n", - " \"zoneMappings\": null\n", - " }\n", - " ]\n", - " },\n", - " {\n", - " \"id\": null,\n", - " \"namespace\": \"Microsoft.CognitiveServices\",\n", - " \"providerAuthorizationConsentState\": null,\n", - " \"registrationPolicy\": null,\n", - " \"registrationState\": null,\n", - " \"resourceTypes\": [\n", - " {\n", - " \"aliases\": null,\n", - " \"apiProfiles\": null,\n", - " \"apiVersions\": null,\n", - " \"capabilities\": null,\n", - " \"defaultApiVersion\": null,\n", - " \"locationMappings\": null,\n", - " \"locations\": [\n", - " null\n", - " ],\n", - " \"properties\": null,\n", - " \"resourceType\": \"accounts/projects\",\n", - " \"zoneMappings\": null\n", - " }\n", - " ]\n", - " },\n", - " {\n", - " \"id\": null,\n", - " \"namespace\": \"Microsoft.Authorization\",\n", - " \"providerAuthorizationConsentState\": null,\n", - " \"registrationPolicy\": null,\n", - " \"registrationState\": null,\n", - " \"resourceTypes\": [\n", - " {\n", - " \"aliases\": null,\n", - " \"apiProfiles\": null,\n", - " \"apiVersions\": null,\n", - " \"capabilities\": null,\n", - " \"defaultApiVersion\": null,\n", - " \"locationMappings\": null,\n", - " \"locations\": [\n", - " null\n", - " ],\n", - " \"properties\": null,\n", - " \"resourceType\": \"roleAssignments\",\n", - " \"zoneMappings\": null\n", - " }\n", - " ]\n", - " },\n", - " {\n", - " \"id\": null,\n", - " \"namespace\": \"Microsoft.ApiManagement\",\n", - " \"providerAuthorizationConsentState\": null,\n", - " \"registrationPolicy\": null,\n", - " \"registrationState\": null,\n", - " \"resourceTypes\": [\n", - " {\n", - " \"aliases\": null,\n", - " \"apiProfiles\": null,\n", - " \"apiVersions\": null,\n", - " \"capabilities\": null,\n", - " \"defaultApiVersion\": null,\n", - " \"locationMappings\": null,\n", - " \"locations\": [\n", - " null\n", - " ],\n", - " \"properties\": null,\n", - " \"resourceType\": \"service/apis\",\n", - " \"zoneMappings\": null\n", - " },\n", - " {\n", - " \"aliases\": null,\n", - " \"apiProfiles\": null,\n", - " \"apiVersions\": null,\n", - " \"capabilities\": null,\n", - " \"defaultApiVersion\": null,\n", - " \"locationMappings\": null,\n", - " \"locations\": [\n", - " null\n", - " ],\n", - " \"properties\": null,\n", - " \"resourceType\": \"service/apis/operations\",\n", - " \"zoneMappings\": null\n", - " },\n", - " {\n", - " \"aliases\": null,\n", - " \"apiProfiles\": null,\n", - " \"apiVersions\": null,\n", - " \"capabilities\": null,\n", - " \"defaultApiVersion\": null,\n", - " \"locationMappings\": null,\n", - " \"locations\": [\n", - " null\n", - " ],\n", - " \"properties\": null,\n", - " \"resourceType\": \"service/apis/policies\",\n", - " \"zoneMappings\": null\n", - " }\n", - " ]\n", - " },\n", - " {\n", - " \"id\": null,\n", - " \"namespace\": \"Microsoft.Resources\",\n", - " \"providerAuthorizationConsentState\": null,\n", - " \"registrationPolicy\": null,\n", - " \"registrationState\": null,\n", - " \"resourceTypes\": [\n", - " {\n", - " \"aliases\": null,\n", - " \"apiProfiles\": null,\n", - " \"apiVersions\": null,\n", - " \"capabilities\": null,\n", - " \"defaultApiVersion\": null,\n", - " \"locationMappings\": null,\n", - " \"locations\": [\n", - " null\n", - " ],\n", - " \"properties\": null,\n", - " \"resourceType\": \"deployments\",\n", - " \"zoneMappings\": null\n", - " }\n", - " ]\n", - " }\n", - " ],\n", - " \"provisioningState\": \"Succeeded\",\n", - " \"templateHash\": \"944749034799081610\",\n", - " \"templateLink\": null,\n", - " \"timestamp\": \"2026-07-09T09:31:29.019113+00:00\",\n", - " \"validatedResources\": [\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4/apis/hosted-agent-responses-api\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": null\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4/apis/hosted-agent-responses-api/operations/create-response\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": null\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4/apis/hosted-agent-responses-api/policies/policy\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": null\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-agents-yxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/757d48fe-4b02-501f-aa26-dc072a3df0ec\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": null\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-models-yxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/58ab3a23-7cc7-5f77-ac1f-abc3771bca77\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": null\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": null\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/22772208-617f-5e2a-a6b2-54fc8f9e266a\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": null\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/287399b4-a485-5e81-91b5-642b7b0611c6\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": null\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/5cd3021a-9d23-5cde-8978-b5d478bd4dc1\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": null\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/73a770d5-7324-58bf-89ad-0020ab023a16\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": null\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/941f7566-c405-5201-929e-29bfe676fa27\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": null\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/94db8588-bfb9-5498-ade3-6f2e83b34ea4\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": null\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/d106d8d7-7d30-5168-bd6f-4b3f07e87cfe\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": null\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.OperationalInsights/workspaces/workspace-yxz4ztnhs2gd4\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": null\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/apimModule\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": null\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/appInsightsModule\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": null\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/foundryModule\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": null\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/inferenceAPIModule\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": null\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/lawModule\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": null\n", - " }\n", - " ],\n", - " \"validationLevel\": null\n", - " },\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"type\": \"Microsoft.Resources/deployments\"\n", - "}\n", - "\n", - "\n", - "$ cmd /c C:\\Program Files\\Microsoft SDKs\\Azure\\CLI2\\wbin\\az.cmd deployment group create --resource-group rg-aigw-hosted-custom-framework-v2 --name deploy-hosted-custom-framework --template-file C:\\GitHub\\ai-gateway\\AI-Gateway\\labs\\ai-foundry-hosted-agents-custom-framework\\main.bicep --parameters @C:\\GitHub\\ai-gateway\\AI-Gateway\\labs\\ai-foundry-hosted-agents-custom-framework\\main.parameters.generated.json --only-show-errors\n", - "{\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/deploy-hosted-custom-framework\",\n", - " \"location\": null,\n", - " \"name\": \"deploy-hosted-custom-framework\",\n", - " \"properties\": {\n", - " \"correlationId\": \"df19d468-d64d-477b-b007-538918bf8e04\",\n", - " \"debugSetting\": null,\n", - " \"dependencies\": [\n", - " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/foundryModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"foundryModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-models-yxz4ztnhs2gd4/projects/default-foundry-models\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"foundry-models-yxz4ztnhs2gd4/default-foundry-models\",\n", - " \"resourceType\": \"Microsoft.CognitiveServices/accounts/projects\"\n", - " },\n", - " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/foundryModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"foundryModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-agents-yxz4ztnhs2gd4/projects/default-foundry-agents\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"foundry-agents-yxz4ztnhs2gd4/default-foundry-agents\",\n", - " \"resourceType\": \"Microsoft.CognitiveServices/accounts/projects\"\n", - " },\n", - " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"acryxz4ztnhs2gd4\",\n", - " \"resourceType\": \"Microsoft.ContainerRegistry/registries\"\n", - " },\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/foundryModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"foundryModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/22772208-617f-5e2a-a6b2-54fc8f9e266a\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"22772208-617f-5e2a-a6b2-54fc8f9e266a\",\n", - " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", - " },\n", - " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"acryxz4ztnhs2gd4\",\n", - " \"resourceType\": \"Microsoft.ContainerRegistry/registries\"\n", - " },\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/foundryModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"foundryModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " },\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-models-yxz4ztnhs2gd4/projects/default-foundry-models\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"foundry-models-yxz4ztnhs2gd4/default-foundry-models\",\n", - " \"resourceType\": \"Microsoft.CognitiveServices/accounts/projects\"\n", - " },\n", - " {\n", - " \"apiVersion\": \"2025-04-01-preview\",\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-models-yxz4ztnhs2gd4/projects/default-foundry-models\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"foundry-models-yxz4ztnhs2gd4/default-foundry-models\",\n", - " \"resourceType\": \"Microsoft.CognitiveServices/accounts/projects\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/d106d8d7-7d30-5168-bd6f-4b3f07e87cfe\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"d106d8d7-7d30-5168-bd6f-4b3f07e87cfe\",\n", - " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", - " },\n", - " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"acryxz4ztnhs2gd4\",\n", - " \"resourceType\": \"Microsoft.ContainerRegistry/registries\"\n", - " },\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/foundryModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"foundryModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/94db8588-bfb9-5498-ade3-6f2e83b34ea4\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"94db8588-bfb9-5498-ade3-6f2e83b34ea4\",\n", - " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", - " },\n", - " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"acryxz4ztnhs2gd4\",\n", - " \"resourceType\": \"Microsoft.ContainerRegistry/registries\"\n", - " },\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/foundryModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"foundryModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/287399b4-a485-5e81-91b5-642b7b0611c6\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"287399b4-a485-5e81-91b5-642b7b0611c6\",\n", - " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", - " },\n", - " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-agents-yxz4ztnhs2gd4/projects/default-foundry-agents\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"foundry-agents-yxz4ztnhs2gd4/default-foundry-agents\",\n", - " \"resourceType\": \"Microsoft.CognitiveServices/accounts/projects\"\n", - " },\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"acryxz4ztnhs2gd4\",\n", - " \"resourceType\": \"Microsoft.ContainerRegistry/registries\"\n", - " },\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/foundryModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"foundryModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " },\n", - " {\n", - " \"apiVersion\": \"2025-04-01-preview\",\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-agents-yxz4ztnhs2gd4/projects/default-foundry-agents\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"foundry-agents-yxz4ztnhs2gd4/default-foundry-agents\",\n", - " \"resourceType\": \"Microsoft.CognitiveServices/accounts/projects\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/5cd3021a-9d23-5cde-8978-b5d478bd4dc1\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"5cd3021a-9d23-5cde-8978-b5d478bd4dc1\",\n", - " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", - " },\n", - " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"acryxz4ztnhs2gd4\",\n", - " \"resourceType\": \"Microsoft.ContainerRegistry/registries\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/941f7566-c405-5201-929e-29bfe676fa27\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"941f7566-c405-5201-929e-29bfe676fa27\",\n", - " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", - " },\n", - " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"acryxz4ztnhs2gd4\",\n", - " \"resourceType\": \"Microsoft.ContainerRegistry/registries\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/73a770d5-7324-58bf-89ad-0020ab023a16\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"73a770d5-7324-58bf-89ad-0020ab023a16\",\n", - " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", - " },\n", - " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/apimModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"apimModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " },\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/foundryModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"foundryModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4/apis/hosted-agent-responses-api\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"apim-yxz4ztnhs2gd4/hosted-agent-responses-api\",\n", - " \"resourceType\": \"Microsoft.ApiManagement/service/apis\"\n", - " },\n", - " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4/apis/hosted-agent-responses-api\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"apim-yxz4ztnhs2gd4/hosted-agent-responses-api\",\n", - " \"resourceType\": \"Microsoft.ApiManagement/service/apis\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4/apis/hosted-agent-responses-api/operations/create-response\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"apim-yxz4ztnhs2gd4/hosted-agent-responses-api/create-response\",\n", - " \"resourceType\": \"Microsoft.ApiManagement/service/apis/operations\"\n", - " },\n", - " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4/apis/hosted-agent-responses-api\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"apim-yxz4ztnhs2gd4/hosted-agent-responses-api\",\n", - " \"resourceType\": \"Microsoft.ApiManagement/service/apis\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4/apis/hosted-agent-responses-api/policies/policy\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"apim-yxz4ztnhs2gd4/hosted-agent-responses-api/policy\",\n", - " \"resourceType\": \"Microsoft.ApiManagement/service/apis/policies\"\n", - " },\n", - " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/lawModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"lawModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/appInsightsModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"appInsightsModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " },\n", - " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/appInsightsModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"appInsightsModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " },\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/lawModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"lawModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/apimModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"apimModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " },\n", - " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/apimModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"apimModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " },\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/appInsightsModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"appInsightsModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/foundryModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"foundryModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " },\n", - " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/apimModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"apimModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " },\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/appInsightsModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"appInsightsModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " },\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/foundryModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"foundryModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/inferenceAPIModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"inferenceAPIModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " },\n", - " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/foundryModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"foundryModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-models-yxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/58ab3a23-7cc7-5f77-ac1f-abc3771bca77\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"58ab3a23-7cc7-5f77-ac1f-abc3771bca77\",\n", - " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", - " },\n", - " {\n", - " \"dependsOn\": [\n", - " {\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Resources/deployments/foundryModule\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"foundryModule\",\n", - " \"resourceType\": \"Microsoft.Resources/deployments\"\n", - " }\n", - " ],\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-agents-yxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/757d48fe-4b02-501f-aa26-dc072a3df0ec\",\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceName\": \"757d48fe-4b02-501f-aa26-dc072a3df0ec\",\n", - " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", - " }\n", - " ],\n", - " \"diagnostics\": null,\n", - " \"duration\": \"PT2M2.3055919S\",\n", - " \"error\": null,\n", - " \"extensions\": [],\n", - " \"mode\": \"Incremental\",\n", - " \"onErrorDeployment\": null,\n", - " \"outputResources\": [\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": \"Microsoft.ApiManagement/service\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4/apis/hosted-agent-responses-api\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": \"Microsoft.ApiManagement/service/apis\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4/apis/hosted-agent-responses-api/operations/create-response\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": \"Microsoft.ApiManagement/service/apis/operations\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4/apis/hosted-agent-responses-api/policies/policy\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": \"Microsoft.ApiManagement/service/apis/policies\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4/apis/inference-api\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": \"Microsoft.ApiManagement/service/apis\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4/apis/inference-api/diagnostics/applicationinsights\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": \"Microsoft.ApiManagement/service/apis/diagnostics\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4/apis/inference-api/diagnostics/azuremonitor\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": \"Microsoft.ApiManagement/service/apis/diagnostics\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4/apis/inference-api/policies/policy\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": \"Microsoft.ApiManagement/service/apis/policies\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4/backends/foundry-models\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": \"Microsoft.ApiManagement/service/backends\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4/loggers/appinsights-logger\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": \"Microsoft.ApiManagement/service/loggers\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4/loggers/azuremonitor\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": \"Microsoft.ApiManagement/service/loggers\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4/providers/Microsoft.Insights/diagnosticSettings/apimDiagnosticSettings\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": \"Microsoft.Insights/diagnosticSettings\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4/subscriptions/starter\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": \"Microsoft.ApiManagement/service/subscriptions\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-agents-yxz4ztnhs2gd4\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": \"Microsoft.CognitiveServices/accounts\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-agents-yxz4ztnhs2gd4/connections/foundry-agents-yxz4ztnhs2gd4-appInsights-connection\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": \"Microsoft.CognitiveServices/accounts/connections\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-agents-yxz4ztnhs2gd4/projects/default-foundry-agents\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": \"Microsoft.CognitiveServices/accounts/projects\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-agents-yxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/1956dcf8-77d7-591d-a940-6564ee8ba21e\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-agents-yxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/757d48fe-4b02-501f-aa26-dc072a3df0ec\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-agents-yxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/e689c10f-239d-52af-9c10-7b01d61cae15\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-models-yxz4ztnhs2gd4\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": \"Microsoft.CognitiveServices/accounts\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-models-yxz4ztnhs2gd4/connections/foundry-models-yxz4ztnhs2gd4-appInsights-connection\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": \"Microsoft.CognitiveServices/accounts/connections\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-models-yxz4ztnhs2gd4/deployments/gpt-5-mini\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": \"Microsoft.CognitiveServices/accounts/deployments\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-models-yxz4ztnhs2gd4/projects/default-foundry-models\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": \"Microsoft.CognitiveServices/accounts/projects\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-models-yxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/58ab3a23-7cc7-5f77-ac1f-abc3771bca77\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-models-yxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/7c4e7696-3e5d-5b71-8a44-de468b930e9d\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.CognitiveServices/accounts/foundry-models-yxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/803cc8f7-4801-5149-9676-6312f1b651ad\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": \"Microsoft.ContainerRegistry/registries\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/22772208-617f-5e2a-a6b2-54fc8f9e266a\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/287399b4-a485-5e81-91b5-642b7b0611c6\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/5cd3021a-9d23-5cde-8978-b5d478bd4dc1\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/73a770d5-7324-58bf-89ad-0020ab023a16\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/941f7566-c405-5201-929e-29bfe676fa27\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/94db8588-bfb9-5498-ade3-6f2e83b34ea4\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ContainerRegistry/registries/acryxz4ztnhs2gd4/providers/Microsoft.Authorization/roleAssignments/d106d8d7-7d30-5168-bd6f-4b3f07e87cfe\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": \"Microsoft.Authorization/roleAssignments\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.Insights/components/insights-yxz4ztnhs2gd4\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": \"Microsoft.Insights/components\"\n", - " },\n", - " {\n", - " \"apiVersion\": null,\n", - " \"extension\": null,\n", - " \"id\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.OperationalInsights/workspaces/workspace-yxz4ztnhs2gd4\",\n", - " \"identifiers\": null,\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"resourceType\": \"Microsoft.OperationalInsights/workspaces\"\n", - " }\n", - " ],\n", - " \"outputs\": {\n", - " \"aiGatewayUrl\": {\n", - " \"type\": \"String\",\n", - " \"value\": \"https://apim-yxz4ztnhs2gd4.azure-api.net/inference\"\n", - " },\n", - " \"apimGatewayUrl\": {\n", - " \"type\": \"String\",\n", - " \"value\": \"https://apim-yxz4ztnhs2gd4.azure-api.net\"\n", - " },\n", - " \"apimServiceId\": {\n", - " \"type\": \"String\",\n", - " \"value\": \"/subscriptions/baba41cf-c01d-4a55-b6c5-ca494b802be5/resourceGroups/rg-aigw-hosted-custom-framework-v2/providers/Microsoft.ApiManagement/service/apim-yxz4ztnhs2gd4\"\n", - " },\n", - " \"apimSubscriptions\": {\n", - " \"type\": \"Array\",\n", - " \"value\": [\n", - " {\n", - " \"displayName\": \"Starter\",\n", - " \"key\": \"d758c99aca6b4231980d5c0ff6917c59\",\n", - " \"name\": \"starter\"\n", - " }\n", - " ]\n", - " },\n", - " \"containerRegistryLoginServer\": {\n", - " \"type\": \"String\",\n", - " \"value\": \"acryxz4ztnhs2gd4.azurecr.io\"\n", - " },\n", - " \"containerRegistryName\": {\n", - " \"type\": \"String\",\n", - " \"value\": \"acryxz4ztnhs2gd4\"\n", - " },\n", - " \"foundryAgentAiServicesEndpoint\": {\n", - " \"type\": \"String\",\n", - " \"value\": \"https://foundry-agents-yxz4ztnhs2gd4.cognitiveservices.azure.com/\"\n", - " },\n", - " \"foundryAgentProjectEndpoint\": {\n", - " \"type\": \"String\",\n", - " \"value\": \"https://foundry-agents-yxz4ztnhs2gd4.services.ai.azure.com/api/projects/default-foundry-agents\"\n", - " },\n", - " \"foundryAiServicesEndpoint\": {\n", - " \"type\": \"String\",\n", - " \"value\": \"https://foundry-models-yxz4ztnhs2gd4.cognitiveservices.azure.com/\"\n", - " },\n", - " \"foundryProjectEndpoint\": {\n", - " \"type\": \"String\",\n", - " \"value\": \"https://foundry-models-yxz4ztnhs2gd4.services.ai.azure.com/api/projects/default-foundry-models\"\n", - " },\n", - " \"hostedAgentResponsesApimPath\": {\n", - " \"type\": \"String\",\n", - " \"value\": \"https://apim-yxz4ztnhs2gd4.azure-api.net/hosted-agent-responses/responses\"\n", - " },\n", - " \"logAnalyticsWorkspaceId\": {\n", - " \"type\": \"String\",\n", - " \"value\": \"3a0ebd2e-444f-4fea-95a4-c0816d17c6f2\"\n", - " }\n", - " },\n", - " \"parameters\": {\n", - " \"aiServicesConfig\": {\n", - " \"type\": \"Array\",\n", - " \"value\": [\n", - " {\n", - " \"location\": \"swedencentral\",\n", - " \"name\": \"foundry-models\",\n", - " \"priority\": 1,\n", - " \"weight\": 100\n", - " },\n", - " {\n", - " \"location\": \"swedencentral\",\n", - " \"name\": \"foundry-agents\",\n", - " \"priority\": 1,\n", - " \"weight\": 100\n", - " }\n", - " ]\n", - " },\n", - " \"apimSku\": {\n", - " \"type\": \"String\",\n", - " \"value\": \"Basicv2\"\n", - " },\n", - " \"apimSubscriptionsConfig\": {\n", - " \"type\": \"Array\",\n", - " \"value\": [\n", - " {\n", - " \"displayName\": \"Starter\",\n", - " \"name\": \"starter\",\n", - " \"scope\": \"/apis\"\n", - " }\n", - " ]\n", - " },\n", - " \"enableHostedAgentResponsesApi\": {\n", - " \"type\": \"Bool\",\n", - " \"value\": true\n", - " },\n", - " \"foundryAgentAiServiceIndex\": {\n", - " \"type\": \"Int\",\n", - " \"value\": 1\n", - " },\n", - " \"foundryProjectName\": {\n", - " \"type\": \"String\",\n", - " \"value\": \"default\"\n", - " },\n", - " \"foundryUserObjectIds\": {\n", - " \"type\": \"Array\",\n", - " \"value\": [\n", - " \"13f94c0d-8a51-492a-928b-59392c23c1ac\"\n", - " ]\n", - " },\n", - " \"hostedAgentResponsesApiPath\": {\n", - " \"type\": \"String\",\n", - " \"value\": \"hosted-agent-responses\"\n", - " },\n", - " \"inferenceAPIPath\": {\n", - " \"type\": \"String\",\n", - " \"value\": \"inference\"\n", - " },\n", - " \"inferenceAPIType\": {\n", - " \"type\": \"String\",\n", - " \"value\": \"AzureAI\"\n", - " },\n", - " \"modelsConfig\": {\n", - " \"type\": \"Array\",\n", - " \"value\": [\n", - " {\n", - " \"aiservice\": \"foundry-models\",\n", - " \"capacity\": 10,\n", - " \"name\": \"gpt-5-mini\",\n", - " \"publisher\": \"OpenAI\",\n", - " \"sku\": \"GlobalStandard\",\n", - " \"version\": \"2025-08-07\"\n", - " }\n", - " ]\n", - " }\n", - " },\n", - " \"parametersLink\": null,\n", - " \"providers\": [\n", - " {\n", - " \"id\": null,\n", - " \"namespace\": \"Microsoft.ContainerRegistry\",\n", - " \"providerAuthorizationConsentState\": null,\n", - " \"registrationPolicy\": null,\n", - " \"registrationState\": null,\n", - " \"resourceTypes\": [\n", - " {\n", - " \"aliases\": null,\n", - " \"apiProfiles\": null,\n", - " \"apiVersions\": null,\n", - " \"capabilities\": null,\n", - " \"defaultApiVersion\": null,\n", - " \"locationMappings\": null,\n", - " \"locations\": [\n", - " \"swedencentral\"\n", - " ],\n", - " \"properties\": null,\n", - " \"resourceType\": \"registries\",\n", - " \"zoneMappings\": null\n", - " }\n", - " ]\n", - " },\n", - " {\n", - " \"id\": null,\n", - " \"namespace\": \"Microsoft.CognitiveServices\",\n", - " \"providerAuthorizationConsentState\": null,\n", - " \"registrationPolicy\": null,\n", - " \"registrationState\": null,\n", - " \"resourceTypes\": [\n", - " {\n", - " \"aliases\": null,\n", - " \"apiProfiles\": null,\n", - " \"apiVersions\": null,\n", - " \"capabilities\": null,\n", - " \"defaultApiVersion\": null,\n", - " \"locationMappings\": null,\n", - " \"locations\": [\n", - " null\n", - " ],\n", - " \"properties\": null,\n", - " \"resourceType\": \"accounts/projects\",\n", - " \"zoneMappings\": null\n", - " }\n", - " ]\n", - " },\n", - " {\n", - " \"id\": null,\n", - " \"namespace\": \"Microsoft.Authorization\",\n", - " \"providerAuthorizationConsentState\": null,\n", - " \"registrationPolicy\": null,\n", - " \"registrationState\": null,\n", - " \"resourceTypes\": [\n", - " {\n", - " \"aliases\": null,\n", - " \"apiProfiles\": null,\n", - " \"apiVersions\": null,\n", - " \"capabilities\": null,\n", - " \"defaultApiVersion\": null,\n", - " \"locationMappings\": null,\n", - " \"locations\": [\n", - " null\n", - " ],\n", - " \"properties\": null,\n", - " \"resourceType\": \"roleAssignments\",\n", - " \"zoneMappings\": null\n", - " }\n", - " ]\n", - " },\n", - " {\n", - " \"id\": null,\n", - " \"namespace\": \"Microsoft.ApiManagement\",\n", - " \"providerAuthorizationConsentState\": null,\n", - " \"registrationPolicy\": null,\n", - " \"registrationState\": null,\n", - " \"resourceTypes\": [\n", - " {\n", - " \"aliases\": null,\n", - " \"apiProfiles\": null,\n", - " \"apiVersions\": null,\n", - " \"capabilities\": null,\n", - " \"defaultApiVersion\": null,\n", - " \"locationMappings\": null,\n", - " \"locations\": [\n", - " null\n", - " ],\n", - " \"properties\": null,\n", - " \"resourceType\": \"service/apis\",\n", - " \"zoneMappings\": null\n", - " },\n", - " {\n", - " \"aliases\": null,\n", - " \"apiProfiles\": null,\n", - " \"apiVersions\": null,\n", - " \"capabilities\": null,\n", - " \"defaultApiVersion\": null,\n", - " \"locationMappings\": null,\n", - " \"locations\": [\n", - " null\n", - " ],\n", - " \"properties\": null,\n", - " \"resourceType\": \"service/apis/operations\",\n", - " \"zoneMappings\": null\n", - " },\n", - " {\n", - " \"aliases\": null,\n", - " \"apiProfiles\": null,\n", - " \"apiVersions\": null,\n", - " \"capabilities\": null,\n", - " \"defaultApiVersion\": null,\n", - " \"locationMappings\": null,\n", - " \"locations\": [\n", - " null\n", - " ],\n", - " \"properties\": null,\n", - " \"resourceType\": \"service/apis/policies\",\n", - " \"zoneMappings\": null\n", - " }\n", - " ]\n", - " },\n", - " {\n", - " \"id\": null,\n", - " \"namespace\": \"Microsoft.Resources\",\n", - " \"providerAuthorizationConsentState\": null,\n", - " \"registrationPolicy\": null,\n", - " \"registrationState\": null,\n", - " \"resourceTypes\": [\n", - " {\n", - " \"aliases\": null,\n", - " \"apiProfiles\": null,\n", - " \"apiVersions\": null,\n", - " \"capabilities\": null,\n", - " \"defaultApiVersion\": null,\n", - " \"locationMappings\": null,\n", - " \"locations\": [\n", - " null\n", - " ],\n", - " \"properties\": null,\n", - " \"resourceType\": \"deployments\",\n", - " \"zoneMappings\": null\n", - " }\n", - " ]\n", - " }\n", - " ],\n", - " \"provisioningState\": \"Succeeded\",\n", - " \"templateHash\": \"944749034799081610\",\n", - " \"templateLink\": null,\n", - " \"timestamp\": \"2026-07-09T09:33:58.842701+00:00\",\n", - " \"validatedResources\": null,\n", - " \"validationLevel\": null\n", - " },\n", - " \"resourceGroup\": \"rg-aigw-hosted-custom-framework-v2\",\n", - " \"tags\": null,\n", - " \"type\": \"Microsoft.Resources/deployments\"\n", - "}\n", - "\n" - ] - } - ], + "outputs": [], "source": [ "# Create resource group and deploy Bicep\n", "# Ensure Azure CLI directory is available to subprocess calls in this kernel\n", From 2a6ba16637ff2a66ba6ba6a7055a623b0d9b4d45 Mon Sep 17 00:00:00 2001 From: George Ollis Date: Thu, 9 Jul 2026 17:13:02 +0100 Subject: [PATCH 08/17] Add Strands agent framework implementation and dependencies - Implemented the Strands agent framework in main.py, enabling server-side function calling and multi-turn conversation tracking. - Added environment variable configurations for Azure OpenAI integration. - Created requirements-strands.txt to manage dependencies for the Strands framework, including azure-ai-agentserver-responses and strands-agents. --- .../README.md | 230 ++-- ...undry-hosted-agents-custom-framework.ipynb | 35 +- .../01_hosted_agent_strands_setup.ipynb | 502 ++++++++ .../02_hosted_agent_pydantic_setup.ipynb | 902 +++++++++++++ .../src/responses/agents/frameworks/README.md | 220 ++++ .../pydantic}/.dockerignore | 0 .../pydantic}/.gitignore | 0 .../agents/frameworks/pydantic/Dockerfile | 7 + .../pydantic}/README.md | 4 +- .../pydantic}/image.png | Bin .../pydantic}/main.py | 56 +- .../pydantic/requirements-pydantic.txt} | 0 .../{ => frameworks}/strands/.dockerignore | 0 .../{ => frameworks}/strands/.gitignore | 0 .../agents/frameworks/strands/Dockerfile | 7 + .../agents/{ => frameworks}/strands/README.md | 0 .../{ => frameworks}/strands/example.env | 0 .../agents/{ => frameworks}/strands/image.png | Bin .../agents/{ => frameworks}/strands/main.py | 0 .../strands/requirements-strands.txt} | 0 .../01_hosted_agent_pydantic_setup.ipynb | 187 --- .../responses/agents/pydantic-ai/Dockerfile | 7 - .../01_hosted_agent_strands_setup.ipynb | 1128 ----------------- .../src/responses/agents/strands/Dockerfile | 7 - 24 files changed, 1805 insertions(+), 1487 deletions(-) create mode 100644 labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/01_hosted_agent_strands_setup.ipynb create mode 100644 labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/02_hosted_agent_pydantic_setup.ipynb create mode 100644 labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/README.md rename labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/{pydantic-ai => frameworks/pydantic}/.dockerignore (100%) rename labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/{pydantic-ai => frameworks/pydantic}/.gitignore (100%) create mode 100644 labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/pydantic/Dockerfile rename labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/{pydantic-ai => frameworks/pydantic}/README.md (83%) rename labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/{pydantic-ai => frameworks/pydantic}/image.png (100%) rename labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/{pydantic-ai => frameworks/pydantic}/main.py (72%) rename labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/{pydantic-ai/requirements.txt => frameworks/pydantic/requirements-pydantic.txt} (100%) rename labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/{ => frameworks}/strands/.dockerignore (100%) rename labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/{ => frameworks}/strands/.gitignore (100%) create mode 100644 labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/strands/Dockerfile rename labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/{ => frameworks}/strands/README.md (100%) rename labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/{ => frameworks}/strands/example.env (100%) rename labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/{ => frameworks}/strands/image.png (100%) rename labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/{ => frameworks}/strands/main.py (100%) rename labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/{strands/requirements.txt => frameworks/strands/requirements-strands.txt} (100%) delete mode 100644 labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/pydantic-ai/01_hosted_agent_pydantic_setup.ipynb delete mode 100644 labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/pydantic-ai/Dockerfile delete mode 100644 labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/01_hosted_agent_strands_setup.ipynb delete mode 100644 labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/Dockerfile diff --git a/labs/ai-foundry-hosted-agents-custom-framework/README.md b/labs/ai-foundry-hosted-agents-custom-framework/README.md index 936e598b..a65897d3 100644 --- a/labs/ai-foundry-hosted-agents-custom-framework/README.md +++ b/labs/ai-foundry-hosted-agents-custom-framework/README.md @@ -9,7 +9,7 @@ services: - Azure API Management - Container Registry shortDescription: Deploy AI Foundry Hosted Agents built with custom frameworks, including Pydantic AI and Strands. -detailedDescription: This lab provides custom framework examples for AI Foundry Hosted Agents, showing how to package and deploy hosted agents built with Pydantic AI and Strands to Azure Container Apps. It includes a Bicep deployment for Azure API Management, Azure AI Foundry, and a GPT-5-Mini model deployment, plus end-to-end setup notebooks and Dockerfiles. +detailedDescription: This lab provides custom framework examples for AI Foundry Hosted Agents, showing how to package and deploy hosted agents built with Pydantic AI and Strands. It includes a Bicep deployment for Azure API Management, Azure AI Foundry resources, and a GPT-5-Mini model deployment, plus end-to-end setup notebooks and Dockerfiles. authors: - georgeollis tags: [] @@ -47,131 +47,129 @@ Agents are managed as platform assets in the Foundry control plane, with operati - You want framework flexibility without giving up Foundry governance and enterprise operations. - You need to standardize deployment and operations across multiple agent implementations. -## [Infrastructure deployment notebook](ai-foundry-hosted-agents-custom-framework.ipynb) +## Infrastructure Deployment Notebook -Use this notebook first to deploy core infrastructure with Bicep. +Use this notebook first to deploy core infrastructure with Bicep: + +- [ai-foundry-hosted-agents-custom-framework.ipynb](ai-foundry-hosted-agents-custom-framework.ipynb) ### What gets deployed -**Core Services:** -- Azure API Management (APIM) - Acts as the gateway and reverse proxy -- Microsoft Foundry (two separate AI Services resources): - - **foundry-models**: Hosts inference models (GPT-5-Mini) for your agents to use - - **foundry-agents**: Hosts your custom framework agent runtimes via Hosted Agents Responses protocol v1.0.0 -- Azure Container Registry (ACR) - Stores your agent container images -- Application Insights & Log Analytics - Provides observability and diagnostics - -**RBAC & Access Control:** -- ACR repository permissions for the hosted-agent Foundry resource (`Container Registry Repository Reader` + `AcrPull`) -- ACR repository permissions for the deploying user (`Container Registry Repository Writer` + `Container Registry Repository Catalog Lister`) -- Foundry User role assignments (`Foundry User`) for configured user object IDs across all Foundry resources - -**APIM Proxy Configuration** (optional, added when `enableHostedAgentResponsesApi=true`): -- Dedicated API endpoint proxying Foundry's Responses API -- **Dynamic Agent Routing**: Clients specify the target agent via `agent_reference` in the request body (not the URL) -- Managed identity token injection (Foundry authentication) -- Automatic header injection: - - `Content-Type: application/json` - - `Foundry-Features: HostedAgents=V1Preview` (required for preview access) -- Automatic query parameter enforcement: - - `api-version: 2025-05-15-preview` -- Uses APIM subscription key for client authentication (cleaner than managing bearer tokens on client side) -- **Agent-Agnostic Design**: Works with any deployed agent—no need to reconfigure APIM when you add a new agent - -Policy definition is in [hosted-agent-policy.xml](hosted-agent-policy.xml) for easy customization. +Core services: +- Azure API Management (APIM) as gateway and reverse proxy +- Microsoft Foundry resources (two AI Services resources): + - foundry-models: hosts inference models used by agents + - foundry-agents: hosts your custom framework runtimes via Hosted Agents Responses protocol v1.0.0 +- Azure Container Registry (ACR) for agent container images +- Application Insights and Log Analytics for observability + +RBAC and access control: +- ACR repository permissions for the hosted-agent Foundry resource (Container Registry Repository Reader + AcrPull) +- ACR repository permissions for the deploying user (Container Registry Repository Writer + Container Registry Repository Catalog Lister) +- Foundry User role assignments for configured user object IDs across Foundry resources + +APIM proxy configuration (optional, enabled when enableHostedAgentResponsesApi=true): +- Dedicated API endpoint proxying Foundry Hosted Agent Responses +- Managed identity token injection for Foundry authentication +- Header injection/enforcement: + - Content-Type: application/json + - Foundry-Features: HostedAgents=V1Preview +- Uses APIM subscription key for client authentication +- Supports multiple agents without APIM reconfiguration by using agent-specific URL paths + +Policy definition is in [hosted-agent-policy.xml](hosted-agent-policy.xml). The deployment template is in [main.bicep](main.bicep). -### Available samples +## Framework Samples -- [Pydantic AI sample](src/responses/agents/pydantic-ai/README.md) -- [Strands sample](src/responses/agents/strands/README.md) +- [Frameworks Overview](src/responses/agents/frameworks/README.md) +- [Strands Framework](src/responses/agents/frameworks/strands/README.md) +- [Pydantic AI Framework](src/responses/agents/frameworks/pydantic/README.md) -### Prerequisites +## Prerequisites -- [Python 3.12 or later version](https://www.python.org/) installed -- [VS Code](https://code.visualstudio.com/) installed with the [Jupyter notebook extension](https://marketplace.visualstudio.com/items?itemName=ms-toolsai.jupyter) enabled -- Python dependencies: Install via `pip install azure-ai-projects azure-identity requests` (or run the dependency cell in each notebook) -- [An Azure Subscription](https://azure.microsoft.com/free/) with [Contributor](https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles/privileged#contributor) + [RBAC Administrator](https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles/privileged#role-based-access-control-administrator) or [Owner](https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles/privileged#owner) roles -- [Azure CLI](https://learn.microsoft.com/cli/azure/install-azure-cli) installed and [signed into your Azure subscription](https://learn.microsoft.com/cli/azure/authenticate-azure-cli-interactively) -- [Docker](https://www.docker.com/get-started/) installed and running (for building container images) +- [Python 3.12 or later](https://www.python.org/) +- [VS Code](https://code.visualstudio.com/) with the [Jupyter extension](https://marketplace.visualstudio.com/items?itemName=ms-toolsai.jupyter) +- Python dependencies: install with pip install azure-ai-projects azure-identity requests (or run dependency cells in notebooks) +- [Azure subscription](https://azure.microsoft.com/free/) with Contributor + RBAC Administrator roles, or Owner role +- [Azure CLI](https://learn.microsoft.com/cli/azure/install-azure-cli) installed and authenticated +- [Docker](https://www.docker.com/get-started/) installed and running -### Get started +## Get Started -**Step 1: Deploy Infrastructure** +Step 1: Deploy infrastructure - Run all cells in [ai-foundry-hosted-agents-custom-framework.ipynb](ai-foundry-hosted-agents-custom-framework.ipynb) -- This creates your Foundry resources, APIM, ACR, and monitoring infrastructure -- Note the outputs (Foundry endpoints, ACR login server, APIM URL) for the next steps - -**Step 2: Choose & Deploy Your Agent** -- Pick one of the sample frameworks: [Pydantic AI](src/responses/agents/pydantic-ai/README.md) or [Strands](src/responses/agents/strands/README.md) -- Open the corresponding setup notebook and run all cells: - 1. Build the Docker container image for your agent framework - 2. Push the image to ACR - 3. Create a hosted agent version in your Foundry project - 4. Test the agent directly via Foundry's Responses API (baseline validation) - 5. Test the agent via APIM (validates the proxy gateway) - -**Step 3: Test via APIM (Optional)** -- APIM is automatically configured for any deployed agent -- In the sample agent notebooks (Section 4), clients specify the target agent via `agent_reference` in the request body -- Request format: - ```json - POST https://apim-{suffix}.azure-api.net/hosted-agent-responses/responses - Headers: api-key: {subscription-key} - Body: { - "agent_reference": { "type": "agent_reference", "name": "strands-agent", "version": "1" }, - "input": "Your prompt", - "model": "gpt-5-mini" - } - ``` -- Once you deploy additional agents to Foundry, simply change `agent_reference.name` in the request—no APIM reconfiguration needed - -### Test Flow Explained - -Each sample notebook includes three test scenarios: - -1. **Direct Foundry Test** (Section 3) - - Calls the Foundry Hosted Agent Responses API directly with agent name in URL - - Uses your Azure CLI credential (bearer token with `https://ai.azure.com/.default` audience) - - Validates the agent runtime and basic connectivity - - No APIM involvement—good baseline for troubleshooting - -2. **APIM Test** (Section 4) - - Routes through APIM gateway using subscription key (`api-key` header) - - Specifies the target agent via `agent_reference` in the request body (not the URL) - - APIM injects managed identity token to Foundry automatically - - APIM enforces `Content-Type`, `Foundry-Features`, and `api-version` headers - - Tests the full production-like path (client → APIM → Foundry agent) - - **Key difference**: You can change `agent_reference.name` to target different agents without reconfiguring APIM - -### Clean up resources - -Use the [clean-up-resources notebook](clean-up-resources.ipynb) to remove deployed resources when you are finished. - -### Troubleshooting - -**Section 3 (Direct Test) fails:** -- Check agent status in Foundry—should be "Running" -- Verify you're logged into Azure CLI (`az login`) -- Confirm the `PROJECT_ENDPOINT` is correct from the infrastructure deployment -- Check network connectivity (firewall, proxy) - -**Section 4 (APIM Test) fails but Section 3 succeeds:** -- Verify `APIM_SUFFIX` matches your APIM instance name -- Confirm `APIM_SUBSCRIPTION_KEY` is correct -- Check APIM policy in `hosted-agent-policy.xml`—ensure token audience is `https://ai.azure.com` -- Use APIM's TRACE tool to debug the request flow: - - In Azure Portal → APIM → Diagnose and solve problems → Trace - - Re-run your test and examine the detailed trace output - - Look for authentication errors, backend routing issues, or header mismatches - -**Agent container fails to start:** -- Check ACR permissions—Foundry resource identity needs `AcrPull` role -- Verify the container image URI in Foundry matches what you pushed to ACR -- Check logs via Foundry's diagnostics or Application Insights - -**For more help:** -- Review the [APIM policy file](hosted-agent-policy.xml) to understand header/parameter enforcement -- Check [Bicep template](main.bicep) for resource configuration details -- Consult [Microsoft Foundry documentation](https://learn.microsoft.com/en-us/foundry/) +- This provisions Foundry resources, APIM, ACR, and monitoring +- Capture outputs (project endpoint, ACR login server, APIM suffix, subscription key) + +Step 2: Choose and deploy your agent +- Open one setup notebook and run top-to-bottom: + - [src/responses/agents/frameworks/01_hosted_agent_strands_setup.ipynb](src/responses/agents/frameworks/01_hosted_agent_strands_setup.ipynb) + - [src/responses/agents/frameworks/02_hosted_agent_pydantic_setup.ipynb](src/responses/agents/frameworks/02_hosted_agent_pydantic_setup.ipynb) +- Each notebook performs: + - Docker build and push to ACR + - Hosted agent version creation in Foundry + - Direct test to Foundry (baseline) + - APIM test (production-like path) + +Step 3: Invoke through APIM +- Use agent-specific URL path routing: + +```http +POST https://apim-{suffix}.azure-api.net/hosted-agent-responses/agents/{agentName}/endpoint/protocols/openai/responses?api-version=v1 +api-key: {subscription-key} +Content-Type: application/json +``` + +Example body: + +```json +{ + "input": "Hello! What can you help me with?", + "stream": false +} +``` + +- Replace {agentName} to target a different deployed agent. +- Do not use agent_reference in the request body for hosted-agent routing. + +## Test Flow Explained + +Direct test (Section 3 in framework notebooks): +- Calls Foundry Hosted Agent Responses API directly +- Uses bearer token from Azure CLI credential with audience https://ai.azure.com/.default +- Best baseline for runtime/connectivity troubleshooting + +APIM test (Section 4 in framework notebooks): +- Routes through APIM using api-key +- APIM injects managed identity token and required headers +- Validates production-like client -> APIM -> Foundry path + +## Clean Up Resources + +Use [clean-up-resources.ipynb](clean-up-resources.ipynb) when finished. + +## Troubleshooting + +If direct test fails: +- Verify agent status is Running in Foundry +- Verify Azure CLI authentication (az login) +- Confirm PROJECT_ENDPOINT is correct +- Check networking/firewall constraints + +If APIM test fails but direct test succeeds: +- Verify APIM suffix and subscription key +- Check [hosted-agent-policy.xml](hosted-agent-policy.xml) token audience (https://ai.azure.com) +- Use APIM Trace in Azure Portal to inspect policy and backend flow + +If container startup fails: +- Verify Foundry identity has AcrPull access +- Verify pushed image URI matches agent definition +- Check Foundry diagnostics and Application Insights + +## References + +- [Microsoft Foundry Documentation](https://learn.microsoft.com/en-us/foundry/) +- [Hosted Agents Responses Protocol](https://learn.microsoft.com/en-us/azure/ai-studio/ai-services/agents/protocols/responses) +- [APIM Authentication Policies](https://learn.microsoft.com/en-us/azure/api-management/policies/authentication-policies) diff --git a/labs/ai-foundry-hosted-agents-custom-framework/ai-foundry-hosted-agents-custom-framework.ipynb b/labs/ai-foundry-hosted-agents-custom-framework/ai-foundry-hosted-agents-custom-framework.ipynb index dd153f06..6fa9a6d5 100644 --- a/labs/ai-foundry-hosted-agents-custom-framework/ai-foundry-hosted-agents-custom-framework.ipynb +++ b/labs/ai-foundry-hosted-agents-custom-framework/ai-foundry-hosted-agents-custom-framework.ipynb @@ -10,7 +10,7 @@ "This notebook deploys the shared lab infrastructure using `main.bicep`:\n", "\n", "- Azure API Management (APIM)\n", - "- Microsoft Foundry instances (One foundry instance hosting models + One found instance hosting agents)\n", + "- Microsoft Foundry resources (one for model hosting and one for hosted-agent runtime hosting)\n", "- GPT-5-Mini model deployment\n", "\n", "## Why run custom frameworks on Foundry Hosted Agents?\n", @@ -41,8 +41,8 @@ "\n", "After deployment, continue with one framework-specific setup notebook:\n", "\n", - "- `src/responses/agents/pydantic-ai/01_hosted_agent_pydantic_setup.ipynb`\n", - "- `src/responses/agents/strands/01_hosted_agent_strands_setup.ipynb`" + "- `src/responses/agents/frameworks/01_hosted_agent_strands_setup.ipynb`\n", + "- `src/responses/agents/frameworks/02_hosted_agent_pydantic_setup.ipynb`" ] }, { @@ -83,8 +83,8 @@ "outputs": [], "source": [ "# Update these values as needed\n", - "subscription_id = 'baba41cf-c01d-4a55-b6c5-ca494b802be5'\n", - "resource_group = 'rg-aigw-hosted-custom-framework-v2'\n", + "subscription_id = 'x'\n", + "resource_group = 'rg-aigw-hosted-custom-framework'\n", "location = 'swedencentral'\n", "deployment_name = 'deploy-hosted-custom-framework'\n", "\n", @@ -127,14 +127,14 @@ " }\n", "]\n", "\n", - "# Deploy Foundry infrastructure and APIM with hosted agent responses API support.\n", - "# APIM will accept requests with 'agent_reference' in the request body,\n", - "# allowing you to target any deployed agent without changing the APIM configuration.\n", + "# Deploy Foundry infrastructure and APIM with hosted-agent responses API support.\n", + "# Hosted agents are invoked by agent-specific URL path through APIM:\n", + "# /hosted-agent-responses/agents/{agentName}/endpoint/protocols/openai/responses\n", "enable_hosted_agent_responses_api = True\n", "\n", "print('Configuration ready. Set real values before running deployment.')\n", - "print('Note: APIM is configured to support any deployed agent.')\n", - "print('Clients specify the target agent via agent_reference in the request body.')" + "print('Note: APIM is configured to support hosted-agent path routing.')\n", + "print('Clients target an agent by setting {agentName} in the request URL path.')" ] }, { @@ -285,13 +285,14 @@ "\n", "1. Run this notebook to deploy all Foundry and APIM infrastructure at once\n", " - Foundry resources (models + agents)\n", - " - APIM with inference API and dynamic hosted agent responses API\n", + " - APIM with inference API and hosted-agent responses API\n", " - All role assignments\n", " \n", "**Then proceed to framework-specific setup:**\n", "\n", - "2. Use one of the framework notebooks under `src/responses/agents/` to build, push, and deploy the hosted agent:\n", - " - `src/responses/agents/strands/01_hosted_agent_strands_setup.ipynb`\n", + "2. Use one of the framework notebooks under `src/responses/agents/frameworks/` to build, push, and deploy the hosted agent:\n", + " - `src/responses/agents/frameworks/01_hosted_agent_strands_setup.ipynb`\n", + " - `src/responses/agents/frameworks/02_hosted_agent_pydantic_setup.ipynb`\n", " - The agent will be created with a name and version (e.g., `strands-agent:1`)\n", " \n", "**Agent routing via APIM:**\n", @@ -303,16 +304,16 @@ "POST https://apim-{suffix}.azure-api.net/hosted-agent-responses/agents/{agentName}/endpoint/protocols/openai/responses?api-version=v1\n", "```\n", "\n", - "- `{agentName}`: The name of your deployed Foundry agent (e.g., `strands-agent`, `pydantic-ai`, etc.)\n", + "- `{agentName}`: The name of your deployed Foundry agent (e.g., `strands-agent`, `pydantic-agent`)\n", "- Header: `api-key: {subscription-key-from-outputs}`\n", "- Header: `Content-Type: application/json`\n", "- Query parameter: `api-version=v1`\n", "\n", "**To use multiple agents:**\n", "\n", - "1. Deploy another agent to Foundry using the framework-specific setup notebook\n", - "2. Update the `{agentName}` in the APIM URL path for each agent call\n", - "3. APIM automatically routes to the correct agent based on the URL path—no reconfiguration needed" + "1. Deploy another agent to Foundry using a framework setup notebook\n", + "2. Update `{agentName}` in the APIM URL path for each call\n", + "3. APIM routes to the correct agent based on URL path without policy changes" ] } ], diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/01_hosted_agent_strands_setup.ipynb b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/01_hosted_agent_strands_setup.ipynb new file mode 100644 index 00000000..2b3ab755 --- /dev/null +++ b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/01_hosted_agent_strands_setup.ipynb @@ -0,0 +1,502 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "d8a4f2a8", + "metadata": {}, + "source": [ + "# Strands Hosted Agent Setup\n", + "\n", + "This notebook helps you build, deploy, and test a **Strands-based custom agent** on Microsoft Foundry Hosted Agents.\n", + "\n", + "### What this notebook does\n", + "\n", + "1. **Build & Push** - Builds a Docker container image for your Strands agent and pushes it to Azure Container Registry (ACR)\n", + "2. **Deploy** - Creates a hosted agent version in your Foundry project, pulling the image from ACR\n", + "3. **Test Direct** - Validates the agent works by calling Foundry's Responses API directly with your Azure credentials\n", + "4. **Test via APIM** - Routes requests through Azure API Management to test the production gateway path\n", + "\n", + "### Prerequisites\n", + "\n", + "Before running this notebook:\n", + "- Complete the **infrastructure deployment** notebook first (creates Foundry resources, APIM, ACR)\n", + "- Have the deployment outputs available:\n", + " - Foundry project endpoint\n", + " - ACR login server\n", + " - APIM suffix\n", + " - APIM subscription key\n", + "- Docker Desktop must be running\n", + "- You must be logged in to Azure CLI (`az login`)" + ] + }, + { + "cell_type": "markdown", + "id": "2ca40d16", + "metadata": {}, + "source": [ + "## 1. Build And Push The Container Image\n", + "\n", + "This builds the image locally with Docker and pushes it to ACR.\n", + "Run this after completing the prerequisites above." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "401a8dd3", + "metadata": {}, + "outputs": [], + "source": [ + "# Central configuration (edit here once, then run notebook top-to-bottom)\n", + "ACR_NAME = \"acrba3feqajmh55m\"\n", + "APIM_SUFFIX = \"ba3feqajmh55m\"\n", + "APIM_SUBSCRIPTION_KEY = \"af58eceeebbe4dac864e1f4785d1d497\"\n", + "PROJECT_ENDPOINT = f\"https://foundry-agents-{APIM_SUFFIX}.services.ai.azure.com/api/projects/default-foundry-agents\"\n", + "\n", + "AGENT_NAME = \"strands-agent\"\n", + "FRAMEWORK_DIR = \"strands\"\n", + "IMAGE_NAME = \"strands-agent\"\n", + "IMAGE_TAG = \"1.0.0\"\n", + "\n", + "AZURE_OPENAI_API_VERSION = \"2024-05-01-preview\"\n", + "AZURE_OPENAI_DEPLOYMENT = \"gpt-5-mini\"\n", + "API_VERSION = \"v1\"\n", + "DEFAULT_CONTENT_TYPE = \"application/json\"\n", + "FOUNDRY_FEATURES_HEADER = \"HostedAgents=V1Preview\"\n", + "DIRECT_TEST_INPUT = \"Hello! What can you help me with? What's the weather in Paris today?\"\n", + "\n", + "ACR_LOGIN_SERVER = f\"{ACR_NAME}.azurecr.io\"\n", + "IMAGE_URI = f\"{ACR_LOGIN_SERVER}/{IMAGE_NAME}:{IMAGE_TAG}\"\n", + "AZURE_OPENAI_ENDPOINT = f\"https://apim-{APIM_SUFFIX}.azure-api.net/inference/models\"\n", + "\n", + "def build_foundry_responses_url(project_endpoint: str, agent_name: str) -> str:\n", + " return f\"{project_endpoint}/agents/{agent_name}/endpoint/protocols/openai/responses\"\n", + "\n", + "def build_apim_responses_url(apim_suffix: str, agent_name: str) -> str:\n", + " return f\"https://apim-{apim_suffix}.azure-api.net/hosted-agent-responses/agents/{agent_name}/endpoint/protocols/openai/responses\"\n", + "\n", + "print(\"Configuration loaded.\")\n", + "print(f\"ACR_LOGIN_SERVER={ACR_LOGIN_SERVER}\")\n", + "print(f\"IMAGE_URI={IMAGE_URI}\")\n", + "print(f\"PROJECT_ENDPOINT={PROJECT_ENDPOINT}\")\n", + "print(f\"AZURE_OPENAI_ENDPOINT={AZURE_OPENAI_ENDPOINT}\")\n", + "print(f\"AGENT_NAME={AGENT_NAME}\")" + ] + }, + { + "cell_type": "markdown", + "id": "e36428d1", + "metadata": {}, + "source": [ + "### Fill in your configuration\n", + "\n", + "Replace the placeholder values above with your actual Azure resources. These should match the outputs from the infrastructure deployment notebook:\n", + "- `ACR_NAME`: Your Azure Container Registry name (e.g., `acrxhep4wovroziu`)\n", + "- `IMAGE_NAME`: Container image name for your Strands agent (usually `strands-agent`)\n", + "- `IMAGE_TAG`: Semantic version tag for your image (e.g., `1.0.0`)\n", + "\n", + "The computed values (`ACR_LOGIN_SERVER`, `IMAGE_URI`) will be used in subsequent steps." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "97767e41", + "metadata": {}, + "outputs": [], + "source": [ + "# Ensure Docker is running\n", + "!az acr login --name {ACR_NAME}" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "905639da", + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "import subprocess\n", + "\n", + "# Build and push from the framework directory configured above\n", + "original_dir = os.getcwd()\n", + "os.chdir(FRAMEWORK_DIR)\n", + "\n", + "try:\n", + " print(f\"Running: docker build -t {IMAGE_URI} .\")\n", + " subprocess.run([\"docker\", \"build\", \"-t\", IMAGE_URI, \"--platform\", \"linux/amd64\", \".\"], check=True)\n", + "\n", + " print(f\"Running: docker push {IMAGE_URI}\")\n", + " subprocess.run([\"docker\", \"push\", IMAGE_URI], check=True)\n", + "\n", + " print(\"Docker build and push completed successfully.\")\n", + "finally:\n", + " os.chdir(original_dir)" + ] + }, + { + "cell_type": "markdown", + "id": "823d4ecc", + "metadata": {}, + "source": [ + "### Build and push your container\n", + "\n", + "This builds the Strands agent Docker image and pushes it to your ACR. The `--platform linux/amd64` flag ensures the image is compatible with Foundry's Linux-based container hosting.\n", + "\n", + "After pushing, your image will be available at `{ACR_LOGIN_SERVER}/strands-agent:1.0.0` for Foundry to pull and deploy." + ] + }, + { + "cell_type": "markdown", + "id": "0235f974", + "metadata": {}, + "source": [ + "## 2. Create Hosted Agent Version\n", + "\n", + "This section creates your Strands agent as a **Foundry Hosted Agent** using the Responses protocol v1.0.0.\n", + "\n", + "### Important notes\n", + "\n", + "- **Agent name**: Choose any name you want (e.g., `strands-agent`, `my-agent`, etc.). \n", + " - Foundry auto-assigns the version suffix (`:1`, `:2`, etc.) when you create versions\n", + " - This name will be used in the APIM URL path to invoke the agent: `/agents/{agentName}/endpoint/protocols/openai/responses`\n", + "\n", + "- **Model endpoint**: Uses APIM **inference** API for model calls (`https://apim-{suffix}.azure-api.net/inference/models`), not the hosted-agent API.\n", + "\n", + "- **Dependencies**: Install `azure-ai-projects` and `azure-identity` to interact with Foundry APIs.\n", + "\n", + "After creation, your agent will transition through status changes. Once it reaches \"Running\", it's ready to accept requests in sections 3 and 4." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "64490111", + "metadata": {}, + "outputs": [], + "source": [ + "pip install azure-ai-projects==2.3.0 --force-reinstall --no-cache-dir" + ] + }, + { + "cell_type": "markdown", + "id": "83a8752a", + "metadata": {}, + "source": [ + "### Create the hosted agent in Foundry\n", + "\n", + "This cell deploys your Strands container as a **Hosted Agent** in your Foundry project. \n", + "\n", + "**Key configuration:**\n", + "- **Protocol**: Responses v1.0.0 (standard for Foundry hosted agents)\n", + "- **Resources**: 1 CPU, 2Gi memory (adjust based on your agent needs)\n", + "- **Environment variables**: \n", + " - `AZURE_OPENAI_ENDPOINT`: Points to APIM inference API for your agent to call models\n", + " - `APIM_SUBSCRIPTION_KEY`: APIM subscription key for authentication\n", + " - `AZURE_OPENAI_DEPLOYMENT`: Model name to use (e.g., `gpt-5-mini`)\n", + "\n", + "The agent will be created with a version suffix (auto-assigned by Foundry). After creation, it transitions to \"Running\" state and is ready to accept requests via the Responses API." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d4de6ece", + "metadata": {}, + "outputs": [], + "source": [ + "from azure.ai.projects import AIProjectClient\n", + "from azure.ai.projects.models import (\n", + " HostedAgentDefinition,\n", + " ProtocolVersionRecord,\n", + " AgentEndpointProtocol,\n", + " ContainerConfiguration,\n", + " )\n", + "from azure.identity import AzureCliCredential\n", + "\n", + "print(f\"PROJECT_ENDPOINT: {PROJECT_ENDPOINT}\")\n", + "print(f\"AGENT_NAME: {AGENT_NAME}\")\n", + "print(f\"IMAGE_URI: {IMAGE_URI}\")\n", + "print(f\"AZURE_OPENAI_ENDPOINT: {AZURE_OPENAI_ENDPOINT}\")\n", + "\n", + "credential = AzureCliCredential()\n", + "\n", + "project = AIProjectClient(\n", + " endpoint=PROJECT_ENDPOINT,\n", + " credential=credential,\n", + " allow_preview=True,\n", + ")\n", + "\n", + "agent = project.agents.create_version(\n", + " agent_name=AGENT_NAME,\n", + " definition=HostedAgentDefinition(\n", + " protocol_versions=[\n", + " ProtocolVersionRecord(protocol=AgentEndpointProtocol.RESPONSES, version=\"1.0.0\")\n", + " ],\n", + " cpu=\"1\",\n", + " memory=\"2Gi\",\n", + " container_configuration=ContainerConfiguration(image=IMAGE_URI),\n", + " environment_variables={\n", + " \"AZURE_OPENAI_ENDPOINT\": AZURE_OPENAI_ENDPOINT,\n", + " \"AZURE_OPENAI_API_VERSION\": AZURE_OPENAI_API_VERSION,\n", + " \"AZURE_OPENAI_DEPLOYMENT\": AZURE_OPENAI_DEPLOYMENT,\n", + " \"APIM_SUBSCRIPTION_KEY\": APIM_SUBSCRIPTION_KEY,\n", + " \"LOG_LEVEL\": \"INFO\",\n", + " \"STRANDS_LOG_LEVEL\": \"INFO\",\n", + " },\n", + " ),\n", + " )\n", + "\n", + "print(f\"Agent created: {agent.name}, version: {agent.version}, id {agent.id}\")" + ] + }, + { + "cell_type": "markdown", + "id": "2e23655c", + "metadata": {}, + "source": [ + "## 3. Test The Hosted Agent (Direct)\n", + "\n", + "**Purpose:** Validate your agent works by calling the Foundry Responses API directly using your Azure CLI credential.\n", + "\n", + "This is your baseline test—if this fails, APIM proxy tests will also fail. Use this to confirm:\n", + "- Agent reached \"Running\" status ✅\n", + "- Network connectivity to Foundry is working ✅\n", + "- Authentication with your credential works ✅\n", + "- Agent payload format is correct ✅\n", + "\n", + "**How it works:**\n", + "- Endpoint: `{PROJECT_ENDPOINT}/agents/{AGENT_NAME}/endpoint/protocols/openai/responses?api-version=v1`\n", + "- Auth: Bearer token with `https://ai.azure.com/.default` audience (from your Azure CLI login)\n", + "- Headers: Includes `Foundry-Features: HostedAgents=V1Preview` (required for preview access)\n", + "\n", + "If this test succeeds, you know the agent itself is working correctly." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "52d31749", + "metadata": {}, + "outputs": [], + "source": [ + "import json\n", + "import requests\n", + "from azure.core.credentials import AccessToken\n", + "from azure.identity import AzureCliCredential\n", + "\n", + "url = build_foundry_responses_url(PROJECT_ENDPOINT, AGENT_NAME)\n", + "\n", + "if \"credential\" not in globals():\n", + " credential = AzureCliCredential()\n", + "\n", + "# Get a token for Foundry Responses API\n", + "token: AccessToken = credential.get_token(\"https://ai.azure.com/.default\")\n", + "\n", + "headers = {\n", + " \"Authorization\": f\"Bearer {token.token}\",\n", + " \"Content-Type\": DEFAULT_CONTENT_TYPE,\n", + " \"Foundry-Features\": FOUNDRY_FEATURES_HEADER,\n", + "}\n", + "\n", + "payload = {\n", + " \"input\": DIRECT_TEST_INPUT,\n", + " \"stream\": False,\n", + "}\n", + "\n", + "print(f\"POST {url}?api-version={API_VERSION}\")\n", + "print(f\"Agent Name: {AGENT_NAME}\")\n", + "print(f\"Payload: {json.dumps(payload, indent=2)}\")\n", + "print()\n", + "\n", + "response = requests.post(url, headers=headers, json=payload, params={\"api-version\": API_VERSION})\n", + "print(f\"Status: {response.status_code}\")\n", + "print(f\"Headers: {dict(response.headers)}\")\n", + "print(f\"Response text (first 500 chars): {response.text[:500]}\")\n", + "print()\n", + "\n", + "if response.status_code == 200:\n", + " try:\n", + " result = response.json()\n", + " print(\"Response JSON:\")\n", + " print(json.dumps(result, indent=2))\n", + " if \"output_text\" in result:\n", + " print(f\"\\nAgent output:\\n{result['output_text']}\")\n", + " except json.JSONDecodeError as e:\n", + " print(f\"Failed to parse JSON: {e}\")\n", + " print(f\"Raw response: {response.text}\")\n", + "else:\n", + " print(f\"Error: {response.status_code}\")\n", + " if response.text:\n", + " try:\n", + " print(json.dumps(response.json(), indent=2))\n", + " except Exception:\n", + " print(response.text)" + ] + }, + { + "cell_type": "markdown", + "id": "3b437f83", + "metadata": {}, + "source": [ + "## 4. Test The Hosted Agent Via APIM\n", + "\n", + "**Purpose:** Route your request through Azure API Management instead of calling Foundry directly.\n", + "\n", + "This validates the production-like path:\n", + "- Client → APIM Gateway (subscription key auth) → Foundry Responses API\n", + "\n", + "**Important: Agent-Specific Routing**\n", + "\n", + "Foundry Hosted Agents **require** the agent name in the URL path. There is no generic `/responses` endpoint that accepts `agent_reference` in the request body. Each agent must have its own URL path:\n", + "\n", + "```\n", + "POST https://apim-{APIM_SUFFIX}.azure-api.net/hosted-agent-responses/agents/{AGENT_NAME}/endpoint/protocols/openai/responses\n", + "```\n", + "\n", + "**What APIM does automatically:**\n", + "- Injects managed identity bearer token for Foundry authentication (audience: `https://ai.azure.com`)\n", + "- Enforces `Content-Type: application/json` header\n", + "- Injects `Foundry-Features: HostedAgents=V1Preview` header for preview access\n", + "- Your client only needs the APIM subscription key (`api-key` header)\n", + "\n", + "**Comparison: Direct vs APIM**\n", + "- **Direct (Section 3):** `https://foundry-agents-{suffix}.services.ai.azure.com/api/projects/default-foundry-agents/agents/{AGENT_NAME}/endpoint/protocols/openai/responses` + Bearer token\n", + "- **APIM (Section 4):** `https://apim-{suffix}.azure-api.net/hosted-agent-responses/agents/{AGENT_NAME}/endpoint/protocols/openai/responses` + API key\n", + "\n", + "**Configuration details** are in [hosted-agent-policy.xml](../../hosted-agent-policy.xml)—update there if you need to change defaults.\n", + "\n", + "Compare this test result with Section 3 to ensure both paths (direct and APIM-proxied) produce consistent responses." + ] + }, + { + "cell_type": "markdown", + "id": "94663b69", + "metadata": {}, + "source": [ + "### Get deployment outputs\n", + "\n", + "Before testing via APIM, retrieve the outputs from your infrastructure deployment notebook and update the **top configuration cell** (Cell 3):\n", + "\n", + "- `APIM_SUFFIX`: The unique suffix for your APIM instance (e.g., `xhep4wovroziu`)\n", + "- `APIM_SUBSCRIPTION_KEY`: The starter subscription key from APIM outputs\n", + "- `PROJECT_ENDPOINT`: The Foundry agents project endpoint (or let it be computed from `APIM_SUFFIX`)\n", + "\n", + "Keeping these values in one place makes reruns and troubleshooting much easier." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d9e3232c", + "metadata": {}, + "outputs": [], + "source": [ + "print(\"Using APIM/Foundry values from the top configuration cell:\")\n", + "print(f\"APIM_SUFFIX: {APIM_SUFFIX}\")\n", + "print(f\"APIM_SUBSCRIPTION_KEY: {APIM_SUBSCRIPTION_KEY[:20]}...\" if len(APIM_SUBSCRIPTION_KEY) > 20 else f\"APIM_SUBSCRIPTION_KEY: {APIM_SUBSCRIPTION_KEY}\")\n", + "print(f\"PROJECT_ENDPOINT: {PROJECT_ENDPOINT}\")\n", + "print()\n", + "print(\"If these are placeholders, update Cell 3 before running APIM tests.\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "447dbe86", + "metadata": {}, + "outputs": [], + "source": [ + "import json\n", + "import requests\n", + "\n", + "url = build_apim_responses_url(APIM_SUFFIX, AGENT_NAME)\n", + "\n", + "headers = {\n", + " \"api-key\": APIM_SUBSCRIPTION_KEY,\n", + " \"Content-Type\": DEFAULT_CONTENT_TYPE,\n", + " \"Foundry-Features\": FOUNDRY_FEATURES_HEADER,\n", + "}\n", + "\n", + "payload = {\n", + " \"input\": DIRECT_TEST_INPUT,\n", + " \"stream\": False,\n", + "}\n", + "\n", + "print(f\"POST {url}?api-version={API_VERSION}\")\n", + "print(f\"APIM Suffix: {APIM_SUFFIX}\")\n", + "print(f\"Agent Name (in URL path): {AGENT_NAME}\")\n", + "print(f\"Content-Type: {DEFAULT_CONTENT_TYPE}\")\n", + "print(f\"Headers: api-key={APIM_SUBSCRIPTION_KEY[:20]}..., Content-Type, Foundry-Features\")\n", + "print(f\"Payload: {json.dumps(payload, indent=2)}\")\n", + "print()\n", + "\n", + "response = requests.post(url, headers=headers, json=payload, params={\"api-version\": API_VERSION})\n", + "print(f\"Status: {response.status_code}\")\n", + "print()\n", + "\n", + "# Extract response from payload\n", + "apim_response = None\n", + "agent_text = None\n", + "\n", + "if response.status_code == 200:\n", + " try:\n", + " result = response.json()\n", + " apim_response = result\n", + "\n", + " # Extract agent text from nested structure\n", + " if \"output\" in result and len(result[\"output\"]) > 0:\n", + " message = result[\"output\"][0]\n", + " if \"content\" in message and len(message[\"content\"]) > 0:\n", + " agent_text = message[\"content\"][0].get(\"text\", \"\")\n", + "\n", + " print(\"=\" * 80)\n", + " print(\"AGENT RESPONSE (via APIM):\")\n", + " print(\"=\" * 80)\n", + " if agent_text:\n", + " print(agent_text)\n", + " else:\n", + " print(\"Full response:\")\n", + " print(json.dumps(result, indent=2))\n", + " print(\"=\" * 80)\n", + "\n", + " except json.JSONDecodeError as e:\n", + " print(f\"Failed to parse JSON: {e}\")\n", + " print(f\"Raw response: {response.text}\")\n", + "else:\n", + " print(f\"Error: {response.status_code}\")\n", + " if response.text:\n", + " try:\n", + " apim_response = response.json()\n", + " print(json.dumps(apim_response, indent=2))\n", + " except Exception:\n", + " print(response.text)\n", + "\n", + "print(\"\\nExtracted response stored in 'apim_response' variable\")\n", + "print(\"Agent text stored in 'agent_text' variable\")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.10" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/02_hosted_agent_pydantic_setup.ipynb b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/02_hosted_agent_pydantic_setup.ipynb new file mode 100644 index 00000000..63530d31 --- /dev/null +++ b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/02_hosted_agent_pydantic_setup.ipynb @@ -0,0 +1,902 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "7db1b3cb", + "metadata": {}, + "source": [ + "# Pydantic AI Hosted Agent Setup\n", + "\n", + "This notebook helps you build, deploy, and test a **Pydantic AI-based custom agent** on Microsoft Foundry Hosted Agents.\n", + "\n", + "### What this notebook does\n", + "\n", + "1. **Build & Push** - Builds a Docker container image for your Pydantic AI agent and pushes it to Azure Container Registry (ACR)\n", + "2. **Deploy** - Creates a hosted agent version in your Foundry project, pulling the image from ACR\n", + "3. **Test Direct** - Validates the agent works by calling Foundry's Responses API directly with your Azure credentials\n", + "4. **Test via APIM** - Routes requests through Azure API Management to test the production gateway path\n", + "\n", + "### Prerequisites\n", + "\n", + "Before running this notebook:\n", + "- Complete the **infrastructure deployment** notebook first (creates Foundry resources, APIM, ACR)\n", + "- Have the deployment outputs available:\n", + " - Foundry project endpoint\n", + " - ACR login server\n", + " - APIM suffix\n", + " - APIM subscription key\n", + "- Docker Desktop must be running\n", + "- You must be logged in to Azure CLI (`az login`)" + ] + }, + { + "cell_type": "markdown", + "id": "75c76518", + "metadata": {}, + "source": [ + "## 1. Build And Push The Container Image\n", + "\n", + "This builds the image locally with Docker and pushes it to ACR.\n", + "Run this after completing the prerequisites above." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b9ba6016", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "ACR_NAME=acrba3feqajmh55m\n", + "ACR_LOGIN_SERVER=acrba3feqajmh55m.azurecr.io\n", + "IMAGE_NAME=pydantic-agent\n", + "IMAGE_TAG=1.0.0\n", + "IMAGE_URI=acrba3feqajmh55m.azurecr.io/pydantic-agent:1.0.0\n" + ] + } + ], + "source": [ + "# Central configuration (edit here once, then run notebook top-to-bottom)\n", + "ACR_NAME = \"acrba3feqajmh55m\"\n", + "APIM_SUFFIX = \"ba3feqajmh55m\"\n", + "APIM_SUBSCRIPTION_KEY = \"af58eceeebbe4dac864e1f4785d1d497\"\n", + "PROJECT_ENDPOINT = f\"https://foundry-agents-{APIM_SUFFIX}.services.ai.azure.com/api/projects/default-foundry-agents\"\n", + "\n", + "AGENT_NAME = \"pydantic-agent\"\n", + "FRAMEWORK_DIR = \"pydantic\"\n", + "IMAGE_NAME = \"pydantic-agent\"\n", + "IMAGE_TAG = \"1.0.0\"\n", + "\n", + "AZURE_OPENAI_API_VERSION = \"2024-05-01-preview\"\n", + "AZURE_OPENAI_DEPLOYMENT = \"gpt-5-mini\"\n", + "API_VERSION = \"v1\"\n", + "DEFAULT_CONTENT_TYPE = \"application/json\"\n", + "FOUNDRY_FEATURES_HEADER = \"HostedAgents=V1Preview\"\n", + "DIRECT_TEST_INPUT = \"Hello! What can you help me with?\"\n", + "\n", + "ACR_LOGIN_SERVER = f\"{ACR_NAME}.azurecr.io\"\n", + "IMAGE_URI = f\"{ACR_LOGIN_SERVER}/{IMAGE_NAME}:{IMAGE_TAG}\"\n", + "AZURE_OPENAI_ENDPOINT = f\"https://apim-{APIM_SUFFIX}.azure-api.net/inference/models\"\n", + "\n", + "def build_foundry_responses_url(project_endpoint: str, agent_name: str) -> str:\n", + " return f\"{project_endpoint}/agents/{agent_name}/endpoint/protocols/openai/responses\"\n", + "\n", + "def build_apim_responses_url(apim_suffix: str, agent_name: str) -> str:\n", + " return f\"https://apim-{apim_suffix}.azure-api.net/hosted-agent-responses/agents/{agent_name}/endpoint/protocols/openai/responses\"\n", + "\n", + "print(\"Configuration loaded.\")\n", + "print(f\"ACR_LOGIN_SERVER={ACR_LOGIN_SERVER}\")\n", + "print(f\"IMAGE_URI={IMAGE_URI}\")\n", + "print(f\"PROJECT_ENDPOINT={PROJECT_ENDPOINT}\")\n", + "print(f\"AZURE_OPENAI_ENDPOINT={AZURE_OPENAI_ENDPOINT}\")\n", + "print(f\"AGENT_NAME={AGENT_NAME}\")" + ] + }, + { + "cell_type": "markdown", + "id": "a144ea9b", + "metadata": {}, + "source": [ + "### Fill in your configuration\n", + "\n", + "Replace the placeholder values above with your actual Azure resources. These should match the outputs from the infrastructure deployment notebook:\n", + "- `ACR_NAME`: Your Azure Container Registry name (e.g., `acrxhep4wovroziu`)\n", + "- `IMAGE_NAME`: Container image name for your Pydantic agent (usually `pydantic-agent`)\n", + "- `IMAGE_TAG`: Semantic version tag for your image (e.g., `1.0.0`)\n", + "\n", + "The computed values (`ACR_LOGIN_SERVER`, `IMAGE_URI`) will be used in subsequent steps." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "ace1aa5f", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Login Succeeded\n" + ] + } + ], + "source": [ + "# Ensure Docker is running\n", + "!az acr login --name {ACR_NAME}" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a49cb256", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running: docker build -t acrba3feqajmh55m.azurecr.io/pydantic-agent:1.0.0 .\n", + "Running: docker push acrba3feqajmh55m.azurecr.io/pydantic-agent:1.0.0\n", + "Docker build and push completed successfully.\n" + ] + } + ], + "source": [ + "import os\n", + "import subprocess\n", + "\n", + "# Build and push from the framework directory configured above\n", + "original_dir = os.getcwd()\n", + "os.chdir(FRAMEWORK_DIR)\n", + "\n", + "try:\n", + " print(f\"Running: docker build -t {IMAGE_URI} .\")\n", + " subprocess.run([\"docker\", \"build\", \"-t\", IMAGE_URI, \"--platform\", \"linux/amd64\", \".\"], check=True)\n", + "\n", + " print(f\"Running: docker push {IMAGE_URI}\")\n", + " subprocess.run([\"docker\", \"push\", IMAGE_URI], check=True)\n", + "\n", + " print(\"Docker build and push completed successfully.\")\n", + "finally:\n", + " os.chdir(original_dir)" + ] + }, + { + "cell_type": "markdown", + "id": "1f4a77ab", + "metadata": {}, + "source": [ + "### Build and push your container\n", + "\n", + "This builds the Pydantic AI agent Docker image and pushes it to your ACR. The `--platform linux/amd64` flag ensures the image is compatible with Foundry's Linux-based container hosting.\n", + "\n", + "After pushing, your image will be available at `{ACR_LOGIN_SERVER}/pydantic-agent:1.0.0` for Foundry to pull and deploy." + ] + }, + { + "cell_type": "markdown", + "id": "ce9910fc", + "metadata": {}, + "source": [ + "## 2. Create Hosted Agent Version\n", + "\n", + "This section creates your Pydantic AI agent as a **Foundry Hosted Agent** using the Responses protocol v1.0.0.\n", + "\n", + "### Important notes\n", + "\n", + "- **Agent name**: Choose any name you want (e.g., `pydantic-agent`, `my-agent`, etc.). \n", + " - Foundry auto-assigns the version suffix (`:1`, `:2`, etc.) when you create versions\n", + " - This name will be used in the APIM URL path to invoke the agent: `/agents/{agentName}/endpoint/protocols/openai/responses`\n", + "\n", + "- **Model endpoint**: Uses APIM **inference** API for model calls (`https://apim-{suffix}.azure-api.net/inference/models`), not the hosted-agent API.\n", + "\n", + "- **Dependencies**: Install `azure-ai-projects` and `azure-identity` to interact with Foundry APIs.\n", + "\n", + "After creation, your agent will transition through status changes. Once it reaches \"Running\", it's ready to accept requests in sections 3 and 4." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "a471f202", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Collecting azure-ai-projects==2.3.0\n", + " Downloading azure_ai_projects-2.3.0-py3-none-any.whl.metadata (64 kB)\n", + "Collecting isodate>=0.6.1 (from azure-ai-projects==2.3.0)\n", + " Downloading isodate-0.7.2-py3-none-any.whl.metadata (11 kB)\n", + "Collecting azure-core>=1.37.0 (from azure-ai-projects==2.3.0)\n", + " Downloading azure_core-1.41.0-py3-none-any.whl.metadata (49 kB)\n", + "Collecting typing-extensions>=4.11 (from azure-ai-projects==2.3.0)\n", + " Downloading typing_extensions-4.16.0-py3-none-any.whl.metadata (3.3 kB)\n", + "Collecting azure-identity>=1.15.0 (from azure-ai-projects==2.3.0)\n", + " Downloading azure_identity-1.25.3-py3-none-any.whl.metadata (91 kB)\n", + "Collecting openai>=2.8.0 (from azure-ai-projects==2.3.0)\n", + " Downloading openai-2.44.0-py3-none-any.whl.metadata (34 kB)\n", + "Collecting azure-storage-blob>=12.15.0 (from azure-ai-projects==2.3.0)\n", + " Downloading azure_storage_blob-12.30.0-py3-none-any.whl.metadata (26 kB)\n", + "Collecting requests>=2.21.0 (from azure-core>=1.37.0->azure-ai-projects==2.3.0)\n", + " Downloading requests-2.34.2-py3-none-any.whl.metadata (4.8 kB)\n", + "Collecting cryptography>=2.5 (from azure-identity>=1.15.0->azure-ai-projects==2.3.0)\n", + " Downloading cryptography-49.0.0-cp311-abi3-win_amd64.whl.metadata (4.3 kB)\n", + "Collecting msal>=1.35.1 (from azure-identity>=1.15.0->azure-ai-projects==2.3.0)\n", + " Downloading msal-1.37.0-py3-none-any.whl.metadata (11 kB)\n", + "Collecting msal-extensions>=1.2.0 (from azure-identity>=1.15.0->azure-ai-projects==2.3.0)\n", + " Downloading msal_extensions-1.3.1-py3-none-any.whl.metadata (7.8 kB)\n", + "Collecting anyio<5,>=3.5.0 (from openai>=2.8.0->azure-ai-projects==2.3.0)\n", + " Downloading anyio-4.14.1-py3-none-any.whl.metadata (4.6 kB)\n", + "Collecting distro<2,>=1.7.0 (from openai>=2.8.0->azure-ai-projects==2.3.0)\n", + " Downloading distro-1.9.0-py3-none-any.whl.metadata (6.8 kB)\n", + "Collecting httpx<1,>=0.23.0 (from openai>=2.8.0->azure-ai-projects==2.3.0)\n", + " Downloading httpx-0.28.1-py3-none-any.whl.metadata (7.1 kB)\n", + "Collecting jiter<1,>=0.10.0 (from openai>=2.8.0->azure-ai-projects==2.3.0)\n", + " Downloading jiter-0.16.0-cp312-cp312-win_amd64.whl.metadata (5.3 kB)\n", + "Collecting pydantic<3,>=1.9.0 (from openai>=2.8.0->azure-ai-projects==2.3.0)\n", + " Downloading pydantic-2.13.4-py3-none-any.whl.metadata (109 kB)\n", + "Collecting sniffio (from openai>=2.8.0->azure-ai-projects==2.3.0)\n", + " Downloading sniffio-1.3.1-py3-none-any.whl.metadata (3.9 kB)\n", + "Collecting tqdm>4 (from openai>=2.8.0->azure-ai-projects==2.3.0)\n", + " Downloading tqdm-4.68.4-py3-none-any.whl.metadata (57 kB)\n", + "Collecting idna>=2.8 (from anyio<5,>=3.5.0->openai>=2.8.0->azure-ai-projects==2.3.0)\n", + " Downloading idna-3.18-py3-none-any.whl.metadata (6.1 kB)\n", + "Collecting cffi>=2.0.0 (from cryptography>=2.5->azure-identity>=1.15.0->azure-ai-projects==2.3.0)\n", + " Downloading cffi-2.1.0-cp312-cp312-win_amd64.whl.metadata (2.6 kB)\n", + "Collecting certifi (from httpx<1,>=0.23.0->openai>=2.8.0->azure-ai-projects==2.3.0)\n", + " Downloading certifi-2026.6.17-py3-none-any.whl.metadata (2.5 kB)\n", + "Collecting httpcore==1.* (from httpx<1,>=0.23.0->openai>=2.8.0->azure-ai-projects==2.3.0)\n", + " Downloading httpcore-1.0.9-py3-none-any.whl.metadata (21 kB)\n", + "Collecting h11>=0.16 (from httpcore==1.*->httpx<1,>=0.23.0->openai>=2.8.0->azure-ai-projects==2.3.0)\n", + " Downloading h11-0.16.0-py3-none-any.whl.metadata (8.3 kB)\n", + "Collecting PyJWT<3,>=1.0.0 (from PyJWT[crypto]<3,>=1.0.0->msal>=1.35.1->azure-identity>=1.15.0->azure-ai-projects==2.3.0)\n", + " Downloading pyjwt-2.13.0-py3-none-any.whl.metadata (3.4 kB)\n", + "Collecting annotated-types>=0.6.0 (from pydantic<3,>=1.9.0->openai>=2.8.0->azure-ai-projects==2.3.0)\n", + " Downloading annotated_types-0.7.0-py3-none-any.whl.metadata (15 kB)\n", + "Collecting pydantic-core==2.46.4 (from pydantic<3,>=1.9.0->openai>=2.8.0->azure-ai-projects==2.3.0)\n", + " Downloading pydantic_core-2.46.4-cp312-cp312-win_amd64.whl.metadata (6.7 kB)\n", + "Collecting typing-inspection>=0.4.2 (from pydantic<3,>=1.9.0->openai>=2.8.0->azure-ai-projects==2.3.0)\n", + " Downloading typing_inspection-0.4.2-py3-none-any.whl.metadata (2.6 kB)\n", + "Collecting charset_normalizer<4,>=2 (from requests>=2.21.0->azure-core>=1.37.0->azure-ai-projects==2.3.0)\n", + " Downloading charset_normalizer-3.4.9-cp312-cp312-win_amd64.whl.metadata (42 kB)\n", + "Collecting urllib3<3,>=1.26 (from requests>=2.21.0->azure-core>=1.37.0->azure-ai-projects==2.3.0)\n", + " Downloading urllib3-2.7.0-py3-none-any.whl.metadata (6.9 kB)\n", + "Collecting colorama (from tqdm>4->openai>=2.8.0->azure-ai-projects==2.3.0)\n", + " Downloading colorama-0.4.6-py2.py3-none-any.whl.metadata (17 kB)\n", + "Collecting pycparser (from cffi>=2.0.0->cryptography>=2.5->azure-identity>=1.15.0->azure-ai-projects==2.3.0)\n", + " Downloading pycparser-3.0-py3-none-any.whl.metadata (8.2 kB)\n", + "Downloading azure_ai_projects-2.3.0-py3-none-any.whl (349 kB)\n", + "Downloading azure_core-1.41.0-py3-none-any.whl (220 kB)\n", + "Downloading azure_identity-1.25.3-py3-none-any.whl (192 kB)\n", + "Downloading azure_storage_blob-12.30.0-py3-none-any.whl (435 kB)\n", + "Downloading isodate-0.7.2-py3-none-any.whl (22 kB)\n", + "Downloading openai-2.44.0-py3-none-any.whl (1.4 MB)\n", + " ---------------------------------------- 0.0/1.4 MB ? eta -:--:--\n", + " ---------------------------------------- 1.4/1.4 MB 35.6 MB/s eta 0:00:00\n", + "Downloading typing_extensions-4.16.0-py3-none-any.whl (45 kB)\n", + "Downloading anyio-4.14.1-py3-none-any.whl (124 kB)\n", + "Downloading cryptography-49.0.0-cp311-abi3-win_amd64.whl (3.8 MB)\n", + " ---------------------------------------- 0.0/3.8 MB ? eta -:--:--\n", + " ---------------------------------------- 3.8/3.8 MB 75.5 MB/s eta 0:00:00\n", + "Downloading distro-1.9.0-py3-none-any.whl (20 kB)\n", + "Downloading httpx-0.28.1-py3-none-any.whl (73 kB)\n", + "Downloading httpcore-1.0.9-py3-none-any.whl (78 kB)\n", + "Downloading jiter-0.16.0-cp312-cp312-win_amd64.whl (196 kB)\n", + "Downloading msal-1.37.0-py3-none-any.whl (123 kB)\n", + "Downloading msal_extensions-1.3.1-py3-none-any.whl (20 kB)\n", + "Downloading pydantic-2.13.4-py3-none-any.whl (472 kB)\n", + "Downloading pydantic_core-2.46.4-cp312-cp312-win_amd64.whl (2.1 MB)\n", + " ---------------------------------------- 0.0/2.1 MB ? eta -:--:--\n", + " ---------------------------------------- 2.1/2.1 MB 113.2 MB/s eta 0:00:00\n", + "Downloading requests-2.34.2-py3-none-any.whl (73 kB)\n", + "Downloading tqdm-4.68.4-py3-none-any.whl (676 kB)\n", + " ---------------------------------------- 0.0/676.6 kB ? eta -:--:--\n", + " ---------------------------------------- 676.6/676.6 kB ? eta 0:00:00\n", + "Downloading sniffio-1.3.1-py3-none-any.whl (10 kB)\n", + "Downloading annotated_types-0.7.0-py3-none-any.whl (13 kB)\n", + "Downloading certifi-2026.6.17-py3-none-any.whl (133 kB)\n", + "Downloading cffi-2.1.0-cp312-cp312-win_amd64.whl (185 kB)\n", + "Downloading charset_normalizer-3.4.9-cp312-cp312-win_amd64.whl (162 kB)\n", + "Downloading idna-3.18-py3-none-any.whl (65 kB)\n", + "Downloading pyjwt-2.13.0-py3-none-any.whl (31 kB)\n", + "Downloading typing_inspection-0.4.2-py3-none-any.whl (14 kB)\n", + "Downloading urllib3-2.7.0-py3-none-any.whl (131 kB)\n", + "Downloading colorama-0.4.6-py2.py3-none-any.whl (25 kB)\n", + "Downloading h11-0.16.0-py3-none-any.whl (37 kB)\n", + "Downloading pycparser-3.0-py3-none-any.whl (48 kB)\n", + "Installing collected packages: urllib3, typing-extensions, sniffio, PyJWT, pycparser, jiter, isodate, idna, h11, distro, colorama, charset_normalizer, certifi, annotated-types, typing-inspection, tqdm, requests, pydantic-core, httpcore, cffi, anyio, pydantic, httpx, cryptography, azure-core, openai, azure-storage-blob, msal, msal-extensions, azure-identity, azure-ai-projects\n", + " Attempting uninstall: urllib3\n", + " Found existing installation: urllib3 2.7.0\n", + " Uninstalling urllib3-2.7.0:\n", + " Successfully uninstalled urllib3-2.7.0\n", + " Attempting uninstall: typing-extensions\n", + " Found existing installation: typing_extensions 4.16.0\n", + " Uninstalling typing_extensions-4.16.0:\n", + " Successfully uninstalled typing_extensions-4.16.0\n", + " Attempting uninstall: sniffio\n", + " Found existing installation: sniffio 1.3.1\n", + " Uninstalling sniffio-1.3.1:\n", + " Successfully uninstalled sniffio-1.3.1\n", + " Attempting uninstall: PyJWT\n", + " Found existing installation: PyJWT 2.13.0\n", + " Uninstalling PyJWT-2.13.0:\n", + " Successfully uninstalled PyJWT-2.13.0\n", + " Attempting uninstall: pycparser\n", + " Found existing installation: pycparser 3.0\n", + " Uninstalling pycparser-3.0:\n", + " Successfully uninstalled pycparser-3.0\n", + " Attempting uninstall: jiter\n", + " Found existing installation: jiter 0.16.0\n", + " Uninstalling jiter-0.16.0:\n", + " Successfully uninstalled jiter-0.16.0\n", + " Attempting uninstall: isodate\n", + " Found existing installation: isodate 0.7.2\n", + " Uninstalling isodate-0.7.2:\n", + " Successfully uninstalled isodate-0.7.2\n", + " Attempting uninstall: idna\n", + " Found existing installation: idna 3.18\n", + " Uninstalling idna-3.18:\n", + " Successfully uninstalled idna-3.18\n", + " Attempting uninstall: h11\n", + " Found existing installation: h11 0.16.0\n", + " Uninstalling h11-0.16.0:\n", + " Successfully uninstalled h11-0.16.0\n", + " Attempting uninstall: distro\n", + " Found existing installation: distro 1.9.0\n", + " Uninstalling distro-1.9.0:\n", + " Successfully uninstalled distro-1.9.0\n", + " Attempting uninstall: colorama\n", + " Found existing installation: colorama 0.4.6\n", + " Uninstalling colorama-0.4.6:\n", + " Successfully uninstalled colorama-0.4.6\n", + " Attempting uninstall: certifi\n", + " Found existing installation: certifi 2026.6.17\n", + " Uninstalling certifi-2026.6.17:\n", + " Successfully uninstalled certifi-2026.6.17\n", + " Attempting uninstall: annotated-types\n", + " Found existing installation: annotated-types 0.7.0\n", + " Uninstalling annotated-types-0.7.0:\n", + " Successfully uninstalled annotated-types-0.7.0\n", + " Attempting uninstall: typing-inspection\n", + " Found existing installation: typing-inspection 0.4.2\n", + " Uninstalling typing-inspection-0.4.2:\n", + " Successfully uninstalled typing-inspection-0.4.2\n", + " Attempting uninstall: tqdm\n", + " Found existing installation: tqdm 4.68.4\n", + " Uninstalling tqdm-4.68.4:\n", + " Successfully uninstalled tqdm-4.68.4\n", + " Attempting uninstall: requests\n", + " Found existing installation: requests 2.34.2\n", + " Uninstalling requests-2.34.2:\n", + " Successfully uninstalled requests-2.34.2\n", + " Attempting uninstall: pydantic-core\n", + " Found existing installation: pydantic_core 2.46.4\n", + " Uninstalling pydantic_core-2.46.4:\n", + " Successfully uninstalled pydantic_core-2.46.4\n", + " Attempting uninstall: httpcore\n", + " Found existing installation: httpcore 1.0.9\n", + " Uninstalling httpcore-1.0.9:\n", + " Successfully uninstalled httpcore-1.0.9\n", + " Attempting uninstall: cffi\n", + " Found existing installation: cffi 2.1.0\n", + " Uninstalling cffi-2.1.0:\n", + " Successfully uninstalled cffi-2.1.0\n", + " Attempting uninstall: anyio\n", + " Found existing installation: anyio 4.14.1\n", + " Uninstalling anyio-4.14.1:\n", + " Successfully uninstalled anyio-4.14.1\n", + " Attempting uninstall: pydantic\n", + " Found existing installation: pydantic 2.13.4\n", + " Uninstalling pydantic-2.13.4:\n", + " Successfully uninstalled pydantic-2.13.4\n", + " Attempting uninstall: httpx\n", + " Found existing installation: httpx 0.28.1\n", + " Uninstalling httpx-0.28.1:\n", + " Successfully uninstalled httpx-0.28.1\n", + " Attempting uninstall: cryptography\n", + " Found existing installation: cryptography 49.0.0\n", + " Uninstalling cryptography-49.0.0:\n", + " Successfully uninstalled cryptography-49.0.0\n", + " Attempting uninstall: azure-core\n", + " Found existing installation: azure-core 1.41.0\n", + " Uninstalling azure-core-1.41.0:\n", + " Successfully uninstalled azure-core-1.41.0\n", + " Attempting uninstall: openai\n", + " Found existing installation: openai 2.44.0\n", + " Uninstalling openai-2.44.0:\n", + " Successfully uninstalled openai-2.44.0\n", + " Attempting uninstall: azure-storage-blob\n", + " Found existing installation: azure-storage-blob 12.30.0\n", + " Uninstalling azure-storage-blob-12.30.0:\n", + " Successfully uninstalled azure-storage-blob-12.30.0\n", + " Attempting uninstall: msal\n", + " Found existing installation: msal 1.37.0\n", + " Uninstalling msal-1.37.0:\n", + " Successfully uninstalled msal-1.37.0\n", + " Attempting uninstall: msal-extensions\n", + " Found existing installation: msal-extensions 1.3.1\n", + " Uninstalling msal-extensions-1.3.1:\n", + " Successfully uninstalled msal-extensions-1.3.1\n", + " Attempting uninstall: azure-identity\n", + " Found existing installation: azure-identity 1.25.3\n", + " Uninstalling azure-identity-1.25.3:\n", + " Successfully uninstalled azure-identity-1.25.3\n", + " Attempting uninstall: azure-ai-projects\n", + " Found existing installation: azure-ai-projects 2.3.0\n", + " Uninstalling azure-ai-projects-2.3.0:\n", + " Successfully uninstalled azure-ai-projects-2.3.0\n", + "Successfully installed PyJWT-2.13.0 annotated-types-0.7.0 anyio-4.14.1 azure-ai-projects-2.3.0 azure-core-1.41.0 azure-identity-1.25.3 azure-storage-blob-12.30.0 certifi-2026.6.17 cffi-2.1.0 charset_normalizer-3.4.9 colorama-0.4.6 cryptography-49.0.0 distro-1.9.0 h11-0.16.0 httpcore-1.0.9 httpx-0.28.1 idna-3.18 isodate-0.7.2 jiter-0.16.0 msal-1.37.0 msal-extensions-1.3.1 openai-2.44.0 pycparser-3.0 pydantic-2.13.4 pydantic-core-2.46.4 requests-2.34.2 sniffio-1.3.1 tqdm-4.68.4 typing-extensions-4.16.0 typing-inspection-0.4.2 urllib3-2.7.0\n", + "Note: you may need to restart the kernel to use updated packages.\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "WARNING: Ignoring invalid distribution ~harset-normalizer (c:\\Users\\ollisgeorge\\AppData\\Local\\Programs\\Python\\Python312-x64\\Lib\\site-packages)\n", + "WARNING: Ignoring invalid distribution ~harset-normalizer (c:\\Users\\ollisgeorge\\AppData\\Local\\Programs\\Python\\Python312-x64\\Lib\\site-packages)\n", + "WARNING: Ignoring invalid distribution ~harset-normalizer (c:\\Users\\ollisgeorge\\AppData\\Local\\Programs\\Python\\Python312-x64\\Lib\\site-packages)\n", + " WARNING: The script idna.exe is installed in 'c:\\Users\\ollisgeorge\\AppData\\Local\\Programs\\Python\\Python312-x64\\Scripts' which is not on PATH.\n", + " Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.\n", + " WARNING: The script distro.exe is installed in 'c:\\Users\\ollisgeorge\\AppData\\Local\\Programs\\Python\\Python312-x64\\Scripts' which is not on PATH.\n", + " Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.\n", + " WARNING: The script normalizer.exe is installed in 'c:\\Users\\ollisgeorge\\AppData\\Local\\Programs\\Python\\Python312-x64\\Scripts' which is not on PATH.\n", + " Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.\n", + " WARNING: The script tqdm.exe is installed in 'c:\\Users\\ollisgeorge\\AppData\\Local\\Programs\\Python\\Python312-x64\\Scripts' which is not on PATH.\n", + " Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.\n", + " WARNING: The script cffi-gen-src.exe is installed in 'c:\\Users\\ollisgeorge\\AppData\\Local\\Programs\\Python\\Python312-x64\\Scripts' which is not on PATH.\n", + " Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.\n", + " WARNING: The script httpx.exe is installed in 'c:\\Users\\ollisgeorge\\AppData\\Local\\Programs\\Python\\Python312-x64\\Scripts' which is not on PATH.\n", + " Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.\n", + "WARNING: Ignoring invalid distribution ~harset-normalizer (c:\\Users\\ollisgeorge\\AppData\\Local\\Programs\\Python\\Python312-x64\\Lib\\site-packages)\n", + "\n", + "[notice] A new release of pip is available: 25.0.1 -> 26.1.2\n", + "[notice] To update, run: python.exe -m pip install --upgrade pip\n" + ] + } + ], + "source": [ + "pip install azure-ai-projects==2.3.0 " + ] + }, + { + "cell_type": "markdown", + "id": "25e4cc10", + "metadata": {}, + "source": [ + "### Create the hosted agent in Foundry\n", + "\n", + "This cell deploys your Pydantic AI container as a **Hosted Agent** in your Foundry project. \n", + "\n", + "**Key configuration:**\n", + "- **Protocol**: Responses v1.0.0 (standard for Foundry hosted agents)\n", + "- **Resources**: 1 CPU, 2Gi memory (adjust based on your agent needs)\n", + "- **Environment variables**: \n", + " - `AZURE_OPENAI_ENDPOINT`: Points to APIM inference API for your agent to call models\n", + " - `APIM_SUBSCRIPTION_KEY`: APIM subscription key for authentication\n", + " - `AZURE_OPENAI_DEPLOYMENT`: Model name to use (e.g., `gpt-5-mini`)\n", + "\n", + "The agent will be created with a version suffix (auto-assigned by Foundry). After creation, it transitions to \"Running\" state and is ready to accept requests via the Responses API." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e6e2ec6a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "PROJECT_ENDPOINT: https://foundry-agents-ba3feqajmh55m.services.ai.azure.com/api/projects/default-foundry-agents\n", + "AGENT_NAME: pydantic-agent\n", + "Agent created: pydantic-agent, version: 1, id pydantic-agent:1\n" + ] + } + ], + "source": [ + "from azure.ai.projects import AIProjectClient\n", + "from azure.ai.projects.models import (\n", + " HostedAgentDefinition,\n", + " ProtocolVersionRecord,\n", + " AgentEndpointProtocol,\n", + " ContainerConfiguration,\n", + " )\n", + "from azure.identity import AzureCliCredential\n", + "\n", + "print(f\"PROJECT_ENDPOINT: {PROJECT_ENDPOINT}\")\n", + "print(f\"AGENT_NAME: {AGENT_NAME}\")\n", + "print(f\"IMAGE_URI: {IMAGE_URI}\")\n", + "print(f\"AZURE_OPENAI_ENDPOINT: {AZURE_OPENAI_ENDPOINT}\")\n", + "\n", + "credential = AzureCliCredential()\n", + "\n", + "project = AIProjectClient(\n", + " endpoint=PROJECT_ENDPOINT,\n", + " credential=credential,\n", + " allow_preview=True,\n", + ")\n", + "\n", + "agent = project.agents.create_version(\n", + " agent_name=AGENT_NAME,\n", + " definition=HostedAgentDefinition(\n", + " protocol_versions=[\n", + " ProtocolVersionRecord(protocol=AgentEndpointProtocol.RESPONSES, version=\"1.0.0\")\n", + " ],\n", + " cpu=\"1\",\n", + " memory=\"2Gi\",\n", + " container_configuration=ContainerConfiguration(image=IMAGE_URI),\n", + " environment_variables={\n", + " \"AZURE_OPENAI_ENDPOINT\": AZURE_OPENAI_ENDPOINT,\n", + " \"AZURE_OPENAI_API_VERSION\": AZURE_OPENAI_API_VERSION,\n", + " \"AZURE_OPENAI_DEPLOYMENT\": AZURE_OPENAI_DEPLOYMENT,\n", + " \"APIM_SUBSCRIPTION_KEY\": APIM_SUBSCRIPTION_KEY,\n", + " \"LOG_LEVEL\": \"INFO\",\n", + " },\n", + " ),\n", + " )\n", + "\n", + "print(f\"Agent created: {agent.name}, version: {agent.version}, id {agent.id}\")" + ] + }, + { + "cell_type": "markdown", + "id": "b56c768b", + "metadata": {}, + "source": [ + "## 3. Test The Hosted Agent (Direct)\n", + "\n", + "**Purpose:** Validate your agent works by calling the Foundry Responses API directly using your Azure CLI credential.\n", + "\n", + "This is your baseline test—if this fails, APIM proxy tests will also fail. Use this to confirm:\n", + "- Agent reached \"Running\" status ✅\n", + "- Network connectivity to Foundry is working ✅\n", + "- Authentication with your credential works ✅\n", + "- Agent payload format is correct ✅\n", + "\n", + "**How it works:**\n", + "- Endpoint: `{PROJECT_ENDPOINT}/agents/{AGENT_NAME}/endpoint/protocols/openai/responses?api-version=v1`\n", + "- Auth: Bearer token with `https://ai.azure.com/.default` audience (from your Azure CLI login)\n", + "- Headers: Includes `Foundry-Features: HostedAgents=V1Preview` (required for preview access)\n", + "\n", + "If this test succeeds, you know the agent itself is working correctly." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2c0c6c90", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "POST https://foundry-agents-ba3feqajmh55m.services.ai.azure.com/api/projects/default-foundry-agents/agents/pydantic-agent/endpoint/protocols/openai/responses?api-version=v1\n", + "Agent Name: pydantic-agent\n", + "Payload: {\n", + " \"input\": \"Hello! What can you help me with?\",\n", + " \"stream\": false\n", + "}\n", + "\n", + "Status: 200\n", + "Headers: {'Content-Length': '1740', 'Content-Type': 'application/json', 'content-encoding': 'identity', 'request-context': 'appId=', 'x-ms-response-type': 'standard', 'x-request-id': 'c1a2ff7f9abf029858efead2779d8426,c1a2ff7f9abf029858efead2779d8426', 'api-supported-versions': '1.0,2025-05-15-preview,2025-11-15-preview', 'x-agent-session-id': 'be166a9eefecee80e53ead6697630e7c3c8fd572145dc2011df6e0b96dd6246', 'x-platform-server': 'azure-ai-agentserver-core/2.0.0b7 (python/3.12) azure-ai-agentserver-responses/1.0.0b8 (python/3.12)', 'azureml-served-by-cluster': 'hyena-swedencentral-01', 'apim-request-id': '88778716-6c1a-4a40-9363-15f708c83294', 'Strict-Transport-Security': 'max-age=31536000; includeSubDomains; preload', 'x-content-type-options': 'nosniff', 'x-ms-region': 'Sweden Central', 'Access-Control-Expose-Headers': 'Operation-Location,Location,Apim-Request-Id,x-agent-session-id,x-agent-invocation-id', 'Date': 'Thu, 09 Jul 2026 16:03:49 GMT'}\n", + "Response text (first 500 chars): {\"id\":\"caresp_00723da9a08875aa00plRMH3lcvohERaHApDJDERSvoCS5t6qq\",\"object\":\"response\",\"output\":[{\"type\":\"message\",\"id\":\"msg_00723da9a08875aa00Twpb9FO4NFWSUyVWIyL91RybvyQo9WIb\",\"role\":\"assistant\",\"content\":[{\"type\":\"output_text\",\"text\":\"Hi — I can help with lots of things. Short list:\\n\\n- Explain topics and answer questions (science, history, tech, etc.)\\n- Research-style summaries and fact-checking (knowledge up to June 2024)\\n- Step-by-step how-tos and troubleshooting (software, appliances, DI\n", + "\n", + "Response JSON:\n", + "{\n", + " \"id\": \"caresp_00723da9a08875aa00plRMH3lcvohERaHApDJDERSvoCS5t6qq\",\n", + " \"object\": \"response\",\n", + " \"output\": [\n", + " {\n", + " \"type\": \"message\",\n", + " \"id\": \"msg_00723da9a08875aa00Twpb9FO4NFWSUyVWIyL91RybvyQo9WIb\",\n", + " \"role\": \"assistant\",\n", + " \"content\": [\n", + " {\n", + " \"type\": \"output_text\",\n", + " \"text\": \"Hi \\u2014 I can help with lots of things. Short list:\\n\\n- Explain topics and answer questions (science, history, tech, etc.)\\n- Research-style summaries and fact-checking (knowledge up to June 2024)\\n- Step-by-step how-tos and troubleshooting (software, appliances, DIY)\\n- Code help: write, debug, refactor, and explain code\\n- Writing and editing: emails, essays, resumes, creative writing\\n- Math, data analysis, and problem solving (showing steps)\\n- Planning and productivity: trip plans, study plans, schedules\\n- Translations and language help\\n- Recommendations: books, movies, recipes\\n- Quick factual lookups like current weather (I can fetch live weather if you give a city)\\n\\nLimitations: I can\\u2019t browse the web in real time (except certain tools I have), access your accounts or perform actions for you, or replace professional legal/medical advice.\\n\\nWhat would you like help with right now? If you want weather, tell me the city.\",\n", + " \"annotations\": [],\n", + " \"logprobs\": []\n", + " }\n", + " ],\n", + " \"status\": \"completed\",\n", + " \"response_id\": \"caresp_00723da9a08875aa00plRMH3lcvohERaHApDJDERSvoCS5t6qq\",\n", + " \"agent_reference\": {\n", + " \"type\": \"agent_reference\",\n", + " \"name\": \"pydantic-agent\",\n", + " \"version\": \"1\"\n", + " }\n", + " }\n", + " ],\n", + " \"created_at\": 1783613022,\n", + " \"agent_reference\": {\n", + " \"type\": \"agent_reference\",\n", + " \"name\": \"pydantic-agent\",\n", + " \"version\": \"1\"\n", + " },\n", + " \"status\": \"completed\",\n", + " \"completed_at\": 1783613029,\n", + " \"response_id\": \"caresp_00723da9a08875aa00plRMH3lcvohERaHApDJDERSvoCS5t6qq\",\n", + " \"model\": \"\",\n", + " \"agent_session_id\": \"be166a9eefecee80e53ead6697630e7c3c8fd572145dc2011df6e0b96dd6246\",\n", + " \"background\": false\n", + "}\n" + ] + } + ], + "source": [ + "import json\n", + "import requests\n", + "from azure.core.credentials import AccessToken\n", + "from azure.identity import AzureCliCredential\n", + "\n", + "url = build_foundry_responses_url(PROJECT_ENDPOINT, AGENT_NAME)\n", + "\n", + "if \"credential\" not in globals():\n", + " credential = AzureCliCredential()\n", + "\n", + "# Get a token for Foundry Responses API\n", + "token: AccessToken = credential.get_token(\"https://ai.azure.com/.default\")\n", + "\n", + "headers = {\n", + " \"Authorization\": f\"Bearer {token.token}\",\n", + " \"Content-Type\": DEFAULT_CONTENT_TYPE,\n", + " \"Foundry-Features\": FOUNDRY_FEATURES_HEADER,\n", + "}\n", + "\n", + "payload = {\n", + " \"input\": DIRECT_TEST_INPUT,\n", + " \"stream\": False,\n", + "}\n", + "\n", + "print(f\"POST {url}?api-version={API_VERSION}\")\n", + "print(f\"Agent Name: {AGENT_NAME}\")\n", + "print(f\"Payload: {json.dumps(payload, indent=2)}\")\n", + "print()\n", + "\n", + "response = requests.post(url, headers=headers, json=payload, params={\"api-version\": API_VERSION})\n", + "print(f\"Status: {response.status_code}\")\n", + "print(f\"Headers: {dict(response.headers)}\")\n", + "print(f\"Response text (first 500 chars): {response.text[:500]}\")\n", + "print()\n", + "\n", + "if response.status_code == 200:\n", + " try:\n", + " result = response.json()\n", + " print(\"Response JSON:\")\n", + " print(json.dumps(result, indent=2))\n", + " if \"output_text\" in result:\n", + " print(f\"\\nAgent output:\\n{result['output_text']}\")\n", + " except json.JSONDecodeError as e:\n", + " print(f\"Failed to parse JSON: {e}\")\n", + " print(f\"Raw response: {response.text}\")\n", + "else:\n", + " print(f\"Error: {response.status_code}\")\n", + " if response.text:\n", + " try:\n", + " print(json.dumps(response.json(), indent=2))\n", + " except Exception:\n", + " print(response.text)" + ] + }, + { + "cell_type": "markdown", + "id": "39e7b9ff", + "metadata": {}, + "source": [ + "## 4. Test The Hosted Agent Via APIM\n", + "\n", + "**Purpose:** Route your request through Azure API Management instead of calling Foundry directly.\n", + "\n", + "This validates the production-like path:\n", + "- Client → APIM Gateway (subscription key auth) → Foundry Responses API\n", + "\n", + "**Important: Agent-Specific Routing**\n", + "\n", + "Foundry Hosted Agents **require** the agent name in the URL path. There is no generic `/responses` endpoint that accepts `agent_reference` in the request body. Each agent must have its own URL path:\n", + "\n", + "```\n", + "POST https://apim-{APIM_SUFFIX}.azure-api.net/hosted-agent-responses/agents/{AGENT_NAME}/endpoint/protocols/openai/responses\n", + "```\n", + "\n", + "**What APIM does automatically:**\n", + "- Injects managed identity bearer token for Foundry authentication (audience: `https://ai.azure.com`)\n", + "- Enforces `Content-Type: application/json` header\n", + "- Injects `Foundry-Features: HostedAgents=V1Preview` header for preview access\n", + "- Your client only needs the APIM subscription key (`api-key` header)\n", + "\n", + "**Configuration details** are in [hosted-agent-policy.xml](../../hosted-agent-policy.xml)—update there if you need to change defaults.\n", + "\n", + "Compare this test result with Section 3 to ensure both paths (direct and APIM-proxied) produce consistent responses." + ] + }, + { + "cell_type": "markdown", + "id": "e7d2c90c", + "metadata": {}, + "source": [ + "### Get deployment outputs\n", + "\n", + "Before testing via APIM, retrieve the outputs from your infrastructure deployment notebook and update the **top configuration cell** (Cell 3):\n", + "\n", + "- `APIM_SUFFIX`: The unique suffix for your APIM instance\n", + "- `APIM_SUBSCRIPTION_KEY`: The starter subscription key from APIM outputs\n", + "- `PROJECT_ENDPOINT`: The Foundry agents project endpoint (or let it be computed from `APIM_SUFFIX`)\n", + "\n", + "Keeping these values in one place makes reruns and troubleshooting much easier." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "06ed7a7f", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "APIM_SUFFIX: ba3feqajmh55m\n", + "APIM_SUBSCRIPTION_KEY: af58eceeebbe4dac864e...\n", + "PROJECT_ENDPOINT: https://foundry-agents-ba3feqajmh55m.services.ai.azure.com/api/projects/default-foundry-agents\n", + "\n", + "⚠️ If these are still placeholders, run the infrastructure deployment notebook first!\n" + ] + } + ], + "source": [ + "print(\"Using APIM/Foundry values from the top configuration cell:\")\n", + "print(f\"APIM_SUFFIX: {APIM_SUFFIX}\")\n", + "print(f\"APIM_SUBSCRIPTION_KEY: {APIM_SUBSCRIPTION_KEY[:20]}...\" if len(APIM_SUBSCRIPTION_KEY) > 20 else f\"APIM_SUBSCRIPTION_KEY: {APIM_SUBSCRIPTION_KEY}\")\n", + "print(f\"PROJECT_ENDPOINT: {PROJECT_ENDPOINT}\")\n", + "print()\n", + "print(\"If these are placeholders, update Cell 3 before running APIM tests.\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b474be31", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "POST https://apim-ba3feqajmh55m.azure-api.net/hosted-agent-responses/agents/pydantic-agent/endpoint/protocols/openai/responses?api-version=v1\n", + "APIM Suffix: ba3feqajmh55m\n", + "Agent Name (in URL path): pydantic-agent\n", + "Content-Type: application/json\n", + "Headers: api-key=af58eceeebbe4dac864e..., Content-Type, Foundry-Features\n", + "Payload: {\n", + " \"input\": \"Hello! What can you help me with?\",\n", + " \"stream\": false\n", + "}\n", + "\n", + "Status: 200\n", + "\n", + "================================================================================\n", + "AGENT RESPONSE (via APIM):\n", + "================================================================================\n", + "Hi — I can help with a wide range of things. A few examples:\n", + "\n", + "- Explain concepts or teach topics (science, history, programming, math) in plain language or with step-by-step reasoning. \n", + "- Answer questions, summarize articles or long text, and highlight key points. \n", + "- Draft, edit, or rewrite text: emails, resumes, essays, reports, or creative writing. \n", + "- Help with coding: write, debug, or explain code in many languages. \n", + "- Plan and organize: study plans, trip itineraries, project steps, or shopping lists. \n", + "- Brainstorm ideas: names, product features, marketing angles, or recipes. \n", + "- Troubleshoot common technical or everyday problems and suggest next steps. \n", + "- Translate text between many languages and adapt tone or formality.\n", + "\n", + "I can also fetch current weather for a specific city if you’d like (just tell me the city). I can’t browse the web in real time or replace professional legal/medical advice, but I can summarize authoritative info and suggest questions to ask a pro.\n", + "\n", + "What would you like help with right now?\n", + "================================================================================\n", + "\n", + "Extracted response stored in 'apim_response' variable\n", + "Agent text stored in 'agent_text' variable\n" + ] + } + ], + "source": [ + "import json\n", + "import requests\n", + "\n", + "url = build_apim_responses_url(APIM_SUFFIX, AGENT_NAME)\n", + "\n", + "headers = {\n", + " \"api-key\": APIM_SUBSCRIPTION_KEY,\n", + " \"Content-Type\": DEFAULT_CONTENT_TYPE,\n", + " \"Foundry-Features\": FOUNDRY_FEATURES_HEADER,\n", + "}\n", + "\n", + "payload = {\n", + " \"input\": DIRECT_TEST_INPUT,\n", + " \"stream\": False,\n", + "}\n", + "\n", + "print(f\"POST {url}?api-version={API_VERSION}\")\n", + "print(f\"APIM Suffix: {APIM_SUFFIX}\")\n", + "print(f\"Agent Name (in URL path): {AGENT_NAME}\")\n", + "print(f\"Content-Type: {DEFAULT_CONTENT_TYPE}\")\n", + "print(f\"Headers: api-key={APIM_SUBSCRIPTION_KEY[:20]}..., Content-Type, Foundry-Features\")\n", + "print(f\"Payload: {json.dumps(payload, indent=2)}\")\n", + "print()\n", + "\n", + "response = requests.post(url, headers=headers, json=payload, params={\"api-version\": API_VERSION})\n", + "print(f\"Status: {response.status_code}\")\n", + "print()\n", + "\n", + "# Extract response from payload\n", + "apim_response = None\n", + "agent_text = None\n", + "\n", + "if response.status_code == 200:\n", + " try:\n", + " result = response.json()\n", + " apim_response = result\n", + "\n", + " # Extract agent text from nested structure\n", + " if \"output\" in result and len(result[\"output\"]) > 0:\n", + " message = result[\"output\"][0]\n", + " if \"content\" in message and len(message[\"content\"]) > 0:\n", + " agent_text = message[\"content\"][0].get(\"text\", \"\")\n", + "\n", + " print(\"=\" * 80)\n", + " print(\"AGENT RESPONSE (via APIM):\")\n", + " print(\"=\" * 80)\n", + " if agent_text:\n", + " print(agent_text)\n", + " else:\n", + " print(\"Full response:\")\n", + " print(json.dumps(result, indent=2))\n", + " print(\"=\" * 80)\n", + "\n", + " except json.JSONDecodeError as e:\n", + " print(f\"Failed to parse JSON: {e}\")\n", + " print(f\"Raw response: {response.text}\")\n", + "else:\n", + " print(f\"Error: {response.status_code}\")\n", + " if response.text:\n", + " try:\n", + " apim_response = response.json()\n", + " print(json.dumps(apim_response, indent=2))\n", + " except Exception:\n", + " print(response.text)\n", + "\n", + "print(\"\\nExtracted response stored in 'apim_response' variable\")\n", + "print(\"Agent text stored in 'agent_text' variable\")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.10" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/README.md b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/README.md new file mode 100644 index 00000000..2eada499 --- /dev/null +++ b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/README.md @@ -0,0 +1,220 @@ +# Hosted Agent Frameworks + +This directory contains multiple framework implementations for deploying custom agents on **Microsoft Foundry Hosted Agents**. + +## Quick Start + +1. **Setup infrastructure first** (if you haven't already): + - Run the **infrastructure deployment notebook** to create Foundry services, APIM, and ACR + - Save the deployment outputs (APIM suffix, subscription key, Foundry endpoint) + +2. **Choose your framework**: + - [**Strands Framework**](#strands-framework) - Custom framework for structured agent responses + - [**Pydantic AI Framework**](#pydantic-ai-framework) - LLM framework with built-in validation + +3. **Run the corresponding setup notebook**: + - For Strands: `01_hosted_agent_strands_setup.ipynb` + - For Pydantic AI: `02_hosted_agent_pydantic_setup.ipynb` + +## Folder Structure + +``` +frameworks/ +├── 01_hosted_agent_strands_setup.ipynb # Deploy Strands-based agent +├── 02_hosted_agent_pydantic_setup.ipynb # Deploy Pydantic AI agent +├── strands/ # Strands framework implementation +│ ├── main.py # Agent entry point +│ ├── agent_creation.py # Agent setup code +│ ├── Dockerfile # Container image definition +│ ├── requirements-strands.txt # Strands framework dependencies +│ ├── README.md # Strands-specific documentation +│ ├── .env # Environment variables template +│ ├── .gitignore +│ └── .dockerignore +│ +└── pydantic/ # Pydantic AI framework implementation + ├── main.py # Agent entry point + ├── agent_creation.py # Agent setup code + ├── Dockerfile # Container image definition + ├── requirements-pydantic.txt # Pydantic dependencies + ├── README.md # Pydantic-specific documentation + ├── .env # Environment variables template + ├── .gitignore + └── .dockerignore +``` + +## Strands Framework + +**Best for**: Custom agent logic with full control over request/response handling + +### What it is +- Custom framework for building agents with structured responses +- Direct control over agent behavior and response formatting +- Ideal for domain-specific agent implementations + +### How it works (in `01_hosted_agent_strands_setup.ipynb`) +1. **Builds Docker image** from `strands/` directory +2. **Deploys to Foundry** using image from ACR +3. **Tests direct API** - calls Foundry Responses API with bearer token +4. **Tests via APIM** - routes through API Management gateway with subscription key + +### Key Files +- `main.py` - Agent execution and response protocol handler +- `agent_creation.py` - Foundry agent registration +- `requirements-strands.txt` - Framework-specific dependencies +- `Dockerfile` - Container image with `FROM python:3.12-slim` + +### Getting Started +```python +# Run notebook cells in order: +# 1. Build and push Docker image to ACR +# 2. Create hosted agent version in Foundry +# 3. Test direct API call (validates agent is running) +# 4. Test through APIM (validates gateway routing) +``` + +## Pydantic AI Framework + +**Best for**: LLM-powered agents with automatic input/output validation + +### What it is +- Lightweight LLM framework with built-in type safety +- Automatic request/response validation via Pydantic models +- Streamlined agent development with minimal boilerplate + +### How it works (in `02_hosted_agent_pydantic_setup.ipynb`) +1. **Builds Docker image** from `pydantic/` directory +2. **Deploys to Foundry** using image from ACR +3. **Tests direct API** - calls Foundry Responses API with bearer token +4. **Tests via APIM** - routes through API Management gateway with subscription key + +### Key Files +- `main.py` - Pydantic-based agent with validation +- `agent_creation.py` - Foundry agent registration +- `requirements-pydantic.txt` - Pydantic and related dependencies +- `Dockerfile` - Container image with `FROM python:3.12-slim` + +### Getting Started +```python +# Run notebook cells in order: +# 1. Build and push Docker image to ACR +# 2. Create hosted agent version in Foundry +# 3. Test direct API call (validates agent is running) +# 4. Test through APIM (validates gateway routing) +``` + +## Important: Foundry Hosted Agent URL Format + +**Agent-specific routing is required** — there is no generic `/responses` endpoint that accepts `agent_reference` in the request body. + +Each agent must be invoked with its name in the URL path: + +``` +POST {FOUNDRY_ENDPOINT}/agents/{AGENT_NAME}/endpoint/protocols/openai/responses?api-version=v1 +``` + +**Through APIM Gateway:** +``` +POST https://apim-{APIM_SUFFIX}.azure-api.net/hosted-agent-responses/agents/{AGENT_NAME}/endpoint/protocols/openai/responses?api-version=v1 +``` + +- `AGENT_NAME` - The name you choose when creating the agent (e.g., `strands-agent`, `pydantic-agent`) +- `api-version=v1` - Required query parameter for Responses protocol v1.0.0 + +## Environment Configuration + +Both frameworks expect these environment variables (set in Foundry agent definition): + +| Variable | Purpose | Example | +|----------|---------|---------| +| `AZURE_OPENAI_ENDPOINT` | APIM inference API for model calls | `https://apim-xyz.azure-api.net/inference/models` | +| `AZURE_OPENAI_API_VERSION` | OpenAI API version | `2024-05-01-preview` | +| `AZURE_OPENAI_DEPLOYMENT` | Model name | `gpt-5-mini` | +| `APIM_SUBSCRIPTION_KEY` | APIM subscription key | (from deployment outputs) | + +## Workflow: Direct vs APIM + +### Direct Call (Section 3 in notebooks) +- **URL**: `https://foundry-agents-{suffix}.services.ai.azure.com/api/projects/default-foundry-agents/agents/{AGENT_NAME}/endpoint/protocols/openai/responses?api-version=v1` +- **Auth**: Bearer token (from `az login` → `https://ai.azure.com/.default`) +- **Use case**: Development, validation that agent is running correctly +- **Pros**: Direct connection, best for debugging +- **Cons**: Requires Azure credentials on client + +### APIM Gateway (Section 4 in notebooks) +- **URL**: `https://apim-{APIM_SUFFIX}.azure-api.net/hosted-agent-responses/agents/{AGENT_NAME}/endpoint/protocols/openai/responses?api-version=v1` +- **Auth**: API key header (`api-key: `) +- **Use case**: Production, client applications, rate limiting, monitoring +- **Pros**: Gateway features (caching, rate limiting, analytics), simpler auth +- **Cons**: One extra hop through APIM + +## Adding a New Framework + +To add another framework (e.g., CrewAI, AutoGen): + +1. **Create folder**: `mkdir frameworks/crew-ai` +2. **Copy template files**: + - Copy `Dockerfile` from existing framework + - Create `main.py` with your framework initialization + - Create `agent_creation.py` with Foundry registration + - Create `requirements-crew-ai.txt` with framework dependencies + - Create `README.md` documenting the framework +3. **Create setup notebook**: Copy `01_hosted_agent_strands_setup.ipynb` and adapt: + - Change `strands_dir = "strands"` to `strands_dir = "crew-ai"` + - Change `IMAGE_NAME` to `crew-ai-agent` + - Update documentation to reference CrewAI + - Update section 2 agent creation code for CrewAI specifics +4. **Update deployment**: If deploying both, register agents with different names + +## Testing Your Agent + +After deployment, verify your agent works: + +```bash +# 1. Ensure agent is in "Running" state (check Foundry portal) +# 2. Run Section 3 (Direct) test +# 3. Run Section 4 (APIM) test +# 4. Compare responses - they should be identical +``` + +Successful response structure: +```json +{ + "id": "caresp_...", + "object": "response", + "output": [{ + "type": "message", + "role": "assistant", + "content": [{ + "type": "output_text", + "text": "Agent's response text..." + }] + }], + "status": "completed" +} +``` + +## Troubleshooting + +### "Agent endpoint not found" +- Verify agent name in URL matches the agent name created in Foundry +- Ensure agent is in "Running" state (not "Creating", "Failed", etc.) + +### "api-version query parameter is not allowed" +- Ensure you're using `/v1` path, not `/v2` +- Don't include `api-version` in APIM policy - use it only in URL + +### "Managed identity does not have access to Azure AI" +- Verify Foundry project's managed identity has proper role assignment +- Check APIM managed identity has `Contributor` or `Cognitive Services User` role + +### Agent not receiving requests +- Check Docker image builds successfully: `docker build -t test:1.0 .` +- Verify APIM policy correctly injects authentication headers +- Check ACR image is pullable by Foundry (check image pull errors in Foundry portal) + +## References + +- [Microsoft Foundry Hosted Agents Documentation](https://learn.microsoft.com/en-us/azure/ai-studio/ai-services/agents/) +- [Responses Protocol v1.0.0 Specification](https://learn.microsoft.com/en-us/azure/ai-studio/ai-services/agents/protocols/responses) +- [APIM Policies for Authentication](https://learn.microsoft.com/en-us/azure/api-management/policies/authentication-policies) diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/pydantic-ai/.dockerignore b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/pydantic/.dockerignore similarity index 100% rename from labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/pydantic-ai/.dockerignore rename to labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/pydantic/.dockerignore diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/pydantic-ai/.gitignore b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/pydantic/.gitignore similarity index 100% rename from labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/pydantic-ai/.gitignore rename to labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/pydantic/.gitignore diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/pydantic/Dockerfile b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/pydantic/Dockerfile new file mode 100644 index 00000000..c8fd2526 --- /dev/null +++ b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/pydantic/Dockerfile @@ -0,0 +1,7 @@ +FROM python:3.12-slim +WORKDIR /app +COPY . user_agent/ +WORKDIR /app/user_agent +RUN if [ -f requirements-pydantic.txt ]; then pip install -r requirements-pydantic.txt; elif [ -f requirements.txt ]; then pip install -r requirements.txt; fi +EXPOSE 8088 +CMD ["python", "main.py"] \ No newline at end of file diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/pydantic-ai/README.md b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/pydantic/README.md similarity index 83% rename from labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/pydantic-ai/README.md rename to labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/pydantic/README.md index 0fd74775..14cd4d16 100644 --- a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/pydantic-ai/README.md +++ b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/pydantic/README.md @@ -28,5 +28,7 @@ This sample code shows you how to run a Pydantic AI agent in Foundry Hosted Agen ## Notes -- Use Microsoft Entra ID / managed identity where possible, and avoid hard-coded API keys. +- This sample routes model calls through APIM inference chat-completions. +- Configure AZURE_OPENAI_ENDPOINT to your APIM inference URL and set APIM_SUBSCRIPTION_KEY. +- The runtime sends the APIM subscription key in the api-key header for model calls. - Use the notebook placeholders to provide your own project, registry, and deployment values. diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/pydantic-ai/image.png b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/pydantic/image.png similarity index 100% rename from labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/pydantic-ai/image.png rename to labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/pydantic/image.png diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/pydantic-ai/main.py b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/pydantic/main.py similarity index 72% rename from labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/pydantic-ai/main.py rename to labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/pydantic/main.py index ca3020e9..a3f0699f 100644 --- a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/pydantic-ai/main.py +++ b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/pydantic/main.py @@ -3,17 +3,20 @@ Requires the following environment variables (see .env): - AZURE_OPENAI_ENDPOINT e.g. https://.openai.azure.com/ - AZURE_OPENAI_DEPLOYMENT deployment name, e.g. gpt-5-mini - AZURE_OPENAI_API_VERSION optional, defaults to 2024-12-01-preview + AZURE_OPENAI_ENDPOINT APIM base URL (recommended): + https://.azure-api.net/inference/models + or full chat-completions URL: + https://.azure-api.net/inference/models/chat/completions?api-version=2024-05-01-preview + AZURE_OPENAI_DEPLOYMENT model name sent as the chat-completions "model" field + AZURE_OPENAI_API_KEY required API key used for model calls (or OPENAI_API_KEY) + AZURE_OPENAI_API_VERSION optional, defaults to 2024-05-01-preview + APIM_SUBSCRIPTION_KEY optional; when set, sent as api-key LOG_LEVEL optional, defaults to INFO Authentication: - This app uses DefaultAzureCredential (Microsoft Entra ID), not API keys. - The runtime identity (user, service principal, or managed identity) must have - Azure OpenAI data-plane access (for example, the Cognitive Services OpenAI User role) - on the target Azure OpenAI resource. + This app uses API key authentication for model calls. + It does not use managed identity for OpenAI chat-completions requests. """ import asyncio @@ -23,13 +26,12 @@ from typing import Sequence from dotenv import load_dotenv -from openai import AsyncAzureOpenAI +from openai import AsyncOpenAI from pydantic_ai import Agent from pydantic_ai.models.openai import OpenAIChatModel from pydantic_ai.providers.openai import OpenAIProvider -from azure.identity import DefaultAzureCredential, get_bearer_token_provider from azure.ai.agentserver.responses import ( CreateResponse, ResponseContext, @@ -96,17 +98,26 @@ def build_agent() -> Agent: if _AGENT is None: endpoint = os.environ["AZURE_OPENAI_ENDPOINT"] deployment = os.environ.get("AZURE_OPENAI_DEPLOYMENT", "gpt-5-mini") - api_version = os.environ.get("AZURE_OPENAI_API_VERSION", "2024-12-01-preview") - - token_provider = get_bearer_token_provider( - DefaultAzureCredential(), - "https://cognitiveservices.azure.com/.default", + api_key = ( + os.environ.get("AZURE_OPENAI_API_KEY") + or os.environ.get("OPENAI_API_KEY") + or os.environ.get("APIM_SUBSCRIPTION_KEY") ) - - client = AsyncAzureOpenAI( - azure_endpoint=endpoint, - api_version=api_version, - azure_ad_token_provider=token_provider, + if not api_key: + raise RuntimeError( + "Missing API key. Set AZURE_OPENAI_API_KEY (or OPENAI_API_KEY / APIM_SUBSCRIPTION_KEY)." + ) + + api_version = os.environ.get("AZURE_OPENAI_API_VERSION", "2024-05-01-preview") + base_url = endpoint.split("?", 1)[0].rstrip("/") + if base_url.endswith("/chat/completions"): + base_url = base_url[: -len("/chat/completions")] + + client = AsyncOpenAI( + base_url=base_url, + api_key=api_key, + default_query={"api-version": api_version}, + default_headers={"api-key": api_key}, ) model = OpenAIChatModel( @@ -118,8 +129,8 @@ def build_agent() -> Agent: model, instructions=( "You are a helpful assistant who can explain concepts, answer questions, and " - "reason through problems. You have access to two tools: get_weather for weather " - "questions and show_internal_environment_variables for debugging." + "reason through problems. You have access to one tool: get_weather for weather " + "questions." ), ) @@ -129,9 +140,6 @@ def get_weather(city: str) -> str: logger.info("tool_call=get_weather city=%s result_c=%s", city, temperature_c) return f"The current temperature in {city} is {temperature_c} deg C." - @_AGENT.tool_plain - def show_internal_environment_variables() -> str: - return str(dict(os.environ)) return _AGENT diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/pydantic-ai/requirements.txt b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/pydantic/requirements-pydantic.txt similarity index 100% rename from labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/pydantic-ai/requirements.txt rename to labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/pydantic/requirements-pydantic.txt diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/.dockerignore b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/strands/.dockerignore similarity index 100% rename from labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/.dockerignore rename to labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/strands/.dockerignore diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/.gitignore b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/strands/.gitignore similarity index 100% rename from labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/.gitignore rename to labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/strands/.gitignore diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/strands/Dockerfile b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/strands/Dockerfile new file mode 100644 index 00000000..9b31e8a4 --- /dev/null +++ b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/strands/Dockerfile @@ -0,0 +1,7 @@ +FROM python:3.12-slim +WORKDIR /app +COPY . user_agent/ +WORKDIR /app/user_agent +RUN if [ -f requirements-strands.txt ]; then pip install -r requirements-strands.txt; elif [ -f requirements.txt ]; then pip install -r requirements.txt; fi +EXPOSE 8088 +CMD ["python", "main.py"] \ No newline at end of file diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/README.md b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/strands/README.md similarity index 100% rename from labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/README.md rename to labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/strands/README.md diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/example.env b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/strands/example.env similarity index 100% rename from labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/example.env rename to labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/strands/example.env diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/image.png b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/strands/image.png similarity index 100% rename from labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/image.png rename to labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/strands/image.png diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/main.py b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/strands/main.py similarity index 100% rename from labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/main.py rename to labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/strands/main.py diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/requirements.txt b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/strands/requirements-strands.txt similarity index 100% rename from labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/requirements.txt rename to labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/strands/requirements-strands.txt diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/pydantic-ai/01_hosted_agent_pydantic_setup.ipynb b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/pydantic-ai/01_hosted_agent_pydantic_setup.ipynb deleted file mode 100644 index 70442702..00000000 --- a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/pydantic-ai/01_hosted_agent_pydantic_setup.ipynb +++ /dev/null @@ -1,187 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "54d927d1", - "metadata": {}, - "source": [ - "# Pydantic AI Hosted Agent Setup\n", - "\n", - "This notebook helps you:\n", - "1. Build and push a container image for your Pydantic AI hosted agent code.\n", - "2. Create or update a hosted agent version from Python.\n", - "3. Grant Foundry role access to the hosted agent identity.\n", - "\n", - "## Prerequisites\n", - "- Your signed-in identity must have `Container Registry Repository Writer` on the target ACR repository (or equivalent push permission).\n", - "- The Azure Foundry project/resource identity must have pull access to the image in ACR (for example `Container Registry Repository Reader` or equivalent repository-level pull permission).\n", - "\n", - "Fill in all placeholder values before running code cells." - ] - }, - { - "cell_type": "markdown", - "id": "368f7a90", - "metadata": {}, - "source": [ - "## 1. Build And Push The Container Image\n", - "\n", - "This runs Azure Container Registry cloud build from the current pydantic-ai folder." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "733aa858", - "metadata": {}, - "outputs": [], - "source": [ - "# Set these placeholders\n", - "ACR_NAME = \"\"\n", - "IMAGE_NAME = \"\"\n", - "IMAGE_TAG = \"\"\n", - "\n", - "print(f\"ACR_NAME={ACR_NAME}\")\n", - "print(f\"IMAGE_NAME={IMAGE_NAME}\")\n", - "print(f\"IMAGE_TAG={IMAGE_TAG}\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0ee7f96c", - "metadata": {}, - "outputs": [], - "source": [ - "import subprocess\n", - "\n", - "build_cmd = [\n", - " \"az\", \"acr\", \"build\",\n", - " \"-t\", f\"{IMAGE_NAME}:{IMAGE_TAG}\",\n", - " \"-r\", ACR_NAME,\n", - " \"--source-acr-auth-id\", \"[caller]\",\n", - " \".\",\n", - "]\n", - "\n", - "print(\"Running:\", \" \".join(build_cmd))\n", - "subprocess.run(build_cmd, check=True)" - ] - }, - { - "cell_type": "markdown", - "id": "2614c4c5", - "metadata": {}, - "source": [ - "## 2. Create Hosted Agent Version\n", - "\n", - "Use this cell to register your hosted agent container image in Foundry.\n", - "\n", - "Install dependencies first if needed:\n", - "`pip install azure-ai-projects azure-identity`" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2a7440bb", - "metadata": {}, - "outputs": [], - "source": [ - "from azure.ai.projects import AIProjectClient\n", - "from azure.ai.projects.models import (\n", - " HostedAgentDefinition,\n", - " ProtocolVersionRecord,\n", - " AgentProtocol,\n", - " ContainerConfiguration,\n", - ")\n", - "from azure.identity import DefaultAzureCredential\n", - "\n", - "# Placeholder values - update before running\n", - "PROJECT_ENDPOINT = \"https://.services.ai.azure.com/api/projects/\"\n", - "AGENT_NAME = \"\"\n", - "\n", - "ACR_LOGIN_SERVER = \".azurecr.io\"\n", - "IMAGE_NAME = \"\"\n", - "IMAGE_TAG = \"\"\n", - "IMAGE_URI = f\"{ACR_LOGIN_SERVER}/{IMAGE_NAME}:{IMAGE_TAG}\"\n", - "\n", - "# Environment variables passed to your containerized Pydantic AI app\n", - "AZURE_OPENAI_ENDPOINT = \"https://.openai.azure.com/\"\n", - "AZURE_OPENAI_API_VERSION = \"\"\n", - "AZURE_OPENAI_DEPLOYMENT = \"\"\n", - "\n", - "credential = DefaultAzureCredential()\n", - "project = AIProjectClient(\n", - " endpoint=PROJECT_ENDPOINT,\n", - " credential=credential,\n", - " allow_preview=True,\n", - ")\n", - "\n", - "agent = project.agents.create_version(\n", - " agent_name=AGENT_NAME,\n", - " definition=HostedAgentDefinition(\n", - " protocol_versions=[\n", - " ProtocolVersionRecord(protocol=AgentProtocol.RESPONSES, version=\"1.0.0\")\n", - " ],\n", - " cpu=\"1\",\n", - " memory=\"2Gi\",\n", - " container_configuration=ContainerConfiguration(image=IMAGE_URI),\n", - " environment_variables={\n", - " \"AZURE_OPENAI_ENDPOINT\": AZURE_OPENAI_ENDPOINT,\n", - " \"AZURE_OPENAI_API_VERSION\": AZURE_OPENAI_API_VERSION,\n", - " \"AZURE_OPENAI_DEPLOYMENT\": AZURE_OPENAI_DEPLOYMENT,\n", - " \"LOG_LEVEL\": \"INFO\",\n", - " },\n", - " ),\n", - ")\n", - "\n", - "print(f\"Agent created: {agent.name}, version: {agent.version}\")" - ] - }, - { - "cell_type": "markdown", - "id": "9633c110", - "metadata": {}, - "source": [ - "## 3. Grant Foundry User Role To The Hosted Agent Identity\n", - "\n", - "After the hosted agent version is created, Azure provisions an agent identity (service principal/object ID).\n", - "\n", - "Grant that identity the `Foundry User` role on your Foundry resource so it can access Foundry capabilities at runtime." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "91ce0d6e", - "metadata": {}, - "outputs": [], - "source": [ - "import subprocess\n", - "\n", - "# Placeholders - update these values\n", - "AGENT_IDENTITY_OBJECT_ID = \"\"\n", - "FOUNDRY_RESOURCE_ID = \"/subscriptions//resourceGroups//providers/Microsoft.CognitiveServices/accounts/\"\n", - "ROLE_NAME = \"Foundry User\"\n", - "\n", - "assign_cmd = [\n", - " \"az\", \"role\", \"assignment\", \"create\",\n", - " \"--assignee-object-id\", AGENT_IDENTITY_OBJECT_ID,\n", - " \"--assignee-principal-type\", \"ServicePrincipal\",\n", - " \"--role\", ROLE_NAME,\n", - " \"--scope\", FOUNDRY_RESOURCE_ID,\n", - "]\n", - "\n", - "print(\"Running:\", \" \".join(assign_cmd))\n", - "subprocess.run(assign_cmd, check=True)" - ] - } - ], - "metadata": { - "language_info": { - "name": "python" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/pydantic-ai/Dockerfile b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/pydantic-ai/Dockerfile deleted file mode 100644 index bf032f64..00000000 --- a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/pydantic-ai/Dockerfile +++ /dev/null @@ -1,7 +0,0 @@ -FROM python:3.12-slim -WORKDIR /app -COPY . user_agent/ -WORKDIR /app/user_agent -RUN if [ -f requirements.txt ]; then pip install -r requirements.txt; fi -EXPOSE 8088 -CMD ["python", "main.py"] \ No newline at end of file diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/01_hosted_agent_strands_setup.ipynb b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/01_hosted_agent_strands_setup.ipynb deleted file mode 100644 index 0cf07f25..00000000 --- a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/01_hosted_agent_strands_setup.ipynb +++ /dev/null @@ -1,1128 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "c4955e40", - "metadata": {}, - "source": [ - "# Strands Hosted Agent Setup\n", - "\n", - "This notebook helps you build, deploy, and test a **Strands-based custom agent** on Microsoft Foundry Hosted Agents.\n", - "\n", - "### What this notebook does\n", - "\n", - "1. **Build & Push** - Builds a Docker container image for your Strands agent and pushes it to Azure Container Registry (ACR)\n", - "2. **Deploy** - Creates a hosted agent version in your Foundry project, pulling the image from ACR\n", - "3. **Test Direct** - Validates the agent works by calling Foundry's Responses API directly with your Azure credentials\n", - "4. **Test via APIM** - Routes requests through Azure API Management to test the production gateway path\n", - "\n", - "### Prerequisites\n", - "\n", - "Before running this notebook:\n", - "- Complete the **infrastructure deployment** notebook first (creates Foundry resources, APIM, ACR)\n", - "- Have the deployment outputs available:\n", - " - Foundry project endpoint\n", - " - ACR login server\n", - " - APIM suffix\n", - " - APIM subscription key\n", - "- Docker Desktop must be running\n", - "- You must be logged in to Azure CLI (`az login`)" - ] - }, - { - "cell_type": "markdown", - "id": "2c5ee3f2", - "metadata": {}, - "source": [ - "## 1. Build And Push The Container Image\n", - "\n", - "This builds the image locally with Docker and pushes it to ACR.\n", - "Run this after completing the prerequisites above." - ] - }, - { - "cell_type": "code", - "execution_count": 44, - "id": "1cc7246e", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "ACR_NAME=acryxz4ztnhs2gd4\n", - "ACR_LOGIN_SERVER=acryxz4ztnhs2gd4.azurecr.io\n", - "IMAGE_NAME=strands-agent\n", - "IMAGE_TAG=1.0.0\n", - "IMAGE_URI=acryxz4ztnhs2gd4.azurecr.io/strands-agent:1.0.0\n" - ] - } - ], - "source": [ - "# Set these placeholders\n", - "ACR_NAME = \"acryxz4ztnhs2gd4\"\n", - "IMAGE_NAME = \"strands-agent\"\n", - "IMAGE_TAG = \"1.0.0\"\n", - "ACR_LOGIN_SERVER = f\"{ACR_NAME}.azurecr.io\"\n", - "IMAGE_URI = f\"{ACR_LOGIN_SERVER}/{IMAGE_NAME}:{IMAGE_TAG}\"\n", - "\n", - "print(f\"ACR_NAME={ACR_NAME}\")\n", - "print(f\"ACR_LOGIN_SERVER={ACR_LOGIN_SERVER}\")\n", - "print(f\"IMAGE_NAME={IMAGE_NAME}\")\n", - "print(f\"IMAGE_TAG={IMAGE_TAG}\")\n", - "print(f\"IMAGE_URI={IMAGE_URI}\")" - ] - }, - { - "cell_type": "markdown", - "id": "97e66486", - "metadata": {}, - "source": [ - "### Fill in your configuration\n", - "\n", - "Replace the placeholder values below with your actual Azure resources. These should match the outputs from the infrastructure deployment notebook:\n", - "- `ACR_NAME`: Your Azure Container Registry name (e.g., `acrxhep4wovroziu`)\n", - "- `IMAGE_NAME`: Container image name for your Strands agent (usually `strands-agent`)\n", - "- `IMAGE_TAG`: Semantic version tag for your image (e.g., `1.0.0`)\n", - "\n", - "The computed values (`ACR_LOGIN_SERVER`, `IMAGE_URI`) will be used in subsequent steps." - ] - }, - { - "cell_type": "code", - "execution_count": 45, - "id": "702db155", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Login Succeeded\n" - ] - } - ], - "source": [ - "# Ensure Docker is running\n", - "!az acr login --name {ACR_NAME}" - ] - }, - { - "cell_type": "code", - "execution_count": 46, - "id": "3126aa58", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Running: docker build -t acryxz4ztnhs2gd4.azurecr.io/strands-agent:1.0.0 .\n", - "Running: docker push acryxz4ztnhs2gd4.azurecr.io/strands-agent:1.0.0\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "#0 building with \"desktop-linux\" instance using docker driver\n", - "\n", - "#1 [internal] load build definition from Dockerfile\n", - "#1 transferring dockerfile: 233B 0.0s done\n", - "#1 DONE 0.0s\n", - "\n", - "#2 [internal] load metadata for docker.io/library/python:3.12-slim\n", - "#2 DONE 0.9s\n", - "\n", - "#3 [internal] load .dockerignore\n", - "#3 transferring context: 341B 0.0s done\n", - "#3 DONE 0.0s\n", - "\n", - "#4 [1/5] FROM docker.io/library/python:3.12-slim@sha256:423ed6ab25b1921a477529254bfeeabf5855151dc2c3141699a1bfc852199fbf\n", - "#4 resolve docker.io/library/python:3.12-slim@sha256:423ed6ab25b1921a477529254bfeeabf5855151dc2c3141699a1bfc852199fbf 0.0s done\n", - "#4 DONE 0.0s\n", - "\n", - "#5 [internal] load build context\n", - "#5 transferring context: 17.61kB 0.0s done\n", - "#5 DONE 0.0s\n", - "\n", - "#6 [2/5] WORKDIR /app\n", - "#6 CACHED\n", - "\n", - "#7 [3/5] COPY . user_agent/\n", - "#7 DONE 0.0s\n", - "\n", - "#8 [4/5] WORKDIR /app/user_agent\n", - "#8 DONE 0.0s\n", - "\n", - "#9 [5/5] RUN if [ -f requirements.txt ]; then pip install -r requirements.txt; fi\n", - "#9 17.38 Collecting azure-ai-agentserver-responses==1.0.0b8 (from -r requirements.txt (line 1))\n", - "#9 17.65 Downloading azure_ai_agentserver_responses-1.0.0b8-py3-none-any.whl.metadata (13 kB)\n", - "#9 17.93 Collecting strands-agents==1.45.0 (from strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 17.97 Downloading strands_agents-1.45.0-py3-none-any.whl.metadata (19 kB)\n", - "#9 18.45 Collecting python-dotenv (from -r requirements.txt (line 3))\n", - "#9 18.48 Downloading python_dotenv-1.2.2-py3-none-any.whl.metadata (27 kB)\n", - "#9 18.63 Collecting azure-ai-projects==2.3.0 (from -r requirements.txt (line 4))\n", - "#9 18.67 Downloading azure_ai_projects-2.3.0-py3-none-any.whl.metadata (64 kB)\n", - "#9 18.95 Collecting azure-ai-agentserver-core>=2.0.0b7 (from azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 18.98 Downloading azure_ai_agentserver_core-2.0.0b7-py3-none-any.whl.metadata (7.8 kB)\n", - "#9 19.23 Collecting azure-core>=1.30.0 (from azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 19.27 Downloading azure_core-1.41.0-py3-none-any.whl.metadata (49 kB)\n", - "#9 19.43 Collecting isodate>=0.6.1 (from azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 19.47 Downloading isodate-0.7.2-py3-none-any.whl.metadata (11 kB)\n", - "#9 25.11 Collecting aiohttp<4.0.0,>=3.10.0 (from azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 25.16 Downloading aiohttp-3.14.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (8.3 kB)\n", - "#9 30.88 Collecting boto3<2.0.0,>=1.26.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 30.92 Downloading boto3-1.43.44-py3-none-any.whl.metadata (6.6 kB)\n", - "#9 36.61 Collecting botocore<2.0.0,>=1.29.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 36.65 Downloading botocore-1.43.44-py3-none-any.whl.metadata (5.6 kB)\n", - "#9 36.78 Collecting docstring-parser<1.0,>=0.15 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 36.81 Downloading docstring_parser-0.18.0-py3-none-any.whl.metadata (3.5 kB)\n", - "#9 37.20 Collecting jsonschema<5.0.0,>=4.0.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 37.23 Downloading jsonschema-4.26.0-py3-none-any.whl.metadata (7.6 kB)\n", - "#9 37.47 Collecting mcp<2.0.0,>=1.23.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 37.54 Downloading mcp-1.28.1-py3-none-any.whl.metadata (9.4 kB)\n", - "#9 37.85 Collecting opentelemetry-api<2.0.0,>=1.30.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 37.88 Downloading opentelemetry_api-1.43.0-py3-none-any.whl.metadata (1.4 kB)\n", - "#9 38.09 Collecting opentelemetry-instrumentation-threading<1.00b0,>=0.51b0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 38.13 Downloading opentelemetry_instrumentation_threading-0.64b0-py3-none-any.whl.metadata (2.1 kB)\n", - "#9 38.40 Collecting opentelemetry-sdk<2.0.0,>=1.30.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 38.43 Downloading opentelemetry_sdk-1.43.0-py3-none-any.whl.metadata (1.7 kB)\n", - "#9 39.84 Collecting pydantic<3.0.0,>=2.4.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 39.87 Downloading pydantic-2.13.4-py3-none-any.whl.metadata (109 kB)\n", - "#9 40.38 Collecting pyyaml<7.0.0,>=6.0.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 40.41 Downloading pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (2.4 kB)\n", - "#9 40.61 Collecting typing-extensions<5.0.0,>=4.13.2 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 40.64 Downloading typing_extensions-4.16.0-py3-none-any.whl.metadata (3.3 kB)\n", - "#9 41.15 Collecting watchdog<7.0.0,>=6.0.0 (from strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 41.18 Downloading watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl.metadata (44 kB)\n", - "#9 41.79 Collecting azure-identity>=1.15.0 (from azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", - "#9 41.83 Downloading azure_identity-1.25.3-py3-none-any.whl.metadata (91 kB)\n", - "#9 42.72 Collecting openai>=2.8.0 (from azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", - "#9 42.75 Downloading openai-2.44.0-py3-none-any.whl.metadata (34 kB)\n", - "#9 43.13 Collecting azure-storage-blob>=12.15.0 (from azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", - "#9 43.17 Downloading azure_storage_blob-12.30.0-py3-none-any.whl.metadata (26 kB)\n", - "#9 43.41 Collecting aws-bedrock-token-generator<2.0.0,>=1.1.0 (from strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 43.45 Downloading aws_bedrock_token_generator-1.1.0-py3-none-any.whl.metadata (7.5 kB)\n", - "#9 44.21 Collecting aiohappyeyeballs>=2.5.0 (from aiohttp<4.0.0,>=3.10.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 44.24 Downloading aiohappyeyeballs-2.7.1-py3-none-any.whl.metadata (5.9 kB)\n", - "#9 44.35 Collecting aiosignal>=1.4.0 (from aiohttp<4.0.0,>=3.10.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 44.38 Downloading aiosignal-1.4.0-py3-none-any.whl.metadata (3.7 kB)\n", - "#9 44.56 Collecting attrs>=17.3.0 (from aiohttp<4.0.0,>=3.10.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 44.59 Downloading attrs-26.1.0-py3-none-any.whl.metadata (8.8 kB)\n", - "#9 45.31 Collecting frozenlist>=1.1.1 (from aiohttp<4.0.0,>=3.10.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 45.36 Downloading frozenlist-1.8.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl.metadata (20 kB)\n", - "#9 48.06 Collecting multidict<7.0,>=4.5 (from aiohttp<4.0.0,>=3.10.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 48.10 Downloading multidict-6.7.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (5.3 kB)\n", - "#9 48.79 Collecting propcache>=0.2.0 (from aiohttp<4.0.0,>=3.10.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 48.82 Downloading propcache-0.5.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (16 kB)\n", - "#9 51.93 Collecting yarl<2.0,>=1.17.0 (from aiohttp<4.0.0,>=3.10.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 51.97 Downloading yarl-1.24.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (94 kB)\n", - "#9 55.94 Collecting starlette>=0.45.0 (from azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 55.97 Downloading starlette-1.3.1-py3-none-any.whl.metadata (6.4 kB)\n", - "#9 56.21 Collecting hypercorn>=0.17.0 (from azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 56.24 Downloading hypercorn-0.18.0-py3-none-any.whl.metadata (5.1 kB)\n", - "#9 56.64 Collecting microsoft-opentelemetry>=1.0.0 (from azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 56.67 Downloading microsoft_opentelemetry-1.3.5-py3-none-any.whl.metadata (23 kB)\n", - "#9 57.07 Collecting requests>=2.21.0 (from azure-core>=1.30.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 57.10 Downloading requests-2.34.2-py3-none-any.whl.metadata (4.8 kB)\n", - "#9 59.61 Collecting cryptography>=2.5 (from azure-identity>=1.15.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", - "#9 59.64 Downloading cryptography-49.0.0-cp311-abi3-manylinux_2_34_x86_64.whl.metadata (4.3 kB)\n", - "#9 59.86 Collecting msal>=1.35.1 (from azure-identity>=1.15.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", - "#9 59.89 Downloading msal-1.37.0-py3-none-any.whl.metadata (11 kB)\n", - "#9 60.06 Collecting msal-extensions>=1.2.0 (from azure-identity>=1.15.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", - "#9 60.12 Downloading msal_extensions-1.3.1-py3-none-any.whl.metadata (7.8 kB)\n", - "#9 62.93 Collecting jmespath<2.0.0,>=0.7.1 (from boto3<2.0.0,>=1.26.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 62.97 Downloading jmespath-1.1.0-py3-none-any.whl.metadata (7.6 kB)\n", - "#9 63.20 Collecting s3transfer<0.20.0,>=0.19.0 (from boto3<2.0.0,>=1.26.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 63.23 Downloading s3transfer-0.19.0-py3-none-any.whl.metadata (1.7 kB)\n", - "#9 63.41 Collecting python-dateutil<3.0.0,>=2.1 (from botocore<2.0.0,>=1.29.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 63.45 Downloading python_dateutil-2.9.0.post0-py2.py3-none-any.whl.metadata (8.4 kB)\n", - "#9 63.90 Collecting urllib3!=2.2.0,<3,>=1.25.4 (from botocore<2.0.0,>=1.29.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 63.93 Downloading urllib3-2.7.0-py3-none-any.whl.metadata (6.9 kB)\n", - "#9 64.18 Collecting jsonschema-specifications>=2023.03.6 (from jsonschema<5.0.0,>=4.0.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 64.22 Downloading jsonschema_specifications-2025.9.1-py3-none-any.whl.metadata (2.9 kB)\n", - "#9 64.55 Collecting referencing>=0.28.4 (from jsonschema<5.0.0,>=4.0.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 64.58 Downloading referencing-0.37.0-py3-none-any.whl.metadata (2.8 kB)\n", - "#9 67.54 Collecting rpds-py>=0.25.0 (from jsonschema<5.0.0,>=4.0.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 67.58 Downloading rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (4.1 kB)\n", - "#9 67.85 Collecting anyio>=4.5 (from mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 67.89 Downloading anyio-4.14.1-py3-none-any.whl.metadata (4.6 kB)\n", - "#9 68.01 Collecting httpx-sse>=0.4 (from mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 68.04 Downloading httpx_sse-0.4.3-py3-none-any.whl.metadata (9.7 kB)\n", - "#9 68.27 Collecting httpx<1.0.0,>=0.27.1 (from mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 68.31 Downloading httpx-0.28.1-py3-none-any.whl.metadata (7.1 kB)\n", - "#9 68.60 Collecting pydantic-settings>=2.5.2 (from mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 68.63 Downloading pydantic_settings-2.14.2-py3-none-any.whl.metadata (3.4 kB)\n", - "#9 69.28 Collecting pyjwt>=2.10.1 (from pyjwt[crypto]>=2.10.1->mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 69.31 Downloading pyjwt-2.13.0-py3-none-any.whl.metadata (3.4 kB)\n", - "#9 69.48 Collecting python-multipart>=0.0.9 (from mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 69.51 Downloading python_multipart-0.0.32-py3-none-any.whl.metadata (2.1 kB)\n", - "#9 69.74 Collecting sse-starlette>=1.6.1 (from mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 69.78 Downloading sse_starlette-3.4.5-py3-none-any.whl.metadata (15 kB)\n", - "#9 70.18 Collecting typing-inspection>=0.4.1 (from mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 70.21 Downloading typing_inspection-0.4.2-py3-none-any.whl.metadata (2.6 kB)\n", - "#9 70.58 Collecting uvicorn>=0.31.1 (from mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 70.61 Downloading uvicorn-0.51.0-py3-none-any.whl.metadata (6.6 kB)\n", - "#9 70.88 Collecting distro<2,>=1.7.0 (from openai>=2.8.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", - "#9 70.91 Downloading distro-1.9.0-py3-none-any.whl.metadata (6.8 kB)\n", - "#9 71.94 Collecting jiter<1,>=0.10.0 (from openai>=2.8.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", - "#9 71.99 Downloading jiter-0.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (5.2 kB)\n", - "#9 72.45 Collecting sniffio (from openai>=2.8.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", - "#9 72.48 Downloading sniffio-1.3.1-py3-none-any.whl.metadata (3.9 kB)\n", - "#9 72.92 Collecting tqdm>4 (from openai>=2.8.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", - "#9 72.96 Downloading tqdm-4.68.4-py3-none-any.whl.metadata (57 kB)\n", - "#9 73.58 Collecting opentelemetry-instrumentation==0.64b0 (from opentelemetry-instrumentation-threading<1.00b0,>=0.51b0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 73.61 Downloading opentelemetry_instrumentation-0.64b0-py3-none-any.whl.metadata (7.2 kB)\n", - "#9 76.31 Collecting wrapt<3.0.0,>=1.0.0 (from opentelemetry-instrumentation-threading<1.00b0,>=0.51b0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 76.35 Downloading wrapt-2.2.2-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl.metadata (7.4 kB)\n", - "#9 76.77 Collecting opentelemetry-semantic-conventions==0.64b0 (from opentelemetry-instrumentation==0.64b0->opentelemetry-instrumentation-threading<1.00b0,>=0.51b0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 76.80 Downloading opentelemetry_semantic_conventions-0.64b0-py3-none-any.whl.metadata (2.4 kB)\n", - "#9 77.00 Collecting packaging>=18.0 (from opentelemetry-instrumentation==0.64b0->opentelemetry-instrumentation-threading<1.00b0,>=0.51b0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 77.03 Downloading packaging-26.2-py3-none-any.whl.metadata (3.5 kB)\n", - "#9 77.39 Collecting annotated-types>=0.6.0 (from pydantic<3.0.0,>=2.4.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 77.42 Downloading annotated_types-0.7.0-py3-none-any.whl.metadata (15 kB)\n", - "#9 85.08 Collecting pydantic-core==2.46.4 (from pydantic<3.0.0,>=2.4.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 85.11 Downloading pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (6.6 kB)\n", - "#9 85.65 Collecting idna>=2.8 (from anyio>=4.5->mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 85.68 Downloading idna-3.18-py3-none-any.whl.metadata (6.1 kB)\n", - "#9 86.89 Collecting cffi>=2.0.0 (from cryptography>=2.5->azure-identity>=1.15.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", - "#9 86.92 Downloading cffi-2.1.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.metadata (2.5 kB)\n", - "#9 87.23 Collecting certifi (from httpx<1.0.0,>=0.27.1->mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 87.26 Downloading certifi-2026.6.17-py3-none-any.whl.metadata (2.5 kB)\n", - "#9 87.50 Collecting httpcore==1.* (from httpx<1.0.0,>=0.27.1->mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 87.53 Downloading httpcore-1.0.9-py3-none-any.whl.metadata (21 kB)\n", - "#9 87.73 Collecting h11>=0.16 (from httpcore==1.*->httpx<1.0.0,>=0.27.1->mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 87.76 Downloading h11-0.16.0-py3-none-any.whl.metadata (8.3 kB)\n", - "#9 88.02 Collecting h2>=4.3.0 (from hypercorn>=0.17.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 88.06 Downloading h2-4.3.0-py3-none-any.whl.metadata (5.1 kB)\n", - "#9 88.16 Collecting priority (from hypercorn>=0.17.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 88.20 Downloading priority-2.0.0-py3-none-any.whl.metadata (6.6 kB)\n", - "#9 88.32 Collecting wsproto>=0.14.0 (from hypercorn>=0.17.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 88.36 Downloading wsproto-1.3.2-py3-none-any.whl.metadata (5.2 kB)\n", - "#9 88.82 Collecting azure-core-tracing-opentelemetry~=1.0.0b11 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 88.85 Downloading azure_core_tracing_opentelemetry-1.0.0b13-py3-none-any.whl.metadata (11 kB)\n", - "#9 89.08 Collecting azure-monitor-opentelemetry-exporter~=1.0.0b54 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 89.12 Downloading azure_monitor_opentelemetry_exporter-1.0.0b55-py2.py3-none-any.whl.metadata (33 kB)\n", - "#9 89.65 Collecting opentelemetry-exporter-otlp-proto-http~=1.43.0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 89.69 Downloading opentelemetry_exporter_otlp_proto_http-1.43.0-py3-none-any.whl.metadata (2.4 kB)\n", - "#9 90.07 Collecting opentelemetry-instrumentation-django<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 90.10 Downloading opentelemetry_instrumentation_django-0.64b0-py3-none-any.whl.metadata (2.3 kB)\n", - "#9 90.39 Collecting opentelemetry-instrumentation-fastapi<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 90.43 Downloading opentelemetry_instrumentation_fastapi-0.64b0-py3-none-any.whl.metadata (2.2 kB)\n", - "#9 90.71 Collecting opentelemetry-instrumentation-flask<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 90.74 Downloading opentelemetry_instrumentation_flask-0.64b0-py3-none-any.whl.metadata (2.2 kB)\n", - "#9 91.00 Collecting opentelemetry-instrumentation-httpx<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 91.03 Downloading opentelemetry_instrumentation_httpx-0.64b0-py3-none-any.whl.metadata (7.3 kB)\n", - "#9 91.30 Collecting opentelemetry-instrumentation-psycopg2<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 91.34 Downloading opentelemetry_instrumentation_psycopg2-0.64b0-py3-none-any.whl.metadata (2.1 kB)\n", - "#9 91.64 Collecting opentelemetry-instrumentation-requests<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 91.67 Downloading opentelemetry_instrumentation_requests-0.64b0-py3-none-any.whl.metadata (2.6 kB)\n", - "#9 91.95 Collecting opentelemetry-instrumentation-urllib<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 92.00 Downloading opentelemetry_instrumentation_urllib-0.64b0-py3-none-any.whl.metadata (3.4 kB)\n", - "#9 92.31 Collecting opentelemetry-instrumentation-urllib3<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 92.34 Downloading opentelemetry_instrumentation_urllib3-0.64b0-py3-none-any.whl.metadata (4.2 kB)\n", - "#9 92.59 Collecting opentelemetry-instrumentation-logging<0.65b0,>=0.64b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 92.63 Downloading opentelemetry_instrumentation_logging-0.64b0-py3-none-any.whl.metadata (1.9 kB)\n", - "#9 92.83 Collecting opentelemetry-instrumentation-openai-agents-v2==0.1.0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 92.87 Downloading opentelemetry_instrumentation_openai_agents_v2-0.1.0-py3-none-any.whl.metadata (1.3 kB)\n", - "#9 92.98 Collecting opentelemetry-instrumentation-openai-v2==2.3b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 93.03 Downloading opentelemetry_instrumentation_openai_v2-2.3b0-py3-none-any.whl.metadata (5.2 kB)\n", - "#9 93.14 Collecting opentelemetry-resource-detector-azure<1.0.0,>=0.1.5 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 93.17 Downloading opentelemetry_resource_detector_azure-0.1.5-py3-none-any.whl.metadata (5.3 kB)\n", - "#9 93.36 Collecting wrapt<3.0.0,>=1.0.0 (from opentelemetry-instrumentation-threading<1.00b0,>=0.51b0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 93.40 Downloading wrapt-1.17.3-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl.metadata (6.4 kB)\n", - "#9 93.61 Collecting opentelemetry-util-genai==0.3b0 (from microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 93.64 Downloading opentelemetry_util_genai-0.3b0-py3-none-any.whl.metadata (4.6 kB)\n", - "#9 97.09 Collecting six>=1.5 (from python-dateutil<3.0.0,>=2.1->botocore<2.0.0,>=1.29.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 97.12 Downloading six-1.17.0-py2.py3-none-any.whl.metadata (1.7 kB)\n", - "#9 98.80 Collecting charset_normalizer<4,>=2 (from requests>=2.21.0->azure-core>=1.30.0->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 98.86 Downloading charset_normalizer-3.4.9-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (41 kB)\n", - "#9 102.5 Collecting click>=7.0 (from uvicorn>=0.31.1->mcp<2.0.0,>=1.23.0->strands-agents==1.45.0->strands-agents[openai]==1.45.0->-r requirements.txt (line 2))\n", - "#9 102.6 Downloading click-8.4.2-py3-none-any.whl.metadata (2.6 kB)\n", - "#9 103.7 Collecting msrest>=0.6.10 (from azure-monitor-opentelemetry-exporter~=1.0.0b54->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 103.7 Downloading msrest-0.7.1-py3-none-any.whl.metadata (21 kB)\n", - "#9 104.6 Collecting psutil<8,>=5.9 (from azure-monitor-opentelemetry-exporter~=1.0.0b54->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 104.7 Downloading psutil-7.2.2-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl.metadata (22 kB)\n", - "#9 104.9 Collecting pycparser (from cffi>=2.0.0->cryptography>=2.5->azure-identity>=1.15.0->azure-ai-projects==2.3.0->-r requirements.txt (line 4))\n", - "#9 105.0 Downloading pycparser-3.0-py3-none-any.whl.metadata (8.2 kB)\n", - "#9 105.2 Collecting hyperframe<7,>=6.1 (from h2>=4.3.0->hypercorn>=0.17.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 105.3 Downloading hyperframe-6.1.0-py3-none-any.whl.metadata (4.3 kB)\n", - "#9 105.4 Collecting hpack<5,>=4.1 (from h2>=4.3.0->hypercorn>=0.17.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 105.5 Downloading hpack-4.2.0-py3-none-any.whl.metadata (3.3 kB)\n", - "#9 105.8 Collecting googleapis-common-protos~=1.52 (from opentelemetry-exporter-otlp-proto-http~=1.43.0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 105.8 Downloading googleapis_common_protos-1.75.0-py3-none-any.whl.metadata (8.6 kB)\n", - "#9 106.2 Collecting opentelemetry-exporter-otlp-proto-common==1.43.0 (from opentelemetry-exporter-otlp-proto-http~=1.43.0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 106.2 Downloading opentelemetry_exporter_otlp_proto_common-1.43.0-py3-none-any.whl.metadata (1.8 kB)\n", - "#9 106.5 Collecting opentelemetry-proto==1.43.0 (from opentelemetry-exporter-otlp-proto-http~=1.43.0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 106.5 Downloading opentelemetry_proto-1.43.0-py3-none-any.whl.metadata (2.3 kB)\n", - "#9 108.9 Collecting protobuf<8.0,>=5.0 (from opentelemetry-proto==1.43.0->opentelemetry-exporter-otlp-proto-http~=1.43.0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 109.0 Downloading protobuf-7.35.1-cp310-abi3-manylinux2014_x86_64.whl.metadata (595 bytes)\n", - "#9 109.3 Collecting opentelemetry-instrumentation-wsgi==0.64b0 (from opentelemetry-instrumentation-django<0.65b0,>=0.64b0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 109.3 Downloading opentelemetry_instrumentation_wsgi-0.64b0-py3-none-any.whl.metadata (2.1 kB)\n", - "#9 109.6 Collecting opentelemetry-util-http==0.64b0 (from opentelemetry-instrumentation-django<0.65b0,>=0.64b0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 109.6 Downloading opentelemetry_util_http-0.64b0-py3-none-any.whl.metadata (2.6 kB)\n", - "#9 110.0 Collecting opentelemetry-instrumentation-asgi==0.64b0 (from opentelemetry-instrumentation-fastapi<0.65b0,>=0.64b0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 110.0 Downloading opentelemetry_instrumentation_asgi-0.64b0-py3-none-any.whl.metadata (2.0 kB)\n", - "#9 110.4 Collecting asgiref~=3.0 (from opentelemetry-instrumentation-asgi==0.64b0->opentelemetry-instrumentation-fastapi<0.65b0,>=0.64b0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 110.4 Downloading asgiref-3.11.1-py3-none-any.whl.metadata (9.3 kB)\n", - "#9 110.9 Collecting opentelemetry-instrumentation-dbapi==0.64b0 (from opentelemetry-instrumentation-psycopg2<0.65b0,>=0.64b0->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 110.9 Downloading opentelemetry_instrumentation_dbapi-0.64b0-py3-none-any.whl.metadata (2.0 kB)\n", - "#9 112.3 Collecting requests-oauthlib>=0.5.0 (from msrest>=0.6.10->azure-monitor-opentelemetry-exporter~=1.0.0b54->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 112.3 Downloading requests_oauthlib-2.0.0-py2.py3-none-any.whl.metadata (11 kB)\n", - "#9 113.2 Collecting oauthlib>=3.0.0 (from requests-oauthlib>=0.5.0->msrest>=0.6.10->azure-monitor-opentelemetry-exporter~=1.0.0b54->microsoft-opentelemetry>=1.0.0->azure-ai-agentserver-core>=2.0.0b7->azure-ai-agentserver-responses==1.0.0b8->-r requirements.txt (line 1))\n", - "#9 113.3 Downloading oauthlib-3.3.1-py3-none-any.whl.metadata (7.9 kB)\n", - "#9 113.5 Downloading azure_ai_agentserver_responses-1.0.0b8-py3-none-any.whl (269 kB)\n", - "#9 113.5 Downloading strands_agents-1.45.0-py3-none-any.whl (579 kB)\n", - "#9 113.6 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 579.3/579.3 kB 10.4 MB/s eta 0:00:00\n", - "#9 113.6 Downloading azure_ai_projects-2.3.0-py3-none-any.whl (349 kB)\n", - "#9 113.7 Downloading python_dotenv-1.2.2-py3-none-any.whl (22 kB)\n", - "#9 113.8 Downloading aiohttp-3.14.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (1.8 MB)\n", - "#9 113.9 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.8/1.8 MB 19.4 MB/s eta 0:00:00\n", - "#9 113.9 Downloading aws_bedrock_token_generator-1.1.0-py3-none-any.whl (10 kB)\n", - "#9 114.0 Downloading azure_ai_agentserver_core-2.0.0b7-py3-none-any.whl (35 kB)\n", - "#9 114.0 Downloading azure_core-1.41.0-py3-none-any.whl (220 kB)\n", - "#9 114.1 Downloading azure_identity-1.25.3-py3-none-any.whl (192 kB)\n", - "#9 114.1 Downloading azure_storage_blob-12.30.0-py3-none-any.whl (435 kB)\n", - "#9 114.2 Downloading boto3-1.43.44-py3-none-any.whl (140 kB)\n", - "#9 114.3 Downloading botocore-1.43.44-py3-none-any.whl (15.4 MB)\n", - "#9 115.1 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 15.4/15.4 MB 18.4 MB/s eta 0:00:00\n", - "#9 115.2 Downloading docstring_parser-0.18.0-py3-none-any.whl (22 kB)\n", - "#9 115.2 Downloading isodate-0.7.2-py3-none-any.whl (22 kB)\n", - "#9 115.2 Downloading jsonschema-4.26.0-py3-none-any.whl (90 kB)\n", - "#9 115.3 Downloading mcp-1.28.1-py3-none-any.whl (222 kB)\n", - "#9 115.4 Downloading openai-2.44.0-py3-none-any.whl (1.4 MB)\n", - "#9 115.4 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.4/1.4 MB 20.5 MB/s eta 0:00:00\n", - "#9 115.5 Downloading opentelemetry_api-1.43.0-py3-none-any.whl (61 kB)\n", - "#9 115.5 Downloading opentelemetry_instrumentation_threading-0.64b0-py3-none-any.whl (8.5 kB)\n", - "#9 115.6 Downloading opentelemetry_instrumentation-0.64b0-py3-none-any.whl (35 kB)\n", - "#9 115.6 Downloading opentelemetry_semantic_conventions-0.64b0-py3-none-any.whl (203 kB)\n", - "#9 115.7 Downloading opentelemetry_sdk-1.43.0-py3-none-any.whl (178 kB)\n", - "#9 115.8 Downloading pydantic-2.13.4-py3-none-any.whl (472 kB)\n", - "#9 115.8 Downloading pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.1 MB)\n", - "#9 116.0 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2.1/2.1 MB 16.3 MB/s eta 0:00:00\n", - "#9 116.0 Downloading pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (807 kB)\n", - "#9 116.1 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 807.9/807.9 kB 15.7 MB/s eta 0:00:00\n", - "#9 116.1 Downloading typing_extensions-4.16.0-py3-none-any.whl (45 kB)\n", - "#9 116.1 Downloading watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl (79 kB)\n", - "#9 116.2 Downloading aiohappyeyeballs-2.7.1-py3-none-any.whl (15 kB)\n", - "#9 116.3 Downloading aiosignal-1.4.0-py3-none-any.whl (7.5 kB)\n", - "#9 116.3 Downloading annotated_types-0.7.0-py3-none-any.whl (13 kB)\n", - "#9 116.4 Downloading anyio-4.14.1-py3-none-any.whl (124 kB)\n", - "#9 116.4 Downloading attrs-26.1.0-py3-none-any.whl (67 kB)\n", - "#9 116.5 Downloading cryptography-49.0.0-cp311-abi3-manylinux_2_34_x86_64.whl (4.7 MB)\n", - "#9 116.8 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 4.7/4.7 MB 16.2 MB/s eta 0:00:00\n", - "#9 116.8 Downloading distro-1.9.0-py3-none-any.whl (20 kB)\n", - "#9 116.9 Downloading frozenlist-1.8.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl (242 kB)\n", - "#9 117.0 Downloading httpx-0.28.1-py3-none-any.whl (73 kB)\n", - "#9 117.0 Downloading httpcore-1.0.9-py3-none-any.whl (78 kB)\n", - "#9 117.1 Downloading httpx_sse-0.4.3-py3-none-any.whl (9.0 kB)\n", - "#9 117.1 Downloading hypercorn-0.18.0-py3-none-any.whl (61 kB)\n", - "#9 117.2 Downloading jiter-0.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (343 kB)\n", - "#9 117.2 Downloading jmespath-1.1.0-py3-none-any.whl (20 kB)\n", - "#9 117.3 Downloading jsonschema_specifications-2025.9.1-py3-none-any.whl (18 kB)\n", - "#9 117.4 Downloading microsoft_opentelemetry-1.3.5-py3-none-any.whl (208 kB)\n", - "#9 117.4 Downloading opentelemetry_instrumentation_openai_agents_v2-0.1.0-py3-none-any.whl (25 kB)\n", - "#9 117.5 Downloading opentelemetry_instrumentation_openai_v2-2.3b0-py3-none-any.whl (18 kB)\n", - "#9 117.6 Downloading opentelemetry_util_genai-0.3b0-py3-none-any.whl (28 kB)\n", - "#9 117.6 Downloading msal-1.37.0-py3-none-any.whl (123 kB)\n", - "#9 117.7 Downloading msal_extensions-1.3.1-py3-none-any.whl (20 kB)\n", - "#9 117.7 Downloading multidict-6.7.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (256 kB)\n", - "#9 117.8 Downloading propcache-0.5.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (61 kB)\n", - "#9 117.9 Downloading pydantic_settings-2.14.2-py3-none-any.whl (61 kB)\n", - "#9 117.9 Downloading pyjwt-2.13.0-py3-none-any.whl (31 kB)\n", - "#9 117.9 Downloading python_dateutil-2.9.0.post0-py2.py3-none-any.whl (229 kB)\n", - "#9 118.0 Downloading python_multipart-0.0.32-py3-none-any.whl (30 kB)\n", - "#9 118.1 Downloading referencing-0.37.0-py3-none-any.whl (26 kB)\n", - "#9 118.1 Downloading requests-2.34.2-py3-none-any.whl (73 kB)\n", - "#9 118.2 Downloading rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (366 kB)\n", - "#9 118.2 Downloading s3transfer-0.19.0-py3-none-any.whl (90 kB)\n", - "#9 118.3 Downloading sse_starlette-3.4.5-py3-none-any.whl (16 kB)\n", - "#9 118.3 Downloading starlette-1.3.1-py3-none-any.whl (73 kB)\n", - "#9 118.4 Downloading tqdm-4.68.4-py3-none-any.whl (676 kB)\n", - "#9 118.4 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 676.6/676.6 kB 15.0 MB/s eta 0:00:00\n", - "#9 118.5 Downloading typing_inspection-0.4.2-py3-none-any.whl (14 kB)\n", - "#9 118.5 Downloading urllib3-2.7.0-py3-none-any.whl (131 kB)\n", - "#9 118.6 Downloading uvicorn-0.51.0-py3-none-any.whl (73 kB)\n", - "#9 118.6 Downloading wrapt-1.17.3-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl (88 kB)\n", - "#9 118.7 Downloading yarl-1.24.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (105 kB)\n", - "#9 118.8 Downloading sniffio-1.3.1-py3-none-any.whl (10 kB)\n", - "#9 118.8 Downloading azure_core_tracing_opentelemetry-1.0.0b13-py3-none-any.whl (12 kB)\n", - "#9 118.9 Downloading azure_monitor_opentelemetry_exporter-1.0.0b55-py2.py3-none-any.whl (251 kB)\n", - "#9 119.0 Downloading certifi-2026.6.17-py3-none-any.whl (133 kB)\n", - "#9 119.0 Downloading cffi-2.1.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (221 kB)\n", - "#9 119.1 Downloading charset_normalizer-3.4.9-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (224 kB)\n", - "#9 119.2 Downloading click-8.4.2-py3-none-any.whl (119 kB)\n", - "#9 119.2 Downloading h11-0.16.0-py3-none-any.whl (37 kB)\n", - "#9 119.3 Downloading h2-4.3.0-py3-none-any.whl (61 kB)\n", - "#9 119.4 Downloading idna-3.18-py3-none-any.whl (65 kB)\n", - "#9 119.4 Downloading opentelemetry_exporter_otlp_proto_http-1.43.0-py3-none-any.whl (21 kB)\n", - "#9 119.5 Downloading opentelemetry_exporter_otlp_proto_common-1.43.0-py3-none-any.whl (17 kB)\n", - "#9 119.5 Downloading opentelemetry_proto-1.43.0-py3-none-any.whl (72 kB)\n", - "#9 119.6 Downloading opentelemetry_instrumentation_django-0.64b0-py3-none-any.whl (18 kB)\n", - "#9 119.7 Downloading opentelemetry_instrumentation_wsgi-0.64b0-py3-none-any.whl (13 kB)\n", - "#9 119.7 Downloading opentelemetry_util_http-0.64b0-py3-none-any.whl (8.2 kB)\n", - "#9 119.8 Downloading opentelemetry_instrumentation_fastapi-0.64b0-py3-none-any.whl (13 kB)\n", - "#9 119.8 Downloading opentelemetry_instrumentation_asgi-0.64b0-py3-none-any.whl (15 kB)\n", - "#9 119.9 Downloading opentelemetry_instrumentation_flask-0.64b0-py3-none-any.whl (15 kB)\n", - "#9 119.9 Downloading opentelemetry_instrumentation_httpx-0.64b0-py3-none-any.whl (16 kB)\n", - "#9 120.0 Downloading opentelemetry_instrumentation_logging-0.64b0-py3-none-any.whl (16 kB)\n", - "#9 120.0 Downloading opentelemetry_instrumentation_psycopg2-0.64b0-py3-none-any.whl (10 kB)\n", - "#9 120.1 Downloading opentelemetry_instrumentation_dbapi-0.64b0-py3-none-any.whl (14 kB)\n", - "#9 120.1 Downloading opentelemetry_instrumentation_requests-0.64b0-py3-none-any.whl (13 kB)\n", - "#9 120.2 Downloading opentelemetry_instrumentation_urllib-0.64b0-py3-none-any.whl (13 kB)\n", - "#9 120.2 Downloading opentelemetry_instrumentation_urllib3-0.64b0-py3-none-any.whl (13 kB)\n", - "#9 120.3 Downloading opentelemetry_resource_detector_azure-0.1.5-py3-none-any.whl (14 kB)\n", - "#9 120.3 Downloading packaging-26.2-py3-none-any.whl (100 kB)\n", - "#9 120.4 Downloading six-1.17.0-py2.py3-none-any.whl (11 kB)\n", - "#9 120.4 Downloading wsproto-1.3.2-py3-none-any.whl (24 kB)\n", - "#9 120.5 Downloading priority-2.0.0-py3-none-any.whl (8.9 kB)\n", - "#9 120.5 Downloading googleapis_common_protos-1.75.0-py3-none-any.whl (300 kB)\n", - "#9 120.6 Downloading hpack-4.2.0-py3-none-any.whl (34 kB)\n", - "#9 120.7 Downloading hyperframe-6.1.0-py3-none-any.whl (13 kB)\n", - "#9 120.7 Downloading msrest-0.7.1-py3-none-any.whl (85 kB)\n", - "#9 120.8 Downloading psutil-7.2.2-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl (155 kB)\n", - "#9 120.8 Downloading pycparser-3.0-py3-none-any.whl (48 kB)\n", - "#9 120.9 Downloading asgiref-3.11.1-py3-none-any.whl (24 kB)\n", - "#9 120.9 Downloading protobuf-7.35.1-cp310-abi3-manylinux2014_x86_64.whl (327 kB)\n", - "#9 121.0 Downloading requests_oauthlib-2.0.0-py2.py3-none-any.whl (24 kB)\n", - "#9 121.1 Downloading oauthlib-3.3.1-py3-none-any.whl (160 kB)\n", - "#9 125.1 Installing collected packages: wrapt, watchdog, urllib3, typing-extensions, tqdm, sniffio, six, rpds-py, pyyaml, python-multipart, python-dotenv, pyjwt, pycparser, psutil, protobuf, propcache, priority, packaging, opentelemetry-util-http, oauthlib, multidict, jmespath, jiter, isodate, idna, hyperframe, httpx-sse, hpack, h11, frozenlist, docstring-parser, distro, click, charset_normalizer, certifi, attrs, asgiref, annotated-types, aiohappyeyeballs, yarl, wsproto, uvicorn, typing-inspection, requests, referencing, python-dateutil, pydantic-core, opentelemetry-proto, opentelemetry-api, httpcore, h2, googleapis-common-protos, cffi, anyio, aiosignal, starlette, requests-oauthlib, pydantic, opentelemetry-semantic-conventions, opentelemetry-exporter-otlp-proto-common, jsonschema-specifications, hypercorn, httpx, cryptography, botocore, azure-core, aiohttp, sse-starlette, s3transfer, pydantic-settings, opentelemetry-sdk, opentelemetry-instrumentation, openai, msrest, jsonschema, azure-storage-blob, azure-core-tracing-opentelemetry, aws-bedrock-token-generator, opentelemetry-util-genai, opentelemetry-resource-detector-azure, opentelemetry-instrumentation-wsgi, opentelemetry-instrumentation-urllib3, opentelemetry-instrumentation-urllib, opentelemetry-instrumentation-threading, opentelemetry-instrumentation-requests, opentelemetry-instrumentation-openai-v2, opentelemetry-instrumentation-logging, opentelemetry-instrumentation-httpx, opentelemetry-instrumentation-dbapi, opentelemetry-instrumentation-asgi, opentelemetry-exporter-otlp-proto-http, msal, mcp, boto3, strands-agents, opentelemetry-instrumentation-psycopg2, opentelemetry-instrumentation-openai-agents-v2, opentelemetry-instrumentation-flask, opentelemetry-instrumentation-fastapi, opentelemetry-instrumentation-django, msal-extensions, azure-identity, azure-monitor-opentelemetry-exporter, azure-ai-projects, microsoft-opentelemetry, azure-ai-agentserver-core, azure-ai-agentserver-responses\n", - "#9 202.1 Successfully installed aiohappyeyeballs-2.7.1 aiohttp-3.14.1 aiosignal-1.4.0 annotated-types-0.7.0 anyio-4.14.1 asgiref-3.11.1 attrs-26.1.0 aws-bedrock-token-generator-1.1.0 azure-ai-agentserver-core-2.0.0b7 azure-ai-agentserver-responses-1.0.0b8 azure-ai-projects-2.3.0 azure-core-1.41.0 azure-core-tracing-opentelemetry-1.0.0b13 azure-identity-1.25.3 azure-monitor-opentelemetry-exporter-1.0.0b55 azure-storage-blob-12.30.0 boto3-1.43.44 botocore-1.43.44 certifi-2026.6.17 cffi-2.1.0 charset_normalizer-3.4.9 click-8.4.2 cryptography-49.0.0 distro-1.9.0 docstring-parser-0.18.0 frozenlist-1.8.0 googleapis-common-protos-1.75.0 h11-0.16.0 h2-4.3.0 hpack-4.2.0 httpcore-1.0.9 httpx-0.28.1 httpx-sse-0.4.3 hypercorn-0.18.0 hyperframe-6.1.0 idna-3.18 isodate-0.7.2 jiter-0.16.0 jmespath-1.1.0 jsonschema-4.26.0 jsonschema-specifications-2025.9.1 mcp-1.28.1 microsoft-opentelemetry-1.3.5 msal-1.37.0 msal-extensions-1.3.1 msrest-0.7.1 multidict-6.7.1 oauthlib-3.3.1 openai-2.44.0 opentelemetry-api-1.43.0 opentelemetry-exporter-otlp-proto-common-1.43.0 opentelemetry-exporter-otlp-proto-http-1.43.0 opentelemetry-instrumentation-0.64b0 opentelemetry-instrumentation-asgi-0.64b0 opentelemetry-instrumentation-dbapi-0.64b0 opentelemetry-instrumentation-django-0.64b0 opentelemetry-instrumentation-fastapi-0.64b0 opentelemetry-instrumentation-flask-0.64b0 opentelemetry-instrumentation-httpx-0.64b0 opentelemetry-instrumentation-logging-0.64b0 opentelemetry-instrumentation-openai-agents-v2-0.1.0 opentelemetry-instrumentation-openai-v2-2.3b0 opentelemetry-instrumentation-psycopg2-0.64b0 opentelemetry-instrumentation-requests-0.64b0 opentelemetry-instrumentation-threading-0.64b0 opentelemetry-instrumentation-urllib-0.64b0 opentelemetry-instrumentation-urllib3-0.64b0 opentelemetry-instrumentation-wsgi-0.64b0 opentelemetry-proto-1.43.0 opentelemetry-resource-detector-azure-0.1.5 opentelemetry-sdk-1.43.0 opentelemetry-semantic-conventions-0.64b0 opentelemetry-util-genai-0.3b0 opentelemetry-util-http-0.64b0 packaging-26.2 priority-2.0.0 propcache-0.5.2 protobuf-7.35.1 psutil-7.2.2 pycparser-3.0 pydantic-2.13.4 pydantic-core-2.46.4 pydantic-settings-2.14.2 pyjwt-2.13.0 python-dateutil-2.9.0.post0 python-dotenv-1.2.2 python-multipart-0.0.32 pyyaml-6.0.3 referencing-0.37.0 requests-2.34.2 requests-oauthlib-2.0.0 rpds-py-2026.6.3 s3transfer-0.19.0 six-1.17.0 sniffio-1.3.1 sse-starlette-3.4.5 starlette-1.3.1 strands-agents-1.45.0 tqdm-4.68.4 typing-extensions-4.16.0 typing-inspection-0.4.2 urllib3-2.7.0 uvicorn-0.51.0 watchdog-6.0.0 wrapt-1.17.3 wsproto-1.3.2 yarl-1.24.2\n", - "#9 202.1 WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager, possibly rendering your system unusable. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv. Use the --root-user-action option if you know what you are doing and want to suppress this warning.\n", - "#9 203.0 \n", - "#9 203.0 [notice] A new release of pip is available: 25.0.1 -> 26.1.2\n", - "#9 203.0 [notice] To update, run: pip install --upgrade pip\n", - "#9 DONE 204.6s\n", - "\n", - "#10 exporting to image\n", - "#10 exporting layers\n", - "#10 exporting layers 6.2s done\n", - "#10 exporting manifest sha256:6e66f34839f2d439deecd9b72f3eab9407391d7100f64d6e9cb38e5464dcb708 0.0s done\n", - "#10 exporting config sha256:0b0004e7fa124d2dd03d23878212de60a777d40947368474544907c14bd89f88 0.0s done\n", - "#10 exporting attestation manifest sha256:a59b4b305d17be987ca52477626cae41ed02c66346e7ae4ecc47c759946675f6 0.0s done\n", - "#10 exporting manifest list sha256:3fc11d28ec016df6b53b0c3f262c4592a8b3aa2021b670962f5d77eee0ba9725 0.0s done\n", - "#10 naming to acryxz4ztnhs2gd4.azurecr.io/strands-agent:1.0.0 done\n", - "#10 DONE 6.4s\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "The push refers to repository [acryxz4ztnhs2gd4.azurecr.io/strands-agent]\n", - "020b426aa498: Waiting\n", - "69ecc8fe6c93: Waiting\n", - "df79d931cd67: Waiting\n", - "4f4fb700ef54: Waiting\n", - "e95a6c7ea7d4: Waiting\n", - "5448f2dea2bc: Waiting\n", - "d60f381e3e0c: Waiting\n", - "b32430367bf0: Waiting\n", - "aff2d9f8dc87: Waiting\n", - "020b426aa498: Waiting\n", - "69ecc8fe6c93: Waiting\n", - "df79d931cd67: Waiting\n", - "4f4fb700ef54: Waiting\n", - "e95a6c7ea7d4: Waiting\n", - "5448f2dea2bc: Waiting\n", - "d60f381e3e0c: Waiting\n", - "b32430367bf0: Waiting\n", - "aff2d9f8dc87: Waiting\n", - "5448f2dea2bc: Waiting\n", - "d60f381e3e0c: Waiting\n", - "b32430367bf0: Waiting\n", - "aff2d9f8dc87: Waiting\n", - "020b426aa498: Waiting\n", - "69ecc8fe6c93: Waiting\n", - "df79d931cd67: Waiting\n", - "4f4fb700ef54: Waiting\n", - "e95a6c7ea7d4: Waiting\n", - "5448f2dea2bc: Waiting\n", - "d60f381e3e0c: Waiting\n", - "b32430367bf0: Waiting\n", - "aff2d9f8dc87: Waiting\n", - "020b426aa498: Waiting\n", - "69ecc8fe6c93: Waiting\n", - "df79d931cd67: Waiting\n", - "4f4fb700ef54: Waiting\n", - "e95a6c7ea7d4: Waiting\n", - "4f4fb700ef54: Waiting\n", - "e95a6c7ea7d4: Waiting\n", - "5448f2dea2bc: Waiting\n", - "d60f381e3e0c: Waiting\n", - "b32430367bf0: Waiting\n", - "aff2d9f8dc87: Waiting\n", - "020b426aa498: Waiting\n", - "69ecc8fe6c93: Waiting\n", - "df79d931cd67: Waiting\n", - "020b426aa498: Waiting\n", - "69ecc8fe6c93: Waiting\n", - "df79d931cd67: Waiting\n", - "4f4fb700ef54: Waiting\n", - "e95a6c7ea7d4: Waiting\n", - "5448f2dea2bc: Waiting\n", - "d60f381e3e0c: Waiting\n", - "b32430367bf0: Waiting\n", - "aff2d9f8dc87: Waiting\n", - "69ecc8fe6c93: Waiting\n", - "df79d931cd67: Waiting\n", - "e95a6c7ea7d4: Waiting\n", - "5448f2dea2bc: Waiting\n", - "d60f381e3e0c: Waiting\n", - "b32430367bf0: Waiting\n", - "aff2d9f8dc87: Waiting\n", - "020b426aa498: Pushed\n", - "b32430367bf0: Pushed\n", - "4f4fb700ef54: Pushed\n", - "5448f2dea2bc: Pushed\n", - "d60f381e3e0c: Pushed\n", - "aff2d9f8dc87: Pushed\n", - "df79d931cd67: Pushed\n", - "e95a6c7ea7d4: Pushed\n", - "69ecc8fe6c93: Pushed\n", - "1.0.0: digest: sha256:3fc11d28ec016df6b53b0c3f262c4592a8b3aa2021b670962f5d77eee0ba9725 size: 856\n", - "Docker build and push completed successfully.\n" - ] - } - ], - "source": [ - "\n", - "# Use Docker directly from the notebook\n", - "print(f\"Running: docker build -t {IMAGE_URI} .\")\n", - "!docker build -t {IMAGE_URI} --platform linux/amd64 .\n", - "\n", - "print(f\"Running: docker push {IMAGE_URI}\")\n", - "!docker push {IMAGE_URI}\n", - "\n", - "print(\"Docker build and push completed successfully.\")" - ] - }, - { - "cell_type": "markdown", - "id": "09b0c0cc", - "metadata": {}, - "source": [ - "### Build and push your container\n", - "\n", - "This builds the Strands agent Docker image and pushes it to your ACR. The `--platform linux/amd64` flag ensures the image is compatible with Foundry's Linux-based container hosting.\n", - "\n", - "After pushing, your image will be available at `{ACR_LOGIN_SERVER}/strands-agent:1.0.0` for Foundry to pull and deploy." - ] - }, - { - "cell_type": "markdown", - "id": "20f53916", - "metadata": {}, - "source": [ - "## 2. Create Hosted Agent Version\n", - "\n", - "This section creates your Strands agent as a **Foundry Hosted Agent** using the Responses protocol v1.0.0.\n", - "\n", - "### Important notes\n", - "\n", - "- **Agent name**: Choose any name you want (e.g., `strands-agent`, `my-agent`, etc.). \n", - " - Foundry auto-assigns the version suffix (`:1`, `:2`, etc.) when you create versions\n", - " - This name will be used in the APIM URL path to invoke the agent: `/agents/{agentName}/endpoint/protocols/openai/responses`\n", - "\n", - "- **Model endpoint**: Uses APIM **inference** API for model calls (`https://apim-{suffix}.azure-api.net/inference/models`), not the hosted-agent API.\n", - "\n", - "- **Dependencies**: Install `azure-ai-projects` and `azure-identity` to interact with Foundry APIs.\n", - "\n", - "After creation, your agent will transition through status changes. Once it reaches \"Running\", it's ready to accept requests in sections 3 and 4." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cca00471", - "metadata": {}, - "outputs": [], - "source": [ - "pip install azure-ai-projects==2.3.0 --force-reinstall --no-cache-dir" - ] - }, - { - "cell_type": "markdown", - "id": "2c7efedf", - "metadata": {}, - "source": [ - "### Create the hosted agent in Foundry\n", - "\n", - "This cell deploys your Strands container as a **Hosted Agent** in your Foundry project. \n", - "\n", - "**Key configuration:**\n", - "- **Protocol**: Responses v1.0.0 (standard for Foundry hosted agents)\n", - "- **Resources**: 1 CPU, 2Gi memory (adjust based on your agent needs)\n", - "- **Environment variables**: \n", - " - `AZURE_OPENAI_ENDPOINT`: Points to APIM inference API for your agent to call models\n", - " - `APIM_SUBSCRIPTION_KEY`: APIM subscription key for authentication\n", - " - `AZURE_OPENAI_DEPLOYMENT`: Model name to use (e.g., `gpt-5-mini`)\n", - "\n", - "The agent will be created with a version suffix (auto-assigned by Foundry). After creation, it transitions to \"Running\" state and is ready to accept requests via the Responses API." - ] - }, - { - "cell_type": "code", - "execution_count": 65, - "id": "89e98ee4", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "PROJECT_ENDPOINT: https://foundry-agents-yxz4ztnhs2gd4.services.ai.azure.com/api/projects/default-foundry-agents\n", - "AGENT_NAME: strands-agent2\n", - "Agent created: strands-agent2, version: 1, id strands-agent2:1\n" - ] - } - ], - "source": [ - "from azure.ai.projects import AIProjectClient\n", - "from azure.ai.projects.models import (\n", - " HostedAgentDefinition,\n", - " ProtocolVersionRecord,\n", - " AgentEndpointProtocol,\n", - " ContainerConfiguration,\n", - " )\n", - "from azure.identity import DefaultAzureCredential, AzureCliCredential\n", - "\n", - "# Placeholder values - update before running\n", - "PROJECT_ENDPOINT = \"https://foundry-agents-yxz4ztnhs2gd4.services.ai.azure.com/api/projects/default-foundry-agents\"\n", - "AGENT_NAME = \"strands-agent2\"\n", - "\n", - "# APIM inference endpoint for model calls.\n", - "AZURE_OPENAI_ENDPOINT = \"https://apim-yxz4ztnhs2gd4.azure-api.net/inference/models\"\n", - "AZURE_OPENAI_API_VERSION = \"2024-05-01-preview\"\n", - "AZURE_OPENAI_DEPLOYMENT = \"gpt-5-mini\"\n", - "APIM_SUBSCRIPTION_KEY = \"d758c99aca6b4231980d5c0ff6917c59\"\n", - "\n", - "print(f\"PROJECT_ENDPOINT: {PROJECT_ENDPOINT}\")\n", - "print(f\"AGENT_NAME: {AGENT_NAME}\")\n", - "\n", - "credential = AzureCliCredential()\n", - "\n", - "project = AIProjectClient(\n", - " endpoint=PROJECT_ENDPOINT,\n", - " credential=credential,\n", - " allow_preview=True,\n", - ")\n", - "\n", - "agent = project.agents.create_version(\n", - " agent_name=AGENT_NAME,\n", - " definition=HostedAgentDefinition(\n", - " protocol_versions=[\n", - " ProtocolVersionRecord(protocol=AgentEndpointProtocol.RESPONSES, version=\"1.0.0\")\n", - " ],\n", - " cpu=\"1\",\n", - " memory=\"2Gi\",\n", - " container_configuration=ContainerConfiguration(image=IMAGE_URI),\n", - " environment_variables={\n", - " \"AZURE_OPENAI_ENDPOINT\": AZURE_OPENAI_ENDPOINT,\n", - " \"AZURE_OPENAI_API_VERSION\": AZURE_OPENAI_API_VERSION,\n", - " \"AZURE_OPENAI_DEPLOYMENT\": AZURE_OPENAI_DEPLOYMENT,\n", - " \"APIM_SUBSCRIPTION_KEY\": APIM_SUBSCRIPTION_KEY,\n", - " \"LOG_LEVEL\": \"INFO\",\n", - " \"STRANDS_LOG_LEVEL\": \"INFO\",\n", - " },\n", - " ),\n", - " )\n", - "\n", - "print(f\"Agent created: {agent.name}, version: {agent.version}, id {agent.id}\")" - ] - }, - { - "cell_type": "markdown", - "id": "faaf591d", - "metadata": {}, - "source": [ - "## 3. Test The Hosted Agent (Direct)\n", - "\n", - "**Purpose:** Validate your agent works by calling the Foundry Responses API directly using your Azure CLI credential.\n", - "\n", - "This is your baseline test—if this fails, APIM proxy tests will also fail. Use this to confirm:\n", - "- Agent reached \"Running\" status ✅\n", - "- Network connectivity to Foundry is working ✅\n", - "- Authentication with your credential works ✅\n", - "- Agent payload format is correct ✅\n", - "\n", - "**How it works:**\n", - "- Endpoint: `{PROJECT_ENDPOINT}/agents/{AGENT_NAME}/endpoint/protocols/openai/responses?api-version=v1`\n", - "- Auth: Bearer token with `https://ai.azure.com/.default` audience (from your Azure CLI login)\n", - "- Headers: Includes `Foundry-Features: HostedAgents=V1Preview` (required for preview access)\n", - "\n", - "If this test succeeds, you know the agent itself is working correctly." - ] - }, - { - "cell_type": "code", - "execution_count": 66, - "id": "93be92da", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "POST https://foundry-agents-yxz4ztnhs2gd4.services.ai.azure.com/api/projects/default-foundry-agents/agents/strands-agent2/endpoint/protocols/openai/responses?api-version=v1\n", - "Agent Name: strands-agent2\n", - "Payload: {\n", - " \"input\": \"Hello! What can you help me with? What's the weather in Paris today?\",\n", - " \"stream\": false\n", - "}\n", - "\n", - "Status: 200\n", - "Headers: {'Content-Length': '1215', 'Content-Type': 'application/json', 'content-encoding': 'identity', 'request-context': 'appId=', 'x-ms-response-type': 'standard', 'x-request-id': '29b495c75664973add72be850196fe06,29b495c75664973add72be850196fe06', 'api-supported-versions': '1.0,2025-05-15-preview,2025-11-15-preview', 'x-agent-session-id': '22a21b2cf5f64e1a7fff8e75bcf6d488e5127d871ed888fcdd9905317fd6068', 'x-platform-server': 'azure-ai-agentserver-core/2.0.0b7 (python/3.12) azure-ai-agentserver-responses/1.0.0b8 (python/3.12)', 'azureml-served-by-cluster': 'hyena-swedencentral-02', 'apim-request-id': 'eac7dff9-7f81-434f-8db0-cc29f5a04c4a', 'Strict-Transport-Security': 'max-age=31536000; includeSubDomains; preload', 'x-content-type-options': 'nosniff', 'x-ms-region': 'Sweden Central', 'Access-Control-Expose-Headers': 'Operation-Location,Location,Apim-Request-Id,x-agent-session-id,x-agent-invocation-id', 'Date': 'Thu, 09 Jul 2026 12:02:02 GMT'}\n", - "Response text (first 500 chars): {\"id\":\"caresp_238be47fdb64c77100zdjo2jUZYlUk52TtiUhT2zARN3LhiQuI\",\"object\":\"response\",\"output\":[{\"type\":\"message\",\"id\":\"msg_238be47fdb64c77100lYxe4zTgvtBmOS3p08emUKpObYutwfil\",\"role\":\"assistant\",\"content\":[{\"type\":\"output_text\",\"text\":\"Hi — I can help with questions, explanations, writing/editing, code, calculations, planning, translations, summarizing text, troubleshooting, and more. I can also look up current weather, convert units, or fetch other data when available.\\n\\nCurrent weather in Par\n", - "\n", - "Response JSON:\n", - "{\n", - " \"id\": \"caresp_238be47fdb64c77100zdjo2jUZYlUk52TtiUhT2zARN3LhiQuI\",\n", - " \"object\": \"response\",\n", - " \"output\": [\n", - " {\n", - " \"type\": \"message\",\n", - " \"id\": \"msg_238be47fdb64c77100lYxe4zTgvtBmOS3p08emUKpObYutwfil\",\n", - " \"role\": \"assistant\",\n", - " \"content\": [\n", - " {\n", - " \"type\": \"output_text\",\n", - " \"text\": \"Hi \\u2014 I can help with questions, explanations, writing/editing, code, calculations, planning, translations, summarizing text, troubleshooting, and more. I can also look up current weather, convert units, or fetch other data when available.\\n\\nCurrent weather in Paris: 12\\u00b0C (about 53.6\\u00b0F). That\\u2019s fairly cool \\u2014 you might want a light jacket. Would you like a forecast, chance of rain, or humidity/wind information?\",\n", - " \"annotations\": [],\n", - " \"logprobs\": []\n", - " }\n", - " ],\n", - " \"status\": \"completed\",\n", - " \"response_id\": \"caresp_238be47fdb64c77100zdjo2jUZYlUk52TtiUhT2zARN3LhiQuI\",\n", - " \"agent_reference\": {\n", - " \"type\": \"agent_reference\",\n", - " \"name\": \"strands-agent2\",\n", - " \"version\": \"1\"\n", - " }\n", - " }\n", - " ],\n", - " \"created_at\": 1783598516,\n", - " \"agent_reference\": {\n", - " \"type\": \"agent_reference\",\n", - " \"name\": \"strands-agent2\",\n", - " \"version\": \"1\"\n", - " },\n", - " \"status\": \"completed\",\n", - " \"completed_at\": 1783598523,\n", - " \"response_id\": \"caresp_238be47fdb64c77100zdjo2jUZYlUk52TtiUhT2zARN3LhiQuI\",\n", - " \"model\": \"\",\n", - " \"agent_session_id\": \"22a21b2cf5f64e1a7fff8e75bcf6d488e5127d871ed888fcdd9905317fd6068\",\n", - " \"background\": false\n", - "}\n" - ] - } - ], - "source": [ - "import json\n", - "import requests\n", - "from azure.core.credentials import AccessToken\n", - "\n", - "# Correct endpoint for Responses protocol (per Microsoft Learn)\n", - "API_VERSION = \"v1\"\n", - "\n", - "# Build the correct URL: use agent name only (not name:version)\n", - "url = f\"{PROJECT_ENDPOINT}/agents/{AGENT_NAME}/endpoint/protocols/openai/responses\"\n", - "\n", - "# Get a token for Foundry Responses API\n", - "token: AccessToken = credential.get_token(\"https://ai.azure.com/.default\")\n", - "\n", - "headers = {\n", - " \"Authorization\": f\"Bearer {token.token}\",\n", - " \"Content-Type\": \"application/json\",\n", - " \"Foundry-Features\": \"HostedAgents=V1Preview\", # Required for preview\n", - "}\n", - "\n", - "payload = {\n", - " \"input\": \"Hello! What can you help me with? What's the weather in Paris today?\",\n", - " \"stream\": False,\n", - "}\n", - "\n", - "print(f\"POST {url}?api-version={API_VERSION}\")\n", - "print(f\"Agent Name: {AGENT_NAME}\")\n", - "print(f\"Payload: {json.dumps(payload, indent=2)}\")\n", - "print()\n", - "\n", - "response = requests.post(url, headers=headers, json=payload, params={\"api-version\": API_VERSION})\n", - "print(f\"Status: {response.status_code}\")\n", - "print(f\"Headers: {dict(response.headers)}\")\n", - "print(f\"Response text (first 500 chars): {response.text[:500]}\")\n", - "print()\n", - "\n", - "if response.status_code == 200:\n", - " try:\n", - " result = response.json()\n", - " print(f\"Response JSON:\")\n", - " print(json.dumps(result, indent=2))\n", - " if \"output_text\" in result:\n", - " print(f\"\\nAgent output:\\n{result['output_text']}\")\n", - " except json.JSONDecodeError as e:\n", - " print(f\"Failed to parse JSON: {e}\")\n", - " print(f\"Raw response: {response.text}\")\n", - "else:\n", - " print(f\"Error: {response.status_code}\")\n", - " if response.text:\n", - " try:\n", - " print(json.dumps(response.json(), indent=2))\n", - " except:\n", - " print(response.text)" - ] - }, - { - "cell_type": "markdown", - "id": "ccdf6775", - "metadata": {}, - "source": [ - "## 4. Test The Hosted Agent Via APIM\n", - "\n", - "**Purpose:** Route your request through Azure API Management instead of calling Foundry directly.\n", - "\n", - "This validates the production-like path:\n", - "- Client → APIM Gateway (subscription key auth) → Foundry Responses API\n", - "\n", - "**Important: Agent-Specific Routing**\n", - "\n", - "Foundry Hosted Agents **require** the agent name in the URL path. There is no generic `/responses` endpoint that accepts `agent_reference` in the request body. Each agent must have its own URL path:\n", - "\n", - "```\n", - "POST https://apim-{APIM_SUFFIX}.azure-api.net/hosted-agent-responses/agents/{AGENT_NAME}/endpoint/protocols/openai/responses\n", - "```\n", - "\n", - "**What APIM does automatically:**\n", - "- Injects managed identity bearer token for Foundry authentication (audience: `https://ai.azure.com`)\n", - "- Enforces `Content-Type: application/json` header\n", - "- Injects `Foundry-Features: HostedAgents=V1Preview` header for preview access\n", - "- Your client only needs the APIM subscription key (`api-key` header)\n", - "\n", - "**Comparison: Direct vs APIM**\n", - "- **Direct (Section 3):** `https://foundry-agents-{suffix}.services.ai.azure.com/api/projects/default-foundry-agents/agents/{AGENT_NAME}/endpoint/protocols/openai/responses` + Bearer token\n", - "- **APIM (Section 4):** `https://apim-{suffix}.azure-api.net/hosted-agent-responses/agents/{AGENT_NAME}/endpoint/protocols/openai/responses` + API key\n", - "\n", - "**Configuration details** are in [hosted-agent-policy.xml](../../hosted-agent-policy.xml)—update there if you need to change defaults.\n", - "\n", - "Compare this test result with Section 3 to ensure both paths (direct and APIM-proxied) produce consistent responses." - ] - }, - { - "cell_type": "markdown", - "id": "6bbb399b", - "metadata": {}, - "source": [ - "### Get deployment outputs\n", - "\n", - "Before testing via APIM, retrieve the outputs from your infrastructure deployment notebook:\n", - "\n", - "1. Run the deployment notebook and copy the outputs\n", - "2. Fill in these values below:\n", - " - `APIM_SUFFIX`: The unique suffix for your APIM instance (e.g., `xhep4wovroziu`)\n", - " - `APIM_SUBSCRIPTION_KEY`: The starter subscription key from APIM outputs\n", - " - `PROJECT_ENDPOINT`: The Foundry agents project endpoint\n", - "\n", - "These are already set in cell 2 of the infrastructure deployment notebook—just copy them here.\n" - ] - }, - { - "cell_type": "code", - "execution_count": 67, - "id": "ee7e33e1", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "APIM_SUFFIX: yxz4ztnhs2gd4\n", - "APIM_SUBSCRIPTION_KEY: d758c99aca6b4231980d...\n", - "PROJECT_ENDPOINT: https://foundry-agents-yxz4ztnhs2gd4.services.ai.azure.com/api/projects/default-foundry-agents\n", - "\n", - "⚠️ If these are still placeholders, run the infrastructure deployment notebook first!\n" - ] - } - ], - "source": [ - "APIM_SUFFIX = \"yxz4ztnhs2gd4\" # ⚠️ REPLACE with actual APIM suffix from deployment outputs\n", - "APIM_SUBSCRIPTION_KEY = \"d758c99aca6b4231980d5c0ff6917c59\" # ⚠️ REPLACE with starter subscription key\n", - "PROJECT_ENDPOINT = \"https://foundry-agents-yxz4ztnhs2gd4.services.ai.azure.com/api/projects/default-foundry-agents\" # ⚠️ REPLACE with actual endpoint\n", - "\n", - "print(f\"APIM_SUFFIX: {APIM_SUFFIX}\")\n", - "print(f\"APIM_SUBSCRIPTION_KEY: {APIM_SUBSCRIPTION_KEY[:20]}...\" if len(APIM_SUBSCRIPTION_KEY) > 20 else f\"APIM_SUBSCRIPTION_KEY: {APIM_SUBSCRIPTION_KEY}\")\n", - "print(f\"PROJECT_ENDPOINT: {PROJECT_ENDPOINT}\")\n", - "print()\n", - "print(\"⚠️ If these are still placeholders, run the infrastructure deployment notebook first!\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4cae98de", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "POST https://apim-yxz4ztnhs2gd4.azure-api.net/hosted-agent-responses/agents/strands-agent2/endpoint/protocols/openai/responses?api-version=v1\n", - "APIM Suffix: yxz4ztnhs2gd4\n", - "Agent Name (in URL path): strands-agent2\n", - "Content-Type: application/json\n", - "Headers: api-key=d758c99aca6b4231980d..., Content-Type, Foundry-Features\n", - "Payload: {\n", - " \"input\": \"Hello! What can you help me with? What's the weather in Paris today?\",\n", - " \"stream\": false\n", - "}\n", - "\n", - "Status: 200\n", - "Response text (first 500 chars): {\"id\":\"caresp_1f2f3736b8cfafb100xx2tyeCuWfTMn3414ZYYTOGImCDFg201\",\"object\":\"response\",\"output\":[{\"type\":\"message\",\"id\":\"msg_1f2f3736b8cfafb100lYSym1CzirQBAL264ippHQvbyVyjR23o\",\"role\":\"assistant\",\"content\":[{\"type\":\"output_text\",\"text\":\"Hi — I can help with a lot of things, for example:\\n- Answer questions and explain concepts (science, history, tech, etc.)\\n- Write, edit, or summarize text (emails, essays, code, reports)\\n- Help with programming, math, data analysis, and debugging\\n- Translate l\n", - "\n", - "Response JSON:\n", - "{\n", - " \"id\": \"caresp_1f2f3736b8cfafb100xx2tyeCuWfTMn3414ZYYTOGImCDFg201\",\n", - " \"object\": \"response\",\n", - " \"output\": [\n", - " {\n", - " \"type\": \"message\",\n", - " \"id\": \"msg_1f2f3736b8cfafb100lYSym1CzirQBAL264ippHQvbyVyjR23o\",\n", - " \"role\": \"assistant\",\n", - " \"content\": [\n", - " {\n", - " \"type\": \"output_text\",\n", - " \"text\": \"Hi \\u2014 I can help with a lot of things, for example:\\n- Answer questions and explain concepts (science, history, tech, etc.)\\n- Write, edit, or summarize text (emails, essays, code, reports)\\n- Help with programming, math, data analysis, and debugging\\n- Translate languages, generate ideas, or plan projects/trips\\n- Look up current weather (and some other live info) or show internal debug info when needed\\n\\nCurrent weather in Paris today: 18\\u00b0C (about 64.4\\u00b0F).\\n\\nWould you like a short forecast, clothing suggestions for that temperature, or the weather for a different place?\",\n", - " \"annotations\": [],\n", - " \"logprobs\": []\n", - " }\n", - " ],\n", - " \"status\": \"completed\",\n", - " \"response_id\": \"caresp_1f2f3736b8cfafb100xx2tyeCuWfTMn3414ZYYTOGImCDFg201\",\n", - " \"agent_reference\": {\n", - " \"type\": \"agent_reference\",\n", - " \"name\": \"strands-agent2\",\n", - " \"version\": \"1\"\n", - " }\n", - " }\n", - " ],\n", - " \"created_at\": 1783598603,\n", - " \"agent_reference\": {\n", - " \"type\": \"agent_reference\",\n", - " \"name\": \"strands-agent2\",\n", - " \"version\": \"1\"\n", - " },\n", - " \"status\": \"completed\",\n", - " \"completed_at\": 1783598608,\n", - " \"response_id\": \"caresp_1f2f3736b8cfafb100xx2tyeCuWfTMn3414ZYYTOGImCDFg201\",\n", - " \"model\": \"\",\n", - " \"agent_session_id\": \"4e22b594e0e8c976fb97fbd08e8f882665b1ff2f6f06a14866a0c0d508e0118\",\n", - " \"background\": false\n", - "}\n", - "\n", - "Extracted response stored in 'apim_response' variable for use in subsequent cells\n" - ] - } - ], - "source": [ - "import json\n", - "import requests\n", - "\n", - "# APIM configuration\n", - "DEFAULT_CONTENT_TYPE = \"application/json\"\n", - "API_VERSION = \"v1\"\n", - "\n", - "# APIM endpoint: agent-specific URL path (Foundry requires agent name in path, not in body)\n", - "# Format: https://apim-{suffix}.azure-api.net/hosted-agent-responses/agents/{agent}/endpoint/protocols/openai/responses\n", - "apim_url = f\"https://apim-{APIM_SUFFIX}.azure-api.net/hosted-agent-responses/agents/{AGENT_NAME}/endpoint/protocols/openai/responses\"\n", - "url = apim_url\n", - "\n", - "# Headers for APIM: use api-key header with subscription key\n", - "headers = {\n", - " \"api-key\": APIM_SUBSCRIPTION_KEY,\n", - " \"Content-Type\": DEFAULT_CONTENT_TYPE,\n", - " \"Foundry-Features\": \"HostedAgents=V1Preview\", # Required for preview\n", - "}\n", - "\n", - "# Foundry Hosted Agents do NOT support agent_reference in request body\n", - "# The agent name must be in the URL path (handled above)\n", - "payload = {\n", - " \"input\": \"Hello! What can you help me with? What's the weather in Paris today?\",\n", - " \"stream\": False,\n", - "}\n", - "\n", - "print(f\"POST {url}?api-version={API_VERSION}\")\n", - "print(f\"APIM Suffix: {APIM_SUFFIX}\")\n", - "print(f\"Agent Name (in URL path): {AGENT_NAME}\")\n", - "print(f\"Content-Type: {DEFAULT_CONTENT_TYPE}\")\n", - "print(f\"Headers: api-key={APIM_SUBSCRIPTION_KEY[:20]}..., Content-Type, Foundry-Features\")\n", - "print(f\"Payload: {json.dumps(payload, indent=2)}\")\n", - "print()\n", - "\n", - "response = requests.post(url, headers=headers, json=payload, params={\"api-version\": API_VERSION})\n", - "print(f\"Status: {response.status_code}\")\n", - "print()\n", - "\n", - "# Extract response from payload\n", - "apim_response = None\n", - "agent_text = None\n", - "\n", - "if response.status_code == 200:\n", - " try:\n", - " result = response.json()\n", - " apim_response = result\n", - " \n", - " # Extract agent text from nested structure\n", - " if \"output\" in result and len(result[\"output\"]) > 0:\n", - " message = result[\"output\"][0]\n", - " if \"content\" in message and len(message[\"content\"]) > 0:\n", - " agent_text = message[\"content\"][0].get(\"text\", \"\")\n", - " \n", - " print(\"=\" * 80)\n", - " print(f\"AGENT RESPONSE (via APIM):\")\n", - " print(\"=\" * 80)\n", - " if agent_text:\n", - " print(agent_text)\n", - " else:\n", - " print(\"Full response:\")\n", - " print(json.dumps(result, indent=2))\n", - " print(\"=\" * 80)\n", - " \n", - " except json.JSONDecodeError as e:\n", - " print(f\"Failed to parse JSON: {e}\")\n", - " print(f\"Raw response: {response.text}\")\n", - "else:\n", - " print(f\"Error: {response.status_code}\")\n", - " if response.text:\n", - " try:\n", - " apim_response = response.json()\n", - " print(json.dumps(apim_response, indent=2))\n", - " except:\n", - " print(response.text)\n", - "\n", - "print(f\"\\nExtracted response stored in 'apim_response' variable\")\n", - "print(f\"Agent text stored in 'agent_text' variable\")" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.12.10" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/Dockerfile b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/Dockerfile deleted file mode 100644 index bf032f64..00000000 --- a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/strands/Dockerfile +++ /dev/null @@ -1,7 +0,0 @@ -FROM python:3.12-slim -WORKDIR /app -COPY . user_agent/ -WORKDIR /app/user_agent -RUN if [ -f requirements.txt ]; then pip install -r requirements.txt; fi -EXPOSE 8088 -CMD ["python", "main.py"] \ No newline at end of file From dc3b7ea20c8213fc6f3e413d6d9cfc1e0911557a Mon Sep 17 00:00:00 2001 From: George Ollis Date: Thu, 9 Jul 2026 17:16:05 +0100 Subject: [PATCH 09/17] Enhance README for Pydantic and Strands agents: update setup instructions, clarify dependencies, and improve validation steps --- .../agents/frameworks/pydantic/README.md | 54 +++++++++++++------ .../agents/frameworks/strands/README.md | 6 +-- 2 files changed, 42 insertions(+), 18 deletions(-) diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/pydantic/README.md b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/pydantic/README.md index 14cd4d16..f86ca1fe 100644 --- a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/pydantic/README.md +++ b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/pydantic/README.md @@ -1,34 +1,58 @@ # Pydantic AI Agent on Foundry Hosted Agents -This sample code shows you how to run a Pydantic AI agent in Foundry Hosted Agents. +This sample shows how to build, deploy, and test a Pydantic AI-based custom agent on Microsoft Foundry Hosted Agents using the Responses protocol v1.0.0. ![Pydantic AI Hosted Agent Sample](image.png) ## What Is Included -- `01_hosted_agent_pydantic_setup.ipynb`: End-to-end setup workbook. - `main.py`: Pydantic AI agent server implementation (Responses protocol + tool calling + streaming). - `Dockerfile`: Container definition for hosting the agent in Foundry Hosted Agents. -- `requirements.txt`: Python dependencies for your Pydantic AI runtime. +- `requirements-pydantic.txt`: Python dependencies for this runtime. +- `../02_hosted_agent_pydantic_setup.ipynb`: End-to-end setup and validation notebook. ## Get Started -1. Open and run `01_hosted_agent_pydantic_setup.ipynb` from top to bottom. -2. Build and push the container image to your Azure Container Registry. -3. Create a hosted agent version in your Foundry project. -4. Grant required permissions (including Foundry role assignment for the hosted agent identity). -5. Test prompts against the deployed hosted agent. +1. Deploy infrastructure first with `../../../ai-foundry-hosted-agents-custom-framework.ipynb`. +2. Open and run `../02_hosted_agent_pydantic_setup.ipynb` from top to bottom. +3. Build and push the container image to Azure Container Registry. +4. Create a hosted agent version in your Foundry project. +5. Validate the agent through: + - Direct Foundry call (baseline) + - APIM call (production-like path) ## Prerequisites -- Azure subscription with access to Azure AI Foundry and Azure Container Registry. +- Azure subscription with access to Microsoft Foundry and Azure Container Registry. - Permission to push images to the target ACR repository. -- Permission to assign RBAC roles on the Foundry resource scope. -- Python environment with the dependencies required by your Pydantic AI app. +- Permission to create hosted agent versions in Foundry. +- Azure CLI installed and authenticated (`az login`). +- Docker Desktop installed and running. +- Python environment with dependencies required by this sample. + +## Invocation and Routing + +Hosted agents are invoked by agent-specific URL path. + +Direct Foundry endpoint: + +```http +POST {PROJECT_ENDPOINT}/agents/{AGENT_NAME}/endpoint/protocols/openai/responses?api-version=v1 +``` + +APIM endpoint: + +```http +POST https://apim-{APIM_SUFFIX}.azure-api.net/hosted-agent-responses/agents/{AGENT_NAME}/endpoint/protocols/openai/responses?api-version=v1 +``` + +- Do not use `agent_reference` in the request body for hosted-agent routing. +- Use `api-key` header when calling APIM. +- Include `Content-Type: application/json`. ## Notes -- This sample routes model calls through APIM inference chat-completions. -- Configure AZURE_OPENAI_ENDPOINT to your APIM inference URL and set APIM_SUBSCRIPTION_KEY. -- The runtime sends the APIM subscription key in the api-key header for model calls. -- Use the notebook placeholders to provide your own project, registry, and deployment values. +- This sample routes model calls through APIM inference (`/inference/models`). +- Configure `AZURE_OPENAI_ENDPOINT` to your APIM inference URL and set `APIM_SUBSCRIPTION_KEY`. +- The runtime sends the APIM subscription key in the `api-key` header for model calls. +- Keep notebook placeholder values aligned with your infrastructure deployment outputs. diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/strands/README.md b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/strands/README.md index 78b1388d..0179d489 100644 --- a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/strands/README.md +++ b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/strands/README.md @@ -10,7 +10,7 @@ The agent runs in a containerized environment managed by Foundry, with full obse - **`main.py`**: Strands agent server implementing the Responses protocol with tool calling and streaming. - **`Dockerfile`**: Container image definition for Foundry Hosted Agents (builds for Linux amd64). -- **`requirements.txt`**: Python dependencies (strands, FastAPI, etc.). +- **`requirements-strands.txt`**: Python dependencies (Strands, FastAPI, etc.). - **`01_hosted_agent_strands_setup.ipynb`**: End-to-end setup and testing notebook with 4 sections: 1. Build and push container to ACR 2. Create hosted agent version in Foundry @@ -95,7 +95,7 @@ Run **Section 4** ("Test via APIM"): - APIM automatically: - Injects managed identity bearer token - Enforces `Content-Type: application/json` - - Enforces `api-version: 2025-05-15-preview` + - Uses Responses API `api-version=v1` - Injects `Foundry-Features: HostedAgents=V1Preview` (required for preview) - Validates end-to-end production path @@ -114,7 +114,7 @@ Policy configuration is in `../../hosted-agent-policy.xml` for customization. ## Key Configuration Notes -- **Agent name**: Should match `hosted_agent_id` parameter from the infrastructure deployment (without version suffix). +- **Agent name**: Use the same value configured as `AGENT_NAME` in the setup notebook. - **Model endpoint**: Your agent calls the APIM **inference** API, not the hosted-agent API. - **Token audience**: - Direct tests use `https://ai.azure.com/.default` From b8c8e8aaf479eaa367f55b83478dbb247966b4fa Mon Sep 17 00:00:00 2001 From: George Ollis Date: Thu, 9 Jul 2026 17:18:01 +0100 Subject: [PATCH 10/17] Enhance README files for Strands and Pydantic AI agents: add framework overviews, comparison table, and official references --- .../src/responses/agents/frameworks/README.md | 35 +++++++++++++++++++ .../agents/frameworks/pydantic/README.md | 12 +++++++ .../agents/frameworks/strands/README.md | 12 +++++++ 3 files changed, 59 insertions(+) diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/README.md b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/README.md index 2eada499..2a64208e 100644 --- a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/README.md +++ b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/README.md @@ -16,6 +16,41 @@ This directory contains multiple framework implementations for deploying custom - For Strands: `01_hosted_agent_strands_setup.ipynb` - For Pydantic AI: `02_hosted_agent_pydantic_setup.ipynb` +## Framework Overview + +### Strands Agents + +From the official Strands site, Strands is positioned as an open-source toolkit for building production agents with: +- model/provider flexibility ("any model, any cloud") +- built-in context management and execution limits +- built-in observability and hook-based control points + +In practice for this lab, Strands is a strong fit when you want explicit control over the agent loop and operational behaviors. + +### Pydantic AI + +From the official Pydantic AI docs, an Agent is the core abstraction and acts as a container for: +- instructions +- tools/toolsets +- optional structured output typing +- dependency typing +- model defaults/settings and composable capabilities + +In practice for this lab, Pydantic AI is a strong fit when typed dependencies and typed/validated outputs are central requirements. + +### At-a-Glance Comparison + +| Dimension | Strands | Pydantic AI | +|---|---|---| +| Primary emphasis | Production agent runtime control | Typed agent design and validation | +| Extensibility model | Hooks + tools + conversation managers | Tools + instructions + capabilities | +| Typing story | Flexible runtime-oriented API | Strong dependency/output typing | +| Good default use case | Tool-heavy workflow automation | Schema/contract-driven agent systems | + +Official references: +- Strands: https://strandsagents.com/ +- Pydantic AI Agents: https://pydantic.dev/docs/ai/core-concepts/agent/ + ## Folder Structure ``` diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/pydantic/README.md b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/pydantic/README.md index f86ca1fe..7a6db333 100644 --- a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/pydantic/README.md +++ b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/pydantic/README.md @@ -2,6 +2,18 @@ This sample shows how to build, deploy, and test a Pydantic AI-based custom agent on Microsoft Foundry Hosted Agents using the Responses protocol v1.0.0. +## Framework Overview (Pydantic AI) + +According to the official Pydantic AI agent docs, an agent is the primary abstraction and can be treated as a container for instructions, tools/toolsets, structured output typing, dependency typing, model settings, and reusable capabilities. + +Why that matters for this sample: +- Good fit when output shape and validation matter to downstream systems. +- Good fit when you want typed dependencies and strong IDE/static-checker feedback. +- Good fit when you want to compose reusable behavior via capabilities. + +Official reference: +- https://pydantic.dev/docs/ai/core-concepts/agent/ + ![Pydantic AI Hosted Agent Sample](image.png) ## What Is Included diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/strands/README.md b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/strands/README.md index 0179d489..36870799 100644 --- a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/strands/README.md +++ b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/strands/README.md @@ -2,6 +2,18 @@ This sample shows how to build, deploy, and test a **Strands-based custom agent** on Microsoft Foundry Hosted Agents using the **Responses protocol v1.0.0**. +## Framework Overview (Strands) + +From the official Strands site, Strands is an open-source toolkit focused on building production agents with model/provider flexibility, built-in context management, execution limits, observability, and hook-based runtime control. + +Why that matters for this sample: +- Good fit for tool-heavy workflow automation. +- Good fit when you want to intercept/steer runtime behavior with hooks. +- Good fit when operational visibility and control of the agent loop are top priorities. + +Official reference: +- https://strandsagents.com/ + The agent runs in a containerized environment managed by Foundry, with full observability, RBAC identity, and optional APIM gateway integration. ![Strands Hosted Agent Sample](image.png) From 728b06777aa309478ada7c40cfc8ded53f1c7bd7 Mon Sep 17 00:00:00 2001 From: George Ollis Date: Thu, 9 Jul 2026 17:20:16 +0100 Subject: [PATCH 11/17] Remove agent_creation.py references from .gitignore files for Strands and Pydantic frameworks --- .../src/responses/agents/frameworks/README.md | 5 ----- .../src/responses/agents/frameworks/pydantic/.gitignore | 1 - .../src/responses/agents/frameworks/strands/.gitignore | 1 - 3 files changed, 7 deletions(-) diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/README.md b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/README.md index 2a64208e..28e99abd 100644 --- a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/README.md +++ b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/README.md @@ -59,7 +59,6 @@ frameworks/ ├── 02_hosted_agent_pydantic_setup.ipynb # Deploy Pydantic AI agent ├── strands/ # Strands framework implementation │ ├── main.py # Agent entry point -│ ├── agent_creation.py # Agent setup code │ ├── Dockerfile # Container image definition │ ├── requirements-strands.txt # Strands framework dependencies │ ├── README.md # Strands-specific documentation @@ -69,7 +68,6 @@ frameworks/ │ └── pydantic/ # Pydantic AI framework implementation ├── main.py # Agent entry point - ├── agent_creation.py # Agent setup code ├── Dockerfile # Container image definition ├── requirements-pydantic.txt # Pydantic dependencies ├── README.md # Pydantic-specific documentation @@ -95,7 +93,6 @@ frameworks/ ### Key Files - `main.py` - Agent execution and response protocol handler -- `agent_creation.py` - Foundry agent registration - `requirements-strands.txt` - Framework-specific dependencies - `Dockerfile` - Container image with `FROM python:3.12-slim` @@ -125,7 +122,6 @@ frameworks/ ### Key Files - `main.py` - Pydantic-based agent with validation -- `agent_creation.py` - Foundry agent registration - `requirements-pydantic.txt` - Pydantic and related dependencies - `Dockerfile` - Container image with `FROM python:3.12-slim` @@ -191,7 +187,6 @@ To add another framework (e.g., CrewAI, AutoGen): 2. **Copy template files**: - Copy `Dockerfile` from existing framework - Create `main.py` with your framework initialization - - Create `agent_creation.py` with Foundry registration - Create `requirements-crew-ai.txt` with framework dependencies - Create `README.md` documenting the framework 3. **Create setup notebook**: Copy `01_hosted_agent_strands_setup.ipynb` and adapt: diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/pydantic/.gitignore b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/pydantic/.gitignore index ffdb3a31..a98520db 100644 --- a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/pydantic/.gitignore +++ b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/pydantic/.gitignore @@ -2,4 +2,3 @@ __pycache__/ *.pyc .env -agent_creation.py \ No newline at end of file diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/strands/.gitignore b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/strands/.gitignore index ffdb3a31..a98520db 100644 --- a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/strands/.gitignore +++ b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/strands/.gitignore @@ -2,4 +2,3 @@ __pycache__/ *.pyc .env -agent_creation.py \ No newline at end of file From f10ccb42b442f28e368b9adc46e76dcbcbfb8670 Mon Sep 17 00:00:00 2001 From: George Ollis Date: Thu, 9 Jul 2026 17:23:28 +0100 Subject: [PATCH 12/17] Refactor 02_hosted_agent_pydantic_setup.ipynb to remove sensitive output and replace configuration values with placeholders --- .../02_hosted_agent_pydantic_setup.ipynb | 431 +----------------- 1 file changed, 13 insertions(+), 418 deletions(-) diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/02_hosted_agent_pydantic_setup.ipynb b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/02_hosted_agent_pydantic_setup.ipynb index 63530d31..4fa16695 100644 --- a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/02_hosted_agent_pydantic_setup.ipynb +++ b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/02_hosted_agent_pydantic_setup.ipynb @@ -45,24 +45,12 @@ "execution_count": null, "id": "b9ba6016", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "ACR_NAME=acrba3feqajmh55m\n", - "ACR_LOGIN_SERVER=acrba3feqajmh55m.azurecr.io\n", - "IMAGE_NAME=pydantic-agent\n", - "IMAGE_TAG=1.0.0\n", - "IMAGE_URI=acrba3feqajmh55m.azurecr.io/pydantic-agent:1.0.0\n" - ] - } - ], + "outputs": [], "source": [ "# Central configuration (edit here once, then run notebook top-to-bottom)\n", - "ACR_NAME = \"acrba3feqajmh55m\"\n", - "APIM_SUFFIX = \"ba3feqajmh55m\"\n", - "APIM_SUBSCRIPTION_KEY = \"af58eceeebbe4dac864e1f4785d1d497\"\n", + "ACR_NAME = \"X\"\n", + "APIM_SUFFIX = \"X\"\n", + "APIM_SUBSCRIPTION_KEY = \"X\"\n", "PROJECT_ENDPOINT = f\"https://foundry-agents-{APIM_SUFFIX}.services.ai.azure.com/api/projects/default-foundry-agents\"\n", "\n", "AGENT_NAME = \"pydantic-agent\"\n", @@ -112,18 +100,10 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "id": "ace1aa5f", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Login Succeeded\n" - ] - } - ], + "outputs": [], "source": [ "# Ensure Docker is running\n", "!az acr login --name {ACR_NAME}" @@ -134,17 +114,7 @@ "execution_count": null, "id": "a49cb256", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Running: docker build -t acrba3feqajmh55m.azurecr.io/pydantic-agent:1.0.0 .\n", - "Running: docker push acrba3feqajmh55m.azurecr.io/pydantic-agent:1.0.0\n", - "Docker build and push completed successfully.\n" - ] - } - ], + "outputs": [], "source": [ "import os\n", "import subprocess\n", @@ -201,266 +171,10 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "id": "a471f202", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Collecting azure-ai-projects==2.3.0\n", - " Downloading azure_ai_projects-2.3.0-py3-none-any.whl.metadata (64 kB)\n", - "Collecting isodate>=0.6.1 (from azure-ai-projects==2.3.0)\n", - " Downloading isodate-0.7.2-py3-none-any.whl.metadata (11 kB)\n", - "Collecting azure-core>=1.37.0 (from azure-ai-projects==2.3.0)\n", - " Downloading azure_core-1.41.0-py3-none-any.whl.metadata (49 kB)\n", - "Collecting typing-extensions>=4.11 (from azure-ai-projects==2.3.0)\n", - " Downloading typing_extensions-4.16.0-py3-none-any.whl.metadata (3.3 kB)\n", - "Collecting azure-identity>=1.15.0 (from azure-ai-projects==2.3.0)\n", - " Downloading azure_identity-1.25.3-py3-none-any.whl.metadata (91 kB)\n", - "Collecting openai>=2.8.0 (from azure-ai-projects==2.3.0)\n", - " Downloading openai-2.44.0-py3-none-any.whl.metadata (34 kB)\n", - "Collecting azure-storage-blob>=12.15.0 (from azure-ai-projects==2.3.0)\n", - " Downloading azure_storage_blob-12.30.0-py3-none-any.whl.metadata (26 kB)\n", - "Collecting requests>=2.21.0 (from azure-core>=1.37.0->azure-ai-projects==2.3.0)\n", - " Downloading requests-2.34.2-py3-none-any.whl.metadata (4.8 kB)\n", - "Collecting cryptography>=2.5 (from azure-identity>=1.15.0->azure-ai-projects==2.3.0)\n", - " Downloading cryptography-49.0.0-cp311-abi3-win_amd64.whl.metadata (4.3 kB)\n", - "Collecting msal>=1.35.1 (from azure-identity>=1.15.0->azure-ai-projects==2.3.0)\n", - " Downloading msal-1.37.0-py3-none-any.whl.metadata (11 kB)\n", - "Collecting msal-extensions>=1.2.0 (from azure-identity>=1.15.0->azure-ai-projects==2.3.0)\n", - " Downloading msal_extensions-1.3.1-py3-none-any.whl.metadata (7.8 kB)\n", - "Collecting anyio<5,>=3.5.0 (from openai>=2.8.0->azure-ai-projects==2.3.0)\n", - " Downloading anyio-4.14.1-py3-none-any.whl.metadata (4.6 kB)\n", - "Collecting distro<2,>=1.7.0 (from openai>=2.8.0->azure-ai-projects==2.3.0)\n", - " Downloading distro-1.9.0-py3-none-any.whl.metadata (6.8 kB)\n", - "Collecting httpx<1,>=0.23.0 (from openai>=2.8.0->azure-ai-projects==2.3.0)\n", - " Downloading httpx-0.28.1-py3-none-any.whl.metadata (7.1 kB)\n", - "Collecting jiter<1,>=0.10.0 (from openai>=2.8.0->azure-ai-projects==2.3.0)\n", - " Downloading jiter-0.16.0-cp312-cp312-win_amd64.whl.metadata (5.3 kB)\n", - "Collecting pydantic<3,>=1.9.0 (from openai>=2.8.0->azure-ai-projects==2.3.0)\n", - " Downloading pydantic-2.13.4-py3-none-any.whl.metadata (109 kB)\n", - "Collecting sniffio (from openai>=2.8.0->azure-ai-projects==2.3.0)\n", - " Downloading sniffio-1.3.1-py3-none-any.whl.metadata (3.9 kB)\n", - "Collecting tqdm>4 (from openai>=2.8.0->azure-ai-projects==2.3.0)\n", - " Downloading tqdm-4.68.4-py3-none-any.whl.metadata (57 kB)\n", - "Collecting idna>=2.8 (from anyio<5,>=3.5.0->openai>=2.8.0->azure-ai-projects==2.3.0)\n", - " Downloading idna-3.18-py3-none-any.whl.metadata (6.1 kB)\n", - "Collecting cffi>=2.0.0 (from cryptography>=2.5->azure-identity>=1.15.0->azure-ai-projects==2.3.0)\n", - " Downloading cffi-2.1.0-cp312-cp312-win_amd64.whl.metadata (2.6 kB)\n", - "Collecting certifi (from httpx<1,>=0.23.0->openai>=2.8.0->azure-ai-projects==2.3.0)\n", - " Downloading certifi-2026.6.17-py3-none-any.whl.metadata (2.5 kB)\n", - "Collecting httpcore==1.* (from httpx<1,>=0.23.0->openai>=2.8.0->azure-ai-projects==2.3.0)\n", - " Downloading httpcore-1.0.9-py3-none-any.whl.metadata (21 kB)\n", - "Collecting h11>=0.16 (from httpcore==1.*->httpx<1,>=0.23.0->openai>=2.8.0->azure-ai-projects==2.3.0)\n", - " Downloading h11-0.16.0-py3-none-any.whl.metadata (8.3 kB)\n", - "Collecting PyJWT<3,>=1.0.0 (from PyJWT[crypto]<3,>=1.0.0->msal>=1.35.1->azure-identity>=1.15.0->azure-ai-projects==2.3.0)\n", - " Downloading pyjwt-2.13.0-py3-none-any.whl.metadata (3.4 kB)\n", - "Collecting annotated-types>=0.6.0 (from pydantic<3,>=1.9.0->openai>=2.8.0->azure-ai-projects==2.3.0)\n", - " Downloading annotated_types-0.7.0-py3-none-any.whl.metadata (15 kB)\n", - "Collecting pydantic-core==2.46.4 (from pydantic<3,>=1.9.0->openai>=2.8.0->azure-ai-projects==2.3.0)\n", - " Downloading pydantic_core-2.46.4-cp312-cp312-win_amd64.whl.metadata (6.7 kB)\n", - "Collecting typing-inspection>=0.4.2 (from pydantic<3,>=1.9.0->openai>=2.8.0->azure-ai-projects==2.3.0)\n", - " Downloading typing_inspection-0.4.2-py3-none-any.whl.metadata (2.6 kB)\n", - "Collecting charset_normalizer<4,>=2 (from requests>=2.21.0->azure-core>=1.37.0->azure-ai-projects==2.3.0)\n", - " Downloading charset_normalizer-3.4.9-cp312-cp312-win_amd64.whl.metadata (42 kB)\n", - "Collecting urllib3<3,>=1.26 (from requests>=2.21.0->azure-core>=1.37.0->azure-ai-projects==2.3.0)\n", - " Downloading urllib3-2.7.0-py3-none-any.whl.metadata (6.9 kB)\n", - "Collecting colorama (from tqdm>4->openai>=2.8.0->azure-ai-projects==2.3.0)\n", - " Downloading colorama-0.4.6-py2.py3-none-any.whl.metadata (17 kB)\n", - "Collecting pycparser (from cffi>=2.0.0->cryptography>=2.5->azure-identity>=1.15.0->azure-ai-projects==2.3.0)\n", - " Downloading pycparser-3.0-py3-none-any.whl.metadata (8.2 kB)\n", - "Downloading azure_ai_projects-2.3.0-py3-none-any.whl (349 kB)\n", - "Downloading azure_core-1.41.0-py3-none-any.whl (220 kB)\n", - "Downloading azure_identity-1.25.3-py3-none-any.whl (192 kB)\n", - "Downloading azure_storage_blob-12.30.0-py3-none-any.whl (435 kB)\n", - "Downloading isodate-0.7.2-py3-none-any.whl (22 kB)\n", - "Downloading openai-2.44.0-py3-none-any.whl (1.4 MB)\n", - " ---------------------------------------- 0.0/1.4 MB ? eta -:--:--\n", - " ---------------------------------------- 1.4/1.4 MB 35.6 MB/s eta 0:00:00\n", - "Downloading typing_extensions-4.16.0-py3-none-any.whl (45 kB)\n", - "Downloading anyio-4.14.1-py3-none-any.whl (124 kB)\n", - "Downloading cryptography-49.0.0-cp311-abi3-win_amd64.whl (3.8 MB)\n", - " ---------------------------------------- 0.0/3.8 MB ? eta -:--:--\n", - " ---------------------------------------- 3.8/3.8 MB 75.5 MB/s eta 0:00:00\n", - "Downloading distro-1.9.0-py3-none-any.whl (20 kB)\n", - "Downloading httpx-0.28.1-py3-none-any.whl (73 kB)\n", - "Downloading httpcore-1.0.9-py3-none-any.whl (78 kB)\n", - "Downloading jiter-0.16.0-cp312-cp312-win_amd64.whl (196 kB)\n", - "Downloading msal-1.37.0-py3-none-any.whl (123 kB)\n", - "Downloading msal_extensions-1.3.1-py3-none-any.whl (20 kB)\n", - "Downloading pydantic-2.13.4-py3-none-any.whl (472 kB)\n", - "Downloading pydantic_core-2.46.4-cp312-cp312-win_amd64.whl (2.1 MB)\n", - " ---------------------------------------- 0.0/2.1 MB ? eta -:--:--\n", - " ---------------------------------------- 2.1/2.1 MB 113.2 MB/s eta 0:00:00\n", - "Downloading requests-2.34.2-py3-none-any.whl (73 kB)\n", - "Downloading tqdm-4.68.4-py3-none-any.whl (676 kB)\n", - " ---------------------------------------- 0.0/676.6 kB ? eta -:--:--\n", - " ---------------------------------------- 676.6/676.6 kB ? eta 0:00:00\n", - "Downloading sniffio-1.3.1-py3-none-any.whl (10 kB)\n", - "Downloading annotated_types-0.7.0-py3-none-any.whl (13 kB)\n", - "Downloading certifi-2026.6.17-py3-none-any.whl (133 kB)\n", - "Downloading cffi-2.1.0-cp312-cp312-win_amd64.whl (185 kB)\n", - "Downloading charset_normalizer-3.4.9-cp312-cp312-win_amd64.whl (162 kB)\n", - "Downloading idna-3.18-py3-none-any.whl (65 kB)\n", - "Downloading pyjwt-2.13.0-py3-none-any.whl (31 kB)\n", - "Downloading typing_inspection-0.4.2-py3-none-any.whl (14 kB)\n", - "Downloading urllib3-2.7.0-py3-none-any.whl (131 kB)\n", - "Downloading colorama-0.4.6-py2.py3-none-any.whl (25 kB)\n", - "Downloading h11-0.16.0-py3-none-any.whl (37 kB)\n", - "Downloading pycparser-3.0-py3-none-any.whl (48 kB)\n", - "Installing collected packages: urllib3, typing-extensions, sniffio, PyJWT, pycparser, jiter, isodate, idna, h11, distro, colorama, charset_normalizer, certifi, annotated-types, typing-inspection, tqdm, requests, pydantic-core, httpcore, cffi, anyio, pydantic, httpx, cryptography, azure-core, openai, azure-storage-blob, msal, msal-extensions, azure-identity, azure-ai-projects\n", - " Attempting uninstall: urllib3\n", - " Found existing installation: urllib3 2.7.0\n", - " Uninstalling urllib3-2.7.0:\n", - " Successfully uninstalled urllib3-2.7.0\n", - " Attempting uninstall: typing-extensions\n", - " Found existing installation: typing_extensions 4.16.0\n", - " Uninstalling typing_extensions-4.16.0:\n", - " Successfully uninstalled typing_extensions-4.16.0\n", - " Attempting uninstall: sniffio\n", - " Found existing installation: sniffio 1.3.1\n", - " Uninstalling sniffio-1.3.1:\n", - " Successfully uninstalled sniffio-1.3.1\n", - " Attempting uninstall: PyJWT\n", - " Found existing installation: PyJWT 2.13.0\n", - " Uninstalling PyJWT-2.13.0:\n", - " Successfully uninstalled PyJWT-2.13.0\n", - " Attempting uninstall: pycparser\n", - " Found existing installation: pycparser 3.0\n", - " Uninstalling pycparser-3.0:\n", - " Successfully uninstalled pycparser-3.0\n", - " Attempting uninstall: jiter\n", - " Found existing installation: jiter 0.16.0\n", - " Uninstalling jiter-0.16.0:\n", - " Successfully uninstalled jiter-0.16.0\n", - " Attempting uninstall: isodate\n", - " Found existing installation: isodate 0.7.2\n", - " Uninstalling isodate-0.7.2:\n", - " Successfully uninstalled isodate-0.7.2\n", - " Attempting uninstall: idna\n", - " Found existing installation: idna 3.18\n", - " Uninstalling idna-3.18:\n", - " Successfully uninstalled idna-3.18\n", - " Attempting uninstall: h11\n", - " Found existing installation: h11 0.16.0\n", - " Uninstalling h11-0.16.0:\n", - " Successfully uninstalled h11-0.16.0\n", - " Attempting uninstall: distro\n", - " Found existing installation: distro 1.9.0\n", - " Uninstalling distro-1.9.0:\n", - " Successfully uninstalled distro-1.9.0\n", - " Attempting uninstall: colorama\n", - " Found existing installation: colorama 0.4.6\n", - " Uninstalling colorama-0.4.6:\n", - " Successfully uninstalled colorama-0.4.6\n", - " Attempting uninstall: certifi\n", - " Found existing installation: certifi 2026.6.17\n", - " Uninstalling certifi-2026.6.17:\n", - " Successfully uninstalled certifi-2026.6.17\n", - " Attempting uninstall: annotated-types\n", - " Found existing installation: annotated-types 0.7.0\n", - " Uninstalling annotated-types-0.7.0:\n", - " Successfully uninstalled annotated-types-0.7.0\n", - " Attempting uninstall: typing-inspection\n", - " Found existing installation: typing-inspection 0.4.2\n", - " Uninstalling typing-inspection-0.4.2:\n", - " Successfully uninstalled typing-inspection-0.4.2\n", - " Attempting uninstall: tqdm\n", - " Found existing installation: tqdm 4.68.4\n", - " Uninstalling tqdm-4.68.4:\n", - " Successfully uninstalled tqdm-4.68.4\n", - " Attempting uninstall: requests\n", - " Found existing installation: requests 2.34.2\n", - " Uninstalling requests-2.34.2:\n", - " Successfully uninstalled requests-2.34.2\n", - " Attempting uninstall: pydantic-core\n", - " Found existing installation: pydantic_core 2.46.4\n", - " Uninstalling pydantic_core-2.46.4:\n", - " Successfully uninstalled pydantic_core-2.46.4\n", - " Attempting uninstall: httpcore\n", - " Found existing installation: httpcore 1.0.9\n", - " Uninstalling httpcore-1.0.9:\n", - " Successfully uninstalled httpcore-1.0.9\n", - " Attempting uninstall: cffi\n", - " Found existing installation: cffi 2.1.0\n", - " Uninstalling cffi-2.1.0:\n", - " Successfully uninstalled cffi-2.1.0\n", - " Attempting uninstall: anyio\n", - " Found existing installation: anyio 4.14.1\n", - " Uninstalling anyio-4.14.1:\n", - " Successfully uninstalled anyio-4.14.1\n", - " Attempting uninstall: pydantic\n", - " Found existing installation: pydantic 2.13.4\n", - " Uninstalling pydantic-2.13.4:\n", - " Successfully uninstalled pydantic-2.13.4\n", - " Attempting uninstall: httpx\n", - " Found existing installation: httpx 0.28.1\n", - " Uninstalling httpx-0.28.1:\n", - " Successfully uninstalled httpx-0.28.1\n", - " Attempting uninstall: cryptography\n", - " Found existing installation: cryptography 49.0.0\n", - " Uninstalling cryptography-49.0.0:\n", - " Successfully uninstalled cryptography-49.0.0\n", - " Attempting uninstall: azure-core\n", - " Found existing installation: azure-core 1.41.0\n", - " Uninstalling azure-core-1.41.0:\n", - " Successfully uninstalled azure-core-1.41.0\n", - " Attempting uninstall: openai\n", - " Found existing installation: openai 2.44.0\n", - " Uninstalling openai-2.44.0:\n", - " Successfully uninstalled openai-2.44.0\n", - " Attempting uninstall: azure-storage-blob\n", - " Found existing installation: azure-storage-blob 12.30.0\n", - " Uninstalling azure-storage-blob-12.30.0:\n", - " Successfully uninstalled azure-storage-blob-12.30.0\n", - " Attempting uninstall: msal\n", - " Found existing installation: msal 1.37.0\n", - " Uninstalling msal-1.37.0:\n", - " Successfully uninstalled msal-1.37.0\n", - " Attempting uninstall: msal-extensions\n", - " Found existing installation: msal-extensions 1.3.1\n", - " Uninstalling msal-extensions-1.3.1:\n", - " Successfully uninstalled msal-extensions-1.3.1\n", - " Attempting uninstall: azure-identity\n", - " Found existing installation: azure-identity 1.25.3\n", - " Uninstalling azure-identity-1.25.3:\n", - " Successfully uninstalled azure-identity-1.25.3\n", - " Attempting uninstall: azure-ai-projects\n", - " Found existing installation: azure-ai-projects 2.3.0\n", - " Uninstalling azure-ai-projects-2.3.0:\n", - " Successfully uninstalled azure-ai-projects-2.3.0\n", - "Successfully installed PyJWT-2.13.0 annotated-types-0.7.0 anyio-4.14.1 azure-ai-projects-2.3.0 azure-core-1.41.0 azure-identity-1.25.3 azure-storage-blob-12.30.0 certifi-2026.6.17 cffi-2.1.0 charset_normalizer-3.4.9 colorama-0.4.6 cryptography-49.0.0 distro-1.9.0 h11-0.16.0 httpcore-1.0.9 httpx-0.28.1 idna-3.18 isodate-0.7.2 jiter-0.16.0 msal-1.37.0 msal-extensions-1.3.1 openai-2.44.0 pycparser-3.0 pydantic-2.13.4 pydantic-core-2.46.4 requests-2.34.2 sniffio-1.3.1 tqdm-4.68.4 typing-extensions-4.16.0 typing-inspection-0.4.2 urllib3-2.7.0\n", - "Note: you may need to restart the kernel to use updated packages.\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "WARNING: Ignoring invalid distribution ~harset-normalizer (c:\\Users\\ollisgeorge\\AppData\\Local\\Programs\\Python\\Python312-x64\\Lib\\site-packages)\n", - "WARNING: Ignoring invalid distribution ~harset-normalizer (c:\\Users\\ollisgeorge\\AppData\\Local\\Programs\\Python\\Python312-x64\\Lib\\site-packages)\n", - "WARNING: Ignoring invalid distribution ~harset-normalizer (c:\\Users\\ollisgeorge\\AppData\\Local\\Programs\\Python\\Python312-x64\\Lib\\site-packages)\n", - " WARNING: The script idna.exe is installed in 'c:\\Users\\ollisgeorge\\AppData\\Local\\Programs\\Python\\Python312-x64\\Scripts' which is not on PATH.\n", - " Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.\n", - " WARNING: The script distro.exe is installed in 'c:\\Users\\ollisgeorge\\AppData\\Local\\Programs\\Python\\Python312-x64\\Scripts' which is not on PATH.\n", - " Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.\n", - " WARNING: The script normalizer.exe is installed in 'c:\\Users\\ollisgeorge\\AppData\\Local\\Programs\\Python\\Python312-x64\\Scripts' which is not on PATH.\n", - " Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.\n", - " WARNING: The script tqdm.exe is installed in 'c:\\Users\\ollisgeorge\\AppData\\Local\\Programs\\Python\\Python312-x64\\Scripts' which is not on PATH.\n", - " Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.\n", - " WARNING: The script cffi-gen-src.exe is installed in 'c:\\Users\\ollisgeorge\\AppData\\Local\\Programs\\Python\\Python312-x64\\Scripts' which is not on PATH.\n", - " Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.\n", - " WARNING: The script httpx.exe is installed in 'c:\\Users\\ollisgeorge\\AppData\\Local\\Programs\\Python\\Python312-x64\\Scripts' which is not on PATH.\n", - " Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.\n", - "WARNING: Ignoring invalid distribution ~harset-normalizer (c:\\Users\\ollisgeorge\\AppData\\Local\\Programs\\Python\\Python312-x64\\Lib\\site-packages)\n", - "\n", - "[notice] A new release of pip is available: 25.0.1 -> 26.1.2\n", - "[notice] To update, run: python.exe -m pip install --upgrade pip\n" - ] - } - ], + "outputs": [], "source": [ "pip install azure-ai-projects==2.3.0 " ] @@ -490,17 +204,7 @@ "execution_count": null, "id": "e6e2ec6a", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "PROJECT_ENDPOINT: https://foundry-agents-ba3feqajmh55m.services.ai.azure.com/api/projects/default-foundry-agents\n", - "AGENT_NAME: pydantic-agent\n", - "Agent created: pydantic-agent, version: 1, id pydantic-agent:1\n" - ] - } - ], + "outputs": [], "source": [ "from azure.ai.projects import AIProjectClient\n", "from azure.ai.projects.models import (\n", @@ -574,64 +278,7 @@ "execution_count": null, "id": "2c0c6c90", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "POST https://foundry-agents-ba3feqajmh55m.services.ai.azure.com/api/projects/default-foundry-agents/agents/pydantic-agent/endpoint/protocols/openai/responses?api-version=v1\n", - "Agent Name: pydantic-agent\n", - "Payload: {\n", - " \"input\": \"Hello! What can you help me with?\",\n", - " \"stream\": false\n", - "}\n", - "\n", - "Status: 200\n", - "Headers: {'Content-Length': '1740', 'Content-Type': 'application/json', 'content-encoding': 'identity', 'request-context': 'appId=', 'x-ms-response-type': 'standard', 'x-request-id': 'c1a2ff7f9abf029858efead2779d8426,c1a2ff7f9abf029858efead2779d8426', 'api-supported-versions': '1.0,2025-05-15-preview,2025-11-15-preview', 'x-agent-session-id': 'be166a9eefecee80e53ead6697630e7c3c8fd572145dc2011df6e0b96dd6246', 'x-platform-server': 'azure-ai-agentserver-core/2.0.0b7 (python/3.12) azure-ai-agentserver-responses/1.0.0b8 (python/3.12)', 'azureml-served-by-cluster': 'hyena-swedencentral-01', 'apim-request-id': '88778716-6c1a-4a40-9363-15f708c83294', 'Strict-Transport-Security': 'max-age=31536000; includeSubDomains; preload', 'x-content-type-options': 'nosniff', 'x-ms-region': 'Sweden Central', 'Access-Control-Expose-Headers': 'Operation-Location,Location,Apim-Request-Id,x-agent-session-id,x-agent-invocation-id', 'Date': 'Thu, 09 Jul 2026 16:03:49 GMT'}\n", - "Response text (first 500 chars): {\"id\":\"caresp_00723da9a08875aa00plRMH3lcvohERaHApDJDERSvoCS5t6qq\",\"object\":\"response\",\"output\":[{\"type\":\"message\",\"id\":\"msg_00723da9a08875aa00Twpb9FO4NFWSUyVWIyL91RybvyQo9WIb\",\"role\":\"assistant\",\"content\":[{\"type\":\"output_text\",\"text\":\"Hi — I can help with lots of things. Short list:\\n\\n- Explain topics and answer questions (science, history, tech, etc.)\\n- Research-style summaries and fact-checking (knowledge up to June 2024)\\n- Step-by-step how-tos and troubleshooting (software, appliances, DI\n", - "\n", - "Response JSON:\n", - "{\n", - " \"id\": \"caresp_00723da9a08875aa00plRMH3lcvohERaHApDJDERSvoCS5t6qq\",\n", - " \"object\": \"response\",\n", - " \"output\": [\n", - " {\n", - " \"type\": \"message\",\n", - " \"id\": \"msg_00723da9a08875aa00Twpb9FO4NFWSUyVWIyL91RybvyQo9WIb\",\n", - " \"role\": \"assistant\",\n", - " \"content\": [\n", - " {\n", - " \"type\": \"output_text\",\n", - " \"text\": \"Hi \\u2014 I can help with lots of things. Short list:\\n\\n- Explain topics and answer questions (science, history, tech, etc.)\\n- Research-style summaries and fact-checking (knowledge up to June 2024)\\n- Step-by-step how-tos and troubleshooting (software, appliances, DIY)\\n- Code help: write, debug, refactor, and explain code\\n- Writing and editing: emails, essays, resumes, creative writing\\n- Math, data analysis, and problem solving (showing steps)\\n- Planning and productivity: trip plans, study plans, schedules\\n- Translations and language help\\n- Recommendations: books, movies, recipes\\n- Quick factual lookups like current weather (I can fetch live weather if you give a city)\\n\\nLimitations: I can\\u2019t browse the web in real time (except certain tools I have), access your accounts or perform actions for you, or replace professional legal/medical advice.\\n\\nWhat would you like help with right now? If you want weather, tell me the city.\",\n", - " \"annotations\": [],\n", - " \"logprobs\": []\n", - " }\n", - " ],\n", - " \"status\": \"completed\",\n", - " \"response_id\": \"caresp_00723da9a08875aa00plRMH3lcvohERaHApDJDERSvoCS5t6qq\",\n", - " \"agent_reference\": {\n", - " \"type\": \"agent_reference\",\n", - " \"name\": \"pydantic-agent\",\n", - " \"version\": \"1\"\n", - " }\n", - " }\n", - " ],\n", - " \"created_at\": 1783613022,\n", - " \"agent_reference\": {\n", - " \"type\": \"agent_reference\",\n", - " \"name\": \"pydantic-agent\",\n", - " \"version\": \"1\"\n", - " },\n", - " \"status\": \"completed\",\n", - " \"completed_at\": 1783613029,\n", - " \"response_id\": \"caresp_00723da9a08875aa00plRMH3lcvohERaHApDJDERSvoCS5t6qq\",\n", - " \"model\": \"\",\n", - " \"agent_session_id\": \"be166a9eefecee80e53ead6697630e7c3c8fd572145dc2011df6e0b96dd6246\",\n", - " \"background\": false\n", - "}\n" - ] - } - ], + "outputs": [], "source": [ "import json\n", "import requests\n", @@ -739,19 +386,7 @@ "execution_count": null, "id": "06ed7a7f", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "APIM_SUFFIX: ba3feqajmh55m\n", - "APIM_SUBSCRIPTION_KEY: af58eceeebbe4dac864e...\n", - "PROJECT_ENDPOINT: https://foundry-agents-ba3feqajmh55m.services.ai.azure.com/api/projects/default-foundry-agents\n", - "\n", - "⚠️ If these are still placeholders, run the infrastructure deployment notebook first!\n" - ] - } - ], + "outputs": [], "source": [ "print(\"Using APIM/Foundry values from the top configuration cell:\")\n", "print(f\"APIM_SUFFIX: {APIM_SUFFIX}\")\n", @@ -766,47 +401,7 @@ "execution_count": null, "id": "b474be31", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "POST https://apim-ba3feqajmh55m.azure-api.net/hosted-agent-responses/agents/pydantic-agent/endpoint/protocols/openai/responses?api-version=v1\n", - "APIM Suffix: ba3feqajmh55m\n", - "Agent Name (in URL path): pydantic-agent\n", - "Content-Type: application/json\n", - "Headers: api-key=af58eceeebbe4dac864e..., Content-Type, Foundry-Features\n", - "Payload: {\n", - " \"input\": \"Hello! What can you help me with?\",\n", - " \"stream\": false\n", - "}\n", - "\n", - "Status: 200\n", - "\n", - "================================================================================\n", - "AGENT RESPONSE (via APIM):\n", - "================================================================================\n", - "Hi — I can help with a wide range of things. A few examples:\n", - "\n", - "- Explain concepts or teach topics (science, history, programming, math) in plain language or with step-by-step reasoning. \n", - "- Answer questions, summarize articles or long text, and highlight key points. \n", - "- Draft, edit, or rewrite text: emails, resumes, essays, reports, or creative writing. \n", - "- Help with coding: write, debug, or explain code in many languages. \n", - "- Plan and organize: study plans, trip itineraries, project steps, or shopping lists. \n", - "- Brainstorm ideas: names, product features, marketing angles, or recipes. \n", - "- Troubleshoot common technical or everyday problems and suggest next steps. \n", - "- Translate text between many languages and adapt tone or formality.\n", - "\n", - "I can also fetch current weather for a specific city if you’d like (just tell me the city). I can’t browse the web in real time or replace professional legal/medical advice, but I can summarize authoritative info and suggest questions to ask a pro.\n", - "\n", - "What would you like help with right now?\n", - "================================================================================\n", - "\n", - "Extracted response stored in 'apim_response' variable\n", - "Agent text stored in 'agent_text' variable\n" - ] - } - ], + "outputs": [], "source": [ "import json\n", "import requests\n", From bf3cab37624d6aee1f7f6d59941fb07aae1f6d17 Mon Sep 17 00:00:00 2001 From: George Ollis Date: Thu, 9 Jul 2026 17:24:59 +0100 Subject: [PATCH 13/17] Remove sensitive configuration values and replace them with placeholders in Strands setup notebook; update README to simplify framework descriptions. --- .../agents/frameworks/01_hosted_agent_strands_setup.ipynb | 6 +++--- .../src/responses/agents/frameworks/README.md | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/01_hosted_agent_strands_setup.ipynb b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/01_hosted_agent_strands_setup.ipynb index 2b3ab755..bfb3b269 100644 --- a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/01_hosted_agent_strands_setup.ipynb +++ b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/01_hosted_agent_strands_setup.ipynb @@ -48,9 +48,9 @@ "outputs": [], "source": [ "# Central configuration (edit here once, then run notebook top-to-bottom)\n", - "ACR_NAME = \"acrba3feqajmh55m\"\n", - "APIM_SUFFIX = \"ba3feqajmh55m\"\n", - "APIM_SUBSCRIPTION_KEY = \"af58eceeebbe4dac864e1f4785d1d497\"\n", + "ACR_NAME = \"X\"\n", + "APIM_SUFFIX = \"X\"\n", + "APIM_SUBSCRIPTION_KEY = \"X\"\n", "PROJECT_ENDPOINT = f\"https://foundry-agents-{APIM_SUFFIX}.services.ai.azure.com/api/projects/default-foundry-agents\"\n", "\n", "AGENT_NAME = \"strands-agent\"\n", diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/README.md b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/README.md index 28e99abd..5ebfd736 100644 --- a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/README.md +++ b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/README.md @@ -9,8 +9,8 @@ This directory contains multiple framework implementations for deploying custom - Save the deployment outputs (APIM suffix, subscription key, Foundry endpoint) 2. **Choose your framework**: - - [**Strands Framework**](#strands-framework) - Custom framework for structured agent responses - - [**Pydantic AI Framework**](#pydantic-ai-framework) - LLM framework with built-in validation + - [**Strands Framework**](#strands-framework) + - [**Pydantic AI Framework**](#pydantic-ai-framework) 3. **Run the corresponding setup notebook**: - For Strands: `01_hosted_agent_strands_setup.ipynb` From 9871c098316f6e4e2d57b38f8077478e29ca0231 Mon Sep 17 00:00:00 2001 From: George Ollis Date: Thu, 9 Jul 2026 17:33:46 +0100 Subject: [PATCH 14/17] Refactor README to enhance descriptions of Strands and Pydantic AI frameworks; remove comparison table and official references for clarity. --- .../src/responses/agents/frameworks/README.md | 29 ++----------------- 1 file changed, 2 insertions(+), 27 deletions(-) diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/README.md b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/README.md index 5ebfd736..2c10d21d 100644 --- a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/README.md +++ b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/README.md @@ -20,36 +20,11 @@ This directory contains multiple framework implementations for deploying custom ### Strands Agents -From the official Strands site, Strands is positioned as an open-source toolkit for building production agents with: -- model/provider flexibility ("any model, any cloud") -- built-in context management and execution limits -- built-in observability and hook-based control points - -In practice for this lab, Strands is a strong fit when you want explicit control over the agent loop and operational behaviors. +https://strandsagents.com/ ### Pydantic AI -From the official Pydantic AI docs, an Agent is the core abstraction and acts as a container for: -- instructions -- tools/toolsets -- optional structured output typing -- dependency typing -- model defaults/settings and composable capabilities - -In practice for this lab, Pydantic AI is a strong fit when typed dependencies and typed/validated outputs are central requirements. - -### At-a-Glance Comparison - -| Dimension | Strands | Pydantic AI | -|---|---|---| -| Primary emphasis | Production agent runtime control | Typed agent design and validation | -| Extensibility model | Hooks + tools + conversation managers | Tools + instructions + capabilities | -| Typing story | Flexible runtime-oriented API | Strong dependency/output typing | -| Good default use case | Tool-heavy workflow automation | Schema/contract-driven agent systems | - -Official references: -- Strands: https://strandsagents.com/ -- Pydantic AI Agents: https://pydantic.dev/docs/ai/core-concepts/agent/ +https://pydantic.dev/docs/ai/core-concepts/agent/ ## Folder Structure From d6cbe2811d33599fe6a90c2fc0fbe19b18daf89e Mon Sep 17 00:00:00 2001 From: George Ollis Date: Thu, 9 Jul 2026 17:41:11 +0100 Subject: [PATCH 15/17] example.env --- .../src/responses/agents/frameworks/pydantic/example.env | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/pydantic/example.env diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/pydantic/example.env b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/pydantic/example.env new file mode 100644 index 00000000..d7135309 --- /dev/null +++ b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/pydantic/example.env @@ -0,0 +1,6 @@ +AZURE_OPENAI_ENDPOINT=https://XXXXXXXXX.azure-api.net/inference/models +AZURE_OPENAI_DEPLOYMENT=gpt-5-mini +AZURE_OPENAI_API_VERSION=2024-05-01-preview +LOG_LEVEL=INFO +STRANDS_LOG_LEVEL=INFO +APIM_SUBSCRIPTION_KEY=XXXXXXXXX \ No newline at end of file From fc3b36ad11bde6d307d5d6d3c0647ef89014a484 Mon Sep 17 00:00:00 2001 From: Nour Shaker <104847536+nourshaker-msft@users.noreply.github.com> Date: Fri, 10 Jul 2026 11:47:32 +0100 Subject: [PATCH 16/17] Updates to the lab and restructuring --- docs/labs-config.json | 6 +- images/ai-foundry-hosted-agents.gif | Bin 465143 -> 458872 bytes .../.gitignore | 3 +- .../README.md | 60 +- ...undry-hosted-agents-custom-framework.ipynb | 595 +++++++++++------- .../clean-up-resources.ipynb | 74 +-- .../main.bicep | 3 +- .../agents => }/frameworks/README.md | 42 +- .../frameworks/pydantic/.dockerignore | 0 .../frameworks/pydantic/.gitignore | 0 .../frameworks/pydantic/Dockerfile | 0 .../agents => }/frameworks/pydantic/README.md | 13 +- .../frameworks/pydantic/example.env | 0 .../agents => }/frameworks/pydantic/image.png | Bin .../agents => }/frameworks/pydantic/main.py | 0 .../pydantic/requirements-pydantic.txt | 0 .../frameworks/strands/.dockerignore | 0 .../agents => }/frameworks/strands/.gitignore | 0 .../agents => }/frameworks/strands/Dockerfile | 0 .../agents => }/frameworks/strands/README.md | 36 +- .../frameworks/strands/example.env | 0 .../agents => }/frameworks/strands/image.png | Bin .../agents => }/frameworks/strands/main.py | 0 .../strands/requirements-strands.txt | 0 .../01_hosted_agent_strands_setup.ipynb | 502 --------------- .../02_hosted_agent_pydantic_setup.ipynb | 497 --------------- modules/cognitive-services/v3/foundry.bicep | 6 +- modules/monitor/v1/appinsights.bicep | 1 + 28 files changed, 449 insertions(+), 1389 deletions(-) rename labs/ai-foundry-hosted-agents-custom-framework/src/{responses/agents => }/frameworks/README.md (82%) rename labs/ai-foundry-hosted-agents-custom-framework/src/{responses/agents => }/frameworks/pydantic/.dockerignore (100%) rename labs/ai-foundry-hosted-agents-custom-framework/src/{responses/agents => }/frameworks/pydantic/.gitignore (100%) rename labs/ai-foundry-hosted-agents-custom-framework/src/{responses/agents => }/frameworks/pydantic/Dockerfile (100%) rename labs/ai-foundry-hosted-agents-custom-framework/src/{responses/agents => }/frameworks/pydantic/README.md (83%) rename labs/ai-foundry-hosted-agents-custom-framework/src/{responses/agents => }/frameworks/pydantic/example.env (100%) rename labs/ai-foundry-hosted-agents-custom-framework/src/{responses/agents => }/frameworks/pydantic/image.png (100%) rename labs/ai-foundry-hosted-agents-custom-framework/src/{responses/agents => }/frameworks/pydantic/main.py (100%) rename labs/ai-foundry-hosted-agents-custom-framework/src/{responses/agents => }/frameworks/pydantic/requirements-pydantic.txt (100%) rename labs/ai-foundry-hosted-agents-custom-framework/src/{responses/agents => }/frameworks/strands/.dockerignore (100%) rename labs/ai-foundry-hosted-agents-custom-framework/src/{responses/agents => }/frameworks/strands/.gitignore (100%) rename labs/ai-foundry-hosted-agents-custom-framework/src/{responses/agents => }/frameworks/strands/Dockerfile (100%) rename labs/ai-foundry-hosted-agents-custom-framework/src/{responses/agents => }/frameworks/strands/README.md (78%) rename labs/ai-foundry-hosted-agents-custom-framework/src/{responses/agents => }/frameworks/strands/example.env (100%) rename labs/ai-foundry-hosted-agents-custom-framework/src/{responses/agents => }/frameworks/strands/image.png (100%) rename labs/ai-foundry-hosted-agents-custom-framework/src/{responses/agents => }/frameworks/strands/main.py (100%) rename labs/ai-foundry-hosted-agents-custom-framework/src/{responses/agents => }/frameworks/strands/requirements-strands.txt (100%) delete mode 100644 labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/01_hosted_agent_strands_setup.ipynb delete mode 100644 labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/02_hosted_agent_pydantic_setup.ipynb diff --git a/docs/labs-config.json b/docs/labs-config.json index 53554e99..c91cb867 100644 --- a/docs/labs-config.json +++ b/docs/labs-config.json @@ -94,14 +94,12 @@ ], "services": [ "Azure AI Foundry", - "Azure API Management", - "Azure Container Apps", - "MCP" + "Azure API Management" ], "shortDescription": "Deploy AI Foundry Hosted Agents built with custom frameworks, including Pydantic AI and Strands.", "detailedDescription": "This lab provides custom framework examples for AI Foundry Hosted Agents, showing how to package and deploy hosted agents built with Pydantic AI and Strands to Azure Container Apps. It includes a Bicep deployment for Azure API Management, Azure AI Foundry, and a GPT-5-Mini model deployment, plus end-to-end setup notebooks and Dockerfiles.", "authors": [ - "nourshaker-msft" + "georgeollis" ], "tags": [], "githubPath": "https://github.com/Azure-Samples/AI-Gateway/tree/main/labs/ai-foundry-hosted-agents-custom-framework", diff --git a/images/ai-foundry-hosted-agents.gif b/images/ai-foundry-hosted-agents.gif index 33dcd4e709449b9f78cc5c402bb489ac8e0e6fe1..03d0b15fdaf4f8f20f2e6c2d6a63d610b35913a9 100644 GIT binary patch delta 397678 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

Hr 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�Ct~J323(fHNmp^1e_xQz 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�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≧(=t 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 M>VI@sgaiZtJH8Snj{pDw diff --git a/labs/ai-foundry-hosted-agents-custom-framework/.gitignore b/labs/ai-foundry-hosted-agents-custom-framework/.gitignore index 656c5a16..cfc63089 100644 --- a/labs/ai-foundry-hosted-agents-custom-framework/.gitignore +++ b/labs/ai-foundry-hosted-agents-custom-framework/.gitignore @@ -2,5 +2,4 @@ __pycache__/ *.pyc .env -main.parameters.generated.json -foundry-user-object-ids.json \ No newline at end of file +params.json \ No newline at end of file diff --git a/labs/ai-foundry-hosted-agents-custom-framework/README.md b/labs/ai-foundry-hosted-agents-custom-framework/README.md index a65897d3..bb9a204c 100644 --- a/labs/ai-foundry-hosted-agents-custom-framework/README.md +++ b/labs/ai-foundry-hosted-agents-custom-framework/README.md @@ -9,7 +9,7 @@ services: - Azure API Management - Container Registry shortDescription: Deploy AI Foundry Hosted Agents built with custom frameworks, including Pydantic AI and Strands. -detailedDescription: This lab provides custom framework examples for AI Foundry Hosted Agents, showing how to package and deploy hosted agents built with Pydantic AI and Strands. It includes a Bicep deployment for Azure API Management, Azure AI Foundry resources, and a GPT-5-Mini model deployment, plus end-to-end setup notebooks and Dockerfiles. +detailedDescription: This lab provides custom framework examples for AI Foundry Hosted Agents, showing how to package and deploy hosted agents built with Pydantic AI and Strands. It includes a Bicep deployment for Azure API Management, Azure AI Foundry resources, and a GPT-5-Mini model deployment, plus a single end-to-end notebook and Dockerfiles. authors: - georgeollis tags: [] @@ -47,12 +47,14 @@ Agents are managed as platform assets in the Foundry control plane, with operati - You want framework flexibility without giving up Foundry governance and enterprise operations. - You need to standardize deployment and operations across multiple agent implementations. -## Infrastructure Deployment Notebook +## Lab Notebook -Use this notebook first to deploy core infrastructure with Bicep: +The lab runs end-to-end from a single notebook. Set the `framework` variable (`strands` or `pydantic`) in the initialization cell to choose which custom-framework agent to build and deploy: - [ai-foundry-hosted-agents-custom-framework.ipynb](ai-foundry-hosted-agents-custom-framework.ipynb) +It deploys the infrastructure with Bicep, builds and pushes the agent image, registers the hosted agent in Foundry, and tests it both directly and through APIM. + ### What gets deployed Core services: @@ -89,32 +91,28 @@ The deployment template is in [main.bicep](main.bicep). ## Prerequisites -- [Python 3.12 or later](https://www.python.org/) -- [VS Code](https://code.visualstudio.com/) with the [Jupyter extension](https://marketplace.visualstudio.com/items?itemName=ms-toolsai.jupyter) -- Python dependencies: install with pip install azure-ai-projects azure-identity requests (or run dependency cells in notebooks) -- [Azure subscription](https://azure.microsoft.com/free/) with Contributor + RBAC Administrator roles, or Owner role -- [Azure CLI](https://learn.microsoft.com/cli/azure/install-azure-cli) installed and authenticated -- [Docker](https://www.docker.com/get-started/) installed and running +- [Python 3.12 or later version](https://www.python.org/) installed +- [VS Code](https://code.visualstudio.com/) installed with the [Jupyter notebook extension](https://marketplace.visualstudio.com/items?itemName=ms-toolsai.jupyter) enabled +- [uv](https://docs.astral.sh/uv/) — run `uv sync` from the repo root to install dependencies +- [An Azure Subscription](https://azure.microsoft.com/free/) with [Contributor](https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles/privileged#contributor) + [RBAC Administrator](https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles/privileged#role-based-access-control-administrator) or [Owner](https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles/privileged#owner) roles +- [Azure CLI](https://learn.microsoft.com/cli/azure/install-azure-cli) installed and [Signed into your Azure subscription](https://learn.microsoft.com/cli/azure/authenticate-azure-cli-interactively) + +> The agent container image is built in Azure Container Registry with `az acr build`, so a local Docker installation is not required. ## Get Started -Step 1: Deploy infrastructure -- Run all cells in [ai-foundry-hosted-agents-custom-framework.ipynb](ai-foundry-hosted-agents-custom-framework.ipynb) -- This provisions Foundry resources, APIM, ACR, and monitoring -- Capture outputs (project endpoint, ACR login server, APIM suffix, subscription key) +Proceed by opening the [Jupyter notebook](ai-foundry-hosted-agents-custom-framework.ipynb) and follow the steps provided. + +The notebook runs top-to-bottom and: + +1. Deploys the infrastructure with Bicep (Foundry resources, APIM, ACR, monitoring). +2. Builds and pushes the selected framework's agent image to ACR with `az acr build`. +3. Registers the container image as a Foundry Hosted Agent. +4. Tests the agent directly against Foundry and through APIM. -Step 2: Choose and deploy your agent -- Open one setup notebook and run top-to-bottom: - - [src/responses/agents/frameworks/01_hosted_agent_strands_setup.ipynb](src/responses/agents/frameworks/01_hosted_agent_strands_setup.ipynb) - - [src/responses/agents/frameworks/02_hosted_agent_pydantic_setup.ipynb](src/responses/agents/frameworks/02_hosted_agent_pydantic_setup.ipynb) -- Each notebook performs: - - Docker build and push to ACR - - Hosted agent version creation in Foundry - - Direct test to Foundry (baseline) - - APIM test (production-like path) +Set the `framework` variable in the initialization cell to `strands` or `pydantic` to switch frameworks, then re-run the build, deploy, and test cells. -Step 3: Invoke through APIM -- Use agent-specific URL path routing: +Invoke a deployed agent through APIM using agent-specific URL path routing: ```http POST https://apim-{suffix}.azure-api.net/hosted-agent-responses/agents/{agentName}/endpoint/protocols/openai/responses?api-version=v1 @@ -136,15 +134,15 @@ Example body: ## Test Flow Explained -Direct test (Section 3 in framework notebooks): -- Calls Foundry Hosted Agent Responses API directly -- Uses bearer token from Azure CLI credential with audience https://ai.azure.com/.default +Direct test: +- Calls the Foundry Hosted Agent Responses API directly +- Uses a bearer token from the Azure CLI credential with audience https://ai.azure.com/.default - Best baseline for runtime/connectivity troubleshooting -APIM test (Section 4 in framework notebooks): -- Routes through APIM using api-key -- APIM injects managed identity token and required headers -- Validates production-like client -> APIM -> Foundry path +APIM test: +- Routes through APIM using the subscription key (api-key) +- APIM injects the managed identity token and required headers +- Validates the production-like client -> APIM -> Foundry path ## Clean Up Resources diff --git a/labs/ai-foundry-hosted-agents-custom-framework/ai-foundry-hosted-agents-custom-framework.ipynb b/labs/ai-foundry-hosted-agents-custom-framework/ai-foundry-hosted-agents-custom-framework.ipynb index 6fa9a6d5..e3af81ec 100644 --- a/labs/ai-foundry-hosted-agents-custom-framework/ai-foundry-hosted-agents-custom-framework.ipynb +++ b/labs/ai-foundry-hosted-agents-custom-framework/ai-foundry-hosted-agents-custom-framework.ipynb @@ -2,324 +2,449 @@ "cells": [ { "cell_type": "markdown", - "id": "db72bfd0", + "id": "be6ee817", "metadata": {}, "source": [ - "# Microsoft Foundry Hosted Agents (Custom Frameworks)\n", + "# APIM ❤️ Microsoft Foundry\n", "\n", - "This notebook deploys the shared lab infrastructure using `main.bicep`:\n", + "## Microsoft Foundry Hosted Agents (Custom Frameworks) lab\n", + "![flow](../../images/ai-foundry-hosted-agents.gif)\n", "\n", - "- Azure API Management (APIM)\n", - "- Microsoft Foundry resources (one for model hosting and one for hosted-agent runtime hosting)\n", - "- GPT-5-Mini model deployment\n", + "This lab deploys a **custom-framework agent** ([Strands](https://strandsagents.com/) or [Pydantic AI](https://ai.pydantic.dev/)) as a **Microsoft Foundry Hosted Agent** and exposes it through Azure API Management (APIM).\n", "\n", - "## Why run custom frameworks on Foundry Hosted Agents?\n", + "The lab is backed by two Microsoft Foundry resources:\n", + "- **foundry-models**: hosts the `gpt-5-mini` model deployment, consumed by the agent through APIM.\n", + "- **foundry-agents**: hosts the custom-framework runtime as a Hosted Agent (Responses protocol v1.0.0).\n", "\n", - "1. Built-in observability, tracing, and monitoring.\n", - "Foundry provides a standard operational surface for agent runs, telemetry, and diagnostics so teams can troubleshoot faster and keep a consistent monitoring model across different agent runtimes.\n", + "### Why run custom frameworks on Foundry Hosted Agents?\n", "\n", - "2. Agent Identity and RBAC by default.\n", - "Your runtime is registered as a Foundry Agent and gets an Agent Identity, enabling least-privilege access to downstream Azure resources (for example, storage, search, or APIs) through RBAC instead of embedded secrets.\n", + "- Built-in observability, tracing, and monitoring across agent runtimes.\n", + "- Agent Identity and RBAC by default (least-privilege access without embedded secrets).\n", + "- Foundry guardrails, governance, evaluations, and red-teaming integration.\n", + "- Discovery and reuse across teams through the Foundry control plane.\n", "\n", - "3. Foundry guardrails and governance.\n", - "Hosted agents can inherit platform safety controls and governance policies, helping you enforce security and compliance consistently even when the runtime framework is custom.\n", + "Clients invoke a hosted agent by specifying the **agent name in the URL path**, so multiple agents are served without changing the APIM configuration:\n", "\n", - "4. Discovery through Agent365.\n", - "Publishing into the Foundry ecosystem makes agents easier to discover and reuse across teams, reducing duplicate implementations.\n", - "\n", - "5. Native evaluation and risk testing integration.\n", - "You can plug directly into Foundry evaluations, red teaming, and cost-estimation workflows to compare quality, safety, and spend using the same platform tooling.\n", - "\n", - "6. Control plane and platform operations.\n", - "Agents are managed as platform assets in the Foundry control plane, with operational benefits such as managed hosting lifecycle, scaling, and centralized administration.\n", - "\n", - "## When custom frameworks are a good fit\n", + "```\n", + "POST {apim-gateway}/hosted-agent-responses/agents/{agentName}/endpoint/protocols/openai/responses?api-version=v1\n", + "```\n", "\n", - "- You need framework-specific capabilities (for example, Pydantic AI or Strands primitives) not available in a default runtime.\n", - "- You want framework flexibility without giving up Foundry governance and enterprise operations.\n", - "- You need to standardize deployment and operations across multiple agent implementations.\n", + "### Prerequisites\n", "\n", - "After deployment, continue with one framework-specific setup notebook:\n", + "- [Python 3.12 or later version](https://www.python.org/) installed\n", + "- [VS Code](https://code.visualstudio.com/) installed with the [Jupyter notebook extension](https://marketplace.visualstudio.com/items?itemName=ms-toolsai.jupyter) enabled\n", + "- [uv](https://docs.astral.sh/uv/) — run `uv sync` from the repo root to install dependencies\n", + "- [An Azure Subscription](https://azure.microsoft.com/free/) with [Contributor](https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles/privileged#contributor) + [RBAC Administrator](https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles/privileged#role-based-access-control-administrator) or [Owner](https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles/privileged#owner) roles\n", + "- [Azure CLI](https://learn.microsoft.com/cli/azure/install-azure-cli) installed and [Signed into your Azure subscription](https://learn.microsoft.com/cli/azure/authenticate-azure-cli-interactively)\n", "\n", - "- `src/responses/agents/frameworks/01_hosted_agent_strands_setup.ipynb`\n", - "- `src/responses/agents/frameworks/02_hosted_agent_pydantic_setup.ipynb`" + "▶️ Click `Run All` to execute all steps sequentially, or execute them `Step by Step`..." ] }, { - "cell_type": "code", - "execution_count": null, - "id": "99068750", + "cell_type": "markdown", + "id": "3268dff6", "metadata": {}, - "outputs": [], "source": [ - "import json\n", - "import os\n", - "import subprocess\n", - "from pathlib import Path\n", - "\n", - "def run(cmd):\n", - " print('\\n$ ' + ' '.join(cmd))\n", - " result = subprocess.run(cmd, capture_output=True, text=True)\n", - " if result.stdout:\n", - " print(result.stdout)\n", - " if result.returncode != 0:\n", - " if result.stderr:\n", - " print(result.stderr)\n", - " raise RuntimeError(f'Command failed: {result.returncode}')\n", - " return result\n", - "\n", - "lab_dir = Path.cwd()\n", - "if not (lab_dir / 'main.bicep').exists():\n", - " raise FileNotFoundError('Run this notebook from labs/ai-foundry-hosted-agents-custom-framework')\n", - "\n", - "print(f'Lab directory: {lab_dir}')" + "\n", + "### 0️⃣ Initialize notebook variables\n", + "\n", + "Configure resource names, regions, the model deployment, and the hosted-agent framework used throughout this lab. Set `framework` to `'strands'` or `'pydantic'` to choose which custom-framework agent to build and deploy." ] }, { "cell_type": "code", "execution_count": null, - "id": "1c47a2ce", + "id": "86f857ab", "metadata": {}, "outputs": [], "source": [ - "# Update these values as needed\n", - "subscription_id = 'x'\n", - "resource_group = 'rg-aigw-hosted-custom-framework'\n", - "location = 'swedencentral'\n", - "deployment_name = 'deploy-hosted-custom-framework'\n", - "\n", - "# Two Foundry resources:\n", - "# - index 0: model hosting\n", - "# - index 1: hosted-agent hosting\n", - "ai_services_config = [\n", - " {\n", - " 'name': 'foundry-models',\n", - " 'location': location,\n", - " 'priority': 1,\n", - " 'weight': 100\n", - " },\n", - " {\n", - " 'name': 'foundry-agents',\n", - " 'location': location,\n", - " 'priority': 1,\n", - " 'weight': 100\n", - " }\n", + "import os, sys, json\n", + "sys.path.insert(1, '../../shared') # add the shared directory to the Python path\n", + "import utils\n", + "\n", + "deployment_name = os.path.basename(os.path.dirname(globals()['__vsc_ipynb_file__']))\n", + "resource_group_name = f\"lab-{deployment_name}\"\n", + "resource_group_location = 'swedencentral'\n", + "\n", + "# Two Microsoft Foundry resources:\n", + "# foundry-models: hosts the inference model consumed by the agent\n", + "# foundry-agents: hosts the custom-framework runtime as a Hosted Agent (index 1)\n", + "aiservices_config = [\n", + " {\"name\": \"foundry-models\", \"location\": \"swedencentral\"},\n", + " {\"name\": \"foundry-agents\", \"location\": \"swedencentral\"},\n", "]\n", "\n", - "# gpt-5-mini is available in this subscription/region and was deployed manually.\n", - "# Keep the version aligned with the manually deployed model.\n", + "# Model deployed to foundry-models and consumed by the hosted agent through APIM\n", "models_config = [\n", - " {\n", - " 'aiservice': 'foundry-models',\n", - " 'name': 'gpt-5-mini',\n", - " 'publisher': 'OpenAI',\n", - " 'version': '2025-08-07',\n", - " 'sku': 'GlobalStandard',\n", - " 'capacity': 10\n", - " }\n", + " {\"name\": \"gpt-5-mini\", \"publisher\": \"OpenAI\", \"version\": \"2025-08-07\",\n", + " \"sku\": \"GlobalStandard\", \"capacity\": 10, \"aiservice\": \"foundry-models\"}\n", "]\n", "\n", - "apim_subscriptions = [\n", - " {\n", - " 'name': 'starter',\n", - " 'displayName': 'Starter',\n", - " 'scope': '/apis'\n", - " }\n", - "]\n", + "# APIM configuration\n", + "apim_sku = 'Basicv2'\n", + "apim_subscriptions_config = [{\"name\": \"subscription1\", \"displayName\": \"Subscription 1\"}]\n", "\n", - "# Deploy Foundry infrastructure and APIM with hosted-agent responses API support.\n", - "# Hosted agents are invoked by agent-specific URL path through APIM:\n", - "# /hosted-agent-responses/agents/{agentName}/endpoint/protocols/openai/responses\n", - "enable_hosted_agent_responses_api = True\n", + "# API paths\n", + "inference_api_path = 'inference'\n", + "inference_api_type = 'AzureAI'\n", + "hosted_agent_responses_api_path = 'hosted-agent-responses'\n", + "foundry_project_name = 'default'\n", + "foundry_agent_ai_service_index = 1\n", + "\n", + "frameworks = {\n", + " 'strands': {'agent_name': 'strands-agent', 'image': 'strands-agent'},\n", + " 'pydantic': {'agent_name': 'pydantic-agent', 'image': 'pydantic-agent'},\n", + "}\n", "\n", - "print('Configuration ready. Set real values before running deployment.')\n", - "print('Note: APIM is configured to support hosted-agent path routing.')\n", - "print('Clients target an agent by setting {agentName} in the request URL path.')" + "build_version = 1\n", + "\n", + "utils.print_ok('Notebook initialized')" + ] + }, + { + "cell_type": "markdown", + "id": "d15a64d3", + "metadata": {}, + "source": [ + "\n", + "### 1️⃣ Verify the Azure CLI and the connected Azure subscription\n", + "\n", + "The following commands ensure that you have the latest version of the Azure CLI and that the Azure CLI is connected to your Azure subscription." ] }, { "cell_type": "code", "execution_count": null, - "id": "91b2888b", + "id": "7b4bdd3a", "metadata": {}, "outputs": [], "source": [ - "from pathlib import Path\n", - "import json\n", - "import shutil\n", - "\n", - "# Run Azure CLI lookups for Foundry user object IDs and save the results locally.\n", - "# Update the user_principal_names list with any users you want to grant Foundry User access.\n", - "user_principal_names = [\n", - " # 'user@contoso.com',\n", - "]\n", - "\n", - "az_cmd = shutil.which('az.cmd') or shutil.which('az')\n", - "if not az_cmd:\n", - " raise FileNotFoundError('Azure CLI was not found on PATH. Install Azure CLI or add az.cmd to PATH.')\n", - "\n", - "\n", - "def az_cli(args):\n", - " command = ['cmd', '/c', az_cmd, *args] if az_cmd.lower().endswith('.cmd') else [az_cmd, *args]\n", - " return run(command).stdout.strip()\n", - "\n", - "signed_in_user_id = az_cli(['ad', 'signed-in-user', 'show', '--query', 'id', '-o', 'tsv'])\n", - "user_object_ids = []\n", - "if signed_in_user_id:\n", - " user_object_ids.append(signed_in_user_id)\n", - "\n", - "for user_principal_name in user_principal_names:\n", - " user_id = az_cli(['ad', 'user', 'show', '--id', user_principal_name, '--query', 'id', '-o', 'tsv'])\n", - " if user_id:\n", - " user_object_ids.append(user_id)\n", - "\n", - "foundry_user_object_ids = list(dict.fromkeys(user_object_ids))\n", + "output = utils.run('az account show', 'Retrieved az account', 'Failed to get the current az account')\n", + "\n", + "if output.success and output.json_data:\n", + " current_user = output.json_data['user']['name']\n", + " tenant_id = output.json_data['tenantId']\n", + " subscription_id = output.json_data['id']\n", + " utils.print_info(f'Current user: {current_user}')\n", + " utils.print_info(f'Tenant ID: {tenant_id}')\n", + " utils.print_info(f'Subscription: {subscription_id}')\n", + "\n", + "# Signed-in user object id is granted the Foundry User (Azure AI User) role on the Foundry resources\n", + "output = utils.run('az ad signed-in-user show', 'Retrieved signed-in user', 'Failed to retrieve signed-in user')\n", + "foundry_user_object_ids = [output.json_data['id']] if output.success and output.json_data else []" + ] + }, + { + "cell_type": "markdown", + "id": "4f38fce7", + "metadata": {}, + "source": [ + "\n", + "### 2️⃣ Create deployment using 🦾 Bicep\n", "\n", - "output_file = lab_dir / 'foundry-user-object-ids.json'\n", - "output_file.write_text(json.dumps(foundry_user_object_ids, indent=2), encoding='utf-8')\n", + "This lab uses [Bicep](https://learn.microsoft.com/azure/azure-resource-manager/bicep/overview?tabs=bicep) to declaratively define all the resources deployed in the resource group. Change the parameters or the [main.bicep](main.bicep) directly to try different configurations.\n", "\n", - "print('Foundry user object IDs:')\n", - "print(json.dumps(foundry_user_object_ids, indent=2))\n", - "print(f'Saved to: {output_file}')" + "Deployed resources include:\n", + "- Log Analytics Workspace + Application Insights\n", + "- Azure API Management (Basicv2) with the inference API and the hosted-agent responses API\n", + "- Two Microsoft Foundry resources (`foundry-models` with `gpt-5-mini`, `foundry-agents` for the hosted agent)\n", + "- Azure Container Registry for the agent container image\n", + "- Role assignments for ACR and Foundry access" ] }, { "cell_type": "code", "execution_count": null, - "id": "3c1be18b", + "id": "b89daab8", "metadata": {}, "outputs": [], "source": [ - "# Create resource group and deploy Bicep\n", - "# Ensure Azure CLI directory is available to subprocess calls in this kernel\n", - "\n", - "import os\n", - "\n", - "az_dir = str(Path(az_cmd).parent)\n", - "if az_dir not in os.environ.get('PATH', ''):\n", - " os.environ['PATH'] = az_dir + os.pathsep + os.environ.get('PATH', '')\n", + "# Create the resource group if it doesn't exist\n", + "utils.create_resource_group(resource_group_name, resource_group_location)\n", "\n", - "def az_run(args):\n", - " command = ['cmd', '/c', az_cmd, *args] if az_cmd.lower().endswith('.cmd') else [az_cmd, *args]\n", - " return run(command)\n", - "\n", - "az_run(['account', 'set', '--subscription', subscription_id])\n", - "az_run(['group', 'create', '--name', resource_group, '--location', location])\n", - "\n", - "parameters_file = lab_dir / 'main.parameters.generated.json'\n", - "parameters = {\n", + "# Define the Bicep parameters\n", + "bicep_parameters = {\n", " '$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#',\n", " 'contentVersion': '1.0.0.0',\n", " 'parameters': {\n", - " 'aiServicesConfig': {'value': ai_services_config},\n", - " 'modelsConfig': {'value': models_config},\n", - " 'apimSku': {'value': 'Basicv2'},\n", - " 'apimSubscriptionsConfig': {'value': apim_subscriptions},\n", - " 'inferenceAPIPath': {'value': 'inference'},\n", - " 'inferenceAPIType': {'value': 'AzureAI'},\n", - " 'foundryProjectName': {'value': 'default'},\n", - " 'foundryAgentAiServiceIndex': {'value': 1},\n", - " 'foundryUserObjectIds': {'value': foundry_user_object_ids},\n", - " 'enableHostedAgentResponsesApi': {'value': enable_hosted_agent_responses_api},\n", - " 'hostedAgentResponsesApiPath': {'value': 'hosted-agent-responses'}\n", + " 'apimSku': {'value': apim_sku},\n", + " 'aiServicesConfig': {'value': aiservices_config},\n", + " 'modelsConfig': {'value': models_config},\n", + " 'apimSubscriptionsConfig': {'value': apim_subscriptions_config},\n", + " 'inferenceAPIPath': {'value': inference_api_path},\n", + " 'inferenceAPIType': {'value': inference_api_type},\n", + " 'foundryProjectName': {'value': foundry_project_name},\n", + " 'foundryAgentAiServiceIndex': {'value': foundry_agent_ai_service_index},\n", + " 'foundryUserObjectIds': {'value': foundry_user_object_ids},\n", + " 'enableHostedAgentResponsesApi': {'value': True},\n", + " 'hostedAgentResponsesApiPath': {'value': hosted_agent_responses_api_path},\n", " }\n", "}\n", "\n", - "parameters_file.write_text(json.dumps(parameters, indent=2), encoding='utf-8')\n", - "print(f'Wrote parameters: {parameters_file}')\n", - "\n", - "# Ensure Bicep is available, then validate before create\n", - "az_run(['bicep', 'install'])\n", - "\n", - "template_file = str((lab_dir / 'main.bicep').resolve())\n", - "parameters_arg = f\"@{parameters_file.resolve()}\"\n", - "\n", - "# Validate first, but do not stop the notebook on transient/CLI validation failures.\n", - "try:\n", - " az_run([\n", - " 'deployment', 'group', 'validate',\n", - " '--resource-group', resource_group,\n", - " '--template-file', template_file,\n", - " '--parameters', parameters_arg,\n", - " '--only-show-errors'\n", - " ])\n", - "except RuntimeError as ex:\n", - " print(f'Validation failed, continuing to deployment create step: {ex}')\n", - "\n", - "result = az_run([\n", - " 'deployment', 'group', 'create',\n", - " '--resource-group', resource_group,\n", - " '--name', deployment_name,\n", - " '--template-file', template_file,\n", - " '--parameters', parameters_arg,\n", - " '--only-show-errors'\n", - "])" + "# Write the parameters to the params.json file\n", + "with open('params.json', 'w') as bicep_parameters_file:\n", + " bicep_parameters_file.write(json.dumps(bicep_parameters))\n", + "\n", + "# Run the deployment\n", + "output = utils.run(\n", + " f'az deployment group create --name {deployment_name} --resource-group {resource_group_name} --template-file main.bicep --parameters params.json',\n", + " f\"Deployment '{deployment_name}' succeeded\",\n", + " f\"Deployment '{deployment_name}' failed\"\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "71c43a83", + "metadata": {}, + "source": [ + "\n", + "### 3️⃣ Get the deployment outputs\n", + "\n", + "Retrieve the gateway URL, the subscription key, the Container Registry name, and the Foundry agent project endpoint used by the remaining steps." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6f6cc281", + "metadata": {}, + "outputs": [], + "source": [ + "output = utils.run(\n", + " f'az deployment group show --name {deployment_name} -g {resource_group_name}',\n", + " f'Retrieved deployment: {deployment_name}',\n", + " f'Failed to retrieve deployment: {deployment_name}'\n", + ")\n", + "\n", + "if output.success and output.json_data:\n", + " apim_resource_gateway_url = utils.get_deployment_output(output, 'apimResourceGatewayURL', 'APIM Gateway URL')\n", + " container_registry_name = utils.get_deployment_output(output, 'containerRegistryName', 'Container Registry Name')\n", + " foundry_agent_project_endpoint = utils.get_deployment_output(output, 'foundryAgentProjectEndpoint', 'Foundry Agent Project Endpoint')\n", + "\n", + " apim_subscriptions = json.loads(utils.get_deployment_output(output, 'apimSubscriptions').replace(\"\\'\", '\"'))\n", + " for subscription in apim_subscriptions:\n", + " utils.print_info(f\"Subscription Name: {subscription['name']}\")\n", + " utils.print_info(f\"Subscription Key: ****{subscription['key'][-4:]}\")\n", + " api_key = apim_subscriptions[0].get('key')\n", + "\n", + " # Inference endpoint the hosted agent uses to call the model through APIM\n", + " inference_endpoint = f'{apim_resource_gateway_url}/{inference_api_path}/models'" + ] + }, + { + "cell_type": "markdown", + "id": "c52019af", + "metadata": {}, + "source": [ + "\n", + "### 4️⃣ Build and push the agent image to the Container Registry\n", + "\n", + "Build the selected framework's Docker image directly in Azure Container Registry with `az acr build` (no local Docker required). The source is in [`src/frameworks/`](src/frameworks/README.md)." ] }, { "cell_type": "code", "execution_count": null, - "id": "a9f37375", + "id": "9eafa83b", "metadata": {}, "outputs": [], "source": [ - "# Print key outputs\n", - "outputs = run([\n", - " 'az', 'deployment', 'group', 'show',\n", - " '--resource-group', resource_group,\n", - " '--name', deployment_name,\n", - " '--query', 'properties.outputs',\n", - " '-o', 'json'\n", - "]).stdout\n", - "print(json.dumps(json.loads(outputs), indent=2))" + "# Choose your framework: 'strands' or 'pydantic'\n", + "# For Hosted agent framework to build and deploy\n", + "framework = 'pydantic'\n", + "\n", + "build_version = build_version + 1\n", + "agent_name = frameworks[framework]['agent_name']\n", + "agent_image_tag = f\"{frameworks[framework]['image']}:{build_version}\"\n", + "framework_src = f\"src/responses/agents/frameworks/{framework}\"\n", + "model_deployment_name = models_config[0]['name']\n", + "\n", + "output = utils.run(\n", + " f'az acr build --registry {container_registry_name} --image {agent_image_tag} {framework_src}',\n", + " f\"'{framework}' agent image built and pushed: {agent_image_tag}\",\n", + " f\"Failed to build and push the '{framework}' agent image\"\n", + ")\n", + "\n", + "image_uri = f'{container_registry_name}.azurecr.io/{agent_image_tag}'\n", + "utils.print_info(f'Image URI: {image_uri}')" ] }, { "cell_type": "markdown", - "id": "d0249aaa", + "id": "8fa67ea3", "metadata": {}, "source": [ - "## Deployment Workflow\n", + "\n", + "### 5️⃣ Create the hosted agent version in Microsoft Foundry\n", "\n", - "**One-time deployment:**\n", + "Register the container image as a **Foundry Hosted Agent** (Responses protocol v1.0.0). Foundry auto-assigns a version suffix (`:1`, `:2`, ...). The agent calls the model through the APIM inference API using the injected environment variables." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "25c56c67", + "metadata": {}, + "outputs": [], + "source": [ + "output = utils.run(\n", + " 'pip install azure-ai-projects==2.3.0 azure-identity -q',\n", + " 'Foundry SDK installed',\n", + " 'Failed to install the Foundry SDK'\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2db292e2", + "metadata": {}, + "outputs": [], + "source": [ + "from azure.ai.projects import AIProjectClient\n", + "from azure.ai.projects.models import (\n", + " HostedAgentDefinition,\n", + " ProtocolVersionRecord,\n", + " AgentEndpointProtocol,\n", + " ContainerConfiguration,\n", + ")\n", + "from azure.identity import AzureCliCredential\n", + "\n", + "credential = AzureCliCredential()\n", + "\n", + "project = AIProjectClient(\n", + " endpoint=foundry_agent_project_endpoint,\n", + " credential=credential,\n", + " allow_preview=True,\n", + ")\n", + "\n", + "agent = project.agents.create_version(\n", + " agent_name=agent_name,\n", + " definition=HostedAgentDefinition(\n", + " protocol_versions=[\n", + " ProtocolVersionRecord(protocol=AgentEndpointProtocol.RESPONSES, version='1.0.0')\n", + " ],\n", + " cpu='1',\n", + " memory='2Gi',\n", + " container_configuration=ContainerConfiguration(image=image_uri),\n", + " environment_variables={\n", + " 'AZURE_OPENAI_ENDPOINT': inference_endpoint,\n", + " 'AZURE_OPENAI_API_VERSION': '2024-05-01-preview',\n", + " 'AZURE_OPENAI_DEPLOYMENT': model_deployment_name,\n", + " 'APIM_SUBSCRIPTION_KEY': api_key,\n", + " 'LOG_LEVEL': 'INFO',\n", + " #'OTEL_SDK_DISABLED': 'true'\n", + " },\n", + " ),\n", + ")\n", + "\n", + "utils.print_ok(f'Agent created: {agent.name}, version: {agent.version}, id: {agent.id}')" + ] + }, + { + "cell_type": "markdown", + "id": "a3e074e6", + "metadata": {}, + "source": [ + "\n", + "### 🧪 Test the hosted agent directly\n", "\n", - "1. Run this notebook to deploy all Foundry and APIM infrastructure at once\n", - " - Foundry resources (models + agents)\n", - " - APIM with inference API and hosted-agent responses API\n", - " - All role assignments\n", - " \n", - "**Then proceed to framework-specific setup:**\n", + "Call the Foundry Responses API directly using your Azure CLI credential. This is the baseline test — if it fails, the APIM test will fail too. Wait until the agent reaches the `Running` state before testing.\n", "\n", - "2. Use one of the framework notebooks under `src/responses/agents/frameworks/` to build, push, and deploy the hosted agent:\n", - " - `src/responses/agents/frameworks/01_hosted_agent_strands_setup.ipynb`\n", - " - `src/responses/agents/frameworks/02_hosted_agent_pydantic_setup.ipynb`\n", - " - The agent will be created with a name and version (e.g., `strands-agent:1`)\n", - " \n", - "**Agent routing via APIM:**\n", + "> **Tip**: Use the [tracing tool](../../tools/tracing.ipynb) to monitor token usage and troubleshoot the [policy](hosted-agent-policy.xml)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "39f41137", + "metadata": {}, + "outputs": [], + "source": [ + "import requests\n", "\n", - "Foundry Hosted Agents require the **agent name in the URL path** (not in the request body):\n", + "query = 'Hello! What can you help me with?'\n", + "url = f'{foundry_agent_project_endpoint}/agents/{agent_name}/endpoint/protocols/openai/responses'\n", "\n", - "**The hosted agent responses API will be available at:**\n", - "```\n", - "POST https://apim-{suffix}.azure-api.net/hosted-agent-responses/agents/{agentName}/endpoint/protocols/openai/responses?api-version=v1\n", - "```\n", + "token = credential.get_token('https://ai.azure.com/.default')\n", + "headers = {\n", + " 'Authorization': f'Bearer {token.token}',\n", + " 'Content-Type': 'application/json',\n", + " 'Foundry-Features': 'HostedAgents=V1Preview',\n", + "}\n", + "\n", + "utils.print_message(f'Q: {query}')\n", + "response = requests.post(url, headers=headers, json={'input': query, 'stream': False}, params={'api-version': 'v1'}, timeout=120)\n", + "\n", + "if response.status_code == 200:\n", + " utils.print_ok('Agent responded successfully (direct)')\n", + " print(json.dumps(response.json(), indent=2))\n", + "else:\n", + " utils.print_error(f'Agent returned HTTP {response.status_code}: {response.text}')" + ] + }, + { + "cell_type": "markdown", + "id": "8b8c9d90", + "metadata": {}, + "source": [ + "\n", + "### 🧪 Test the hosted agent through APIM\n", + "\n", + "Route the request through Azure API Management using only the subscription key. APIM injects the managed-identity bearer token, forces `Content-Type: application/json`, and adds the `Foundry-Features` header. The target agent is selected by the `{agentName}` segment in the URL path." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4b8f8455", + "metadata": {}, + "outputs": [], + "source": [ + "import requests\n", "\n", - "- `{agentName}`: The name of your deployed Foundry agent (e.g., `strands-agent`, `pydantic-agent`)\n", - "- Header: `api-key: {subscription-key-from-outputs}`\n", - "- Header: `Content-Type: application/json`\n", - "- Query parameter: `api-version=v1`\n", + "query = 'Hello! What can you help me with?'\n", + "url = f'{apim_resource_gateway_url}/{hosted_agent_responses_api_path}/agents/{agent_name}/endpoint/protocols/openai/responses'\n", "\n", - "**To use multiple agents:**\n", + "headers = {\n", + " 'api-key': api_key,\n", + " 'Content-Type': 'application/json',\n", + " 'Foundry-Features': 'HostedAgents=V1Preview',\n", + "}\n", + "\n", + "utils.print_message(f'Q: {query}')\n", + "response = requests.post(url, headers=headers, json={'input': query, 'stream': False}, params={'api-version': 'v1'}, timeout=120)\n", + "\n", + "if response.status_code == 200:\n", + " utils.print_ok('Agent responded successfully (via APIM)')\n", + " result = response.json()\n", + " agent_text = None\n", + " if result.get('output'):\n", + " content = result['output'][0].get('content', [])\n", + " if content:\n", + " agent_text = content[0].get('text')\n", + " utils.print_ok(f'A: {agent_text}') if agent_text else print(json.dumps(result, indent=2))\n", + "else:\n", + " utils.print_error(f'Agent returned HTTP {response.status_code}: {response.text}')" + ] + }, + { + "cell_type": "markdown", + "id": "1641aeaf", + "metadata": {}, + "source": [ + "\n", + "### 🗑️ Clean up resources\n", "\n", - "1. Deploy another agent to Foundry using a framework setup notebook\n", - "2. Update `{agentName}` in the APIM URL path for each call\n", - "3. APIM routes to the correct agent based on URL path without policy changes" + "When you're finished with the lab, you should remove all your deployed resources from Azure to avoid extra charges and keep your Azure subscription uncluttered.\n", + "Use the [clean-up-resources notebook](clean-up-resources.ipynb) for that." ] } ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "pip2uv", "language": "python", "name": "python3" }, @@ -333,7 +458,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.10" + "version": "3.12.13" } }, "nbformat": 4, diff --git a/labs/ai-foundry-hosted-agents-custom-framework/clean-up-resources.ipynb b/labs/ai-foundry-hosted-agents-custom-framework/clean-up-resources.ipynb index 5e37406e..bab5ea71 100644 --- a/labs/ai-foundry-hosted-agents-custom-framework/clean-up-resources.ipynb +++ b/labs/ai-foundry-hosted-agents-custom-framework/clean-up-resources.ipynb @@ -2,81 +2,37 @@ "cells": [ { "cell_type": "markdown", - "id": "2feb47db", + "id": "f27aae93", "metadata": {}, "source": [ - "# Clean Up Resources\n", + "### 🗑️ Clean up resources\n", "\n", - "This notebook removes the resource group created for the `ai-foundry-hosted-agents-custom-framework` lab." + "When you're finished with the lab, you should remove all your deployed resources from Azure to avoid extra charges and keep your Azure subscription uncluttered.\n", + "\n", + "The cell below deletes the resource group and everything in it." ] }, { "cell_type": "code", - "execution_count": 1, - "id": "3ab6bfd0", + "execution_count": null, + "id": "b90b2598", "metadata": {}, "outputs": [], "source": [ - "import shutil\n", - "import subprocess\n", - "import sys\n", - "\n", - "_az = (\n", - " shutil.which(\"az\")\n", - " or shutil.which(\"az.cmd\")\n", - " or r\"C:\\Program Files\\Microsoft SDKs\\Azure\\CLI2\\wbin\\az.CMD\"\n", - " )\n", - "\n", - "if not _az:\n", - " raise FileNotFoundError(\n", - " \"Azure CLI executable was not found. Install Azure CLI or add it to PATH.\"\n", - " )\n", + "import os, sys\n", + "sys.path.insert(1, '../../shared') # add the shared directory to the Python path\n", + "import utils\n", "\n", - "def run(cmd):\n", - " if cmd and cmd[0] == \"az\":\n", - " cmd = [_az] + cmd[1:]\n", - " print(\"\\n$ \" + \" \".join(cmd))\n", - " result = subprocess.run(cmd, capture_output=True, text=True)\n", - " if result.stdout:\n", - " print(result.stdout)\n", - " if result.returncode != 0:\n", - " if result.stderr:\n", - " print(result.stderr)\n", - " raise RuntimeError(f\"Command failed: {result.returncode}\")\n", + "deployment_name = os.path.basename(os.path.dirname(globals()['__vsc_ipynb_file__']))\n", + "resource_group_name = f\"lab-{deployment_name}\"\n", "\n", - "subscription_id = \"baba41cf-c01d-4a55-b6c5-ca494b802be5\"\n", - "resource_group = \"rg-aigw-hosted-custom-framework\"" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "5083d437", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "$ C:\\Program Files\\Microsoft SDKs\\Azure\\CLI2\\wbin\\az.CMD account set --subscription baba41cf-c01d-4a55-b6c5-ca494b802be5\n", - "\n", - "$ C:\\Program Files\\Microsoft SDKs\\Azure\\CLI2\\wbin\\az.CMD group delete --name rg-aigw-hosted-custom-framework --yes --no-wait\n", - "Deletion started. Use az group show to verify completion.\n" - ] - } - ], - "source": [ - "# Delete lab resources\n", - "run([\"az\", \"account\", \"set\", \"--subscription\", subscription_id])\n", - "run([\"az\", \"group\", \"delete\", \"--name\", resource_group, \"--yes\", \"--no-wait\"])\n", - "print(\"Deletion started. Use az group show to verify completion.\")" + "utils.cleanup_resources(deployment_name, resource_group_name=resource_group_name)" ] } ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "pip2uv", "language": "python", "name": "python3" }, @@ -90,7 +46,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.10" + "version": "3.12.13" } }, "nbformat": 4, diff --git a/labs/ai-foundry-hosted-agents-custom-framework/main.bicep b/labs/ai-foundry-hosted-agents-custom-framework/main.bicep index eb1f9861..178a7b07 100644 --- a/labs/ai-foundry-hosted-agents-custom-framework/main.bicep +++ b/labs/ai-foundry-hosted-agents-custom-framework/main.bicep @@ -83,6 +83,7 @@ module foundryModule '../../modules/cognitive-services/v3/foundry.bicep' = { foundryProjectName: foundryProjectName appInsightsId: appInsightsModule.outputs.id appInsightsInstrumentationKey: appInsightsModule.outputs.instrumentationKey + appInsightsConnectionString: appInsightsModule.outputs.connectionString } } @@ -305,7 +306,7 @@ resource hostedAgentResponsesApiPolicy 'Microsoft.ApiManagement/service/apis/pol output logAnalyticsWorkspaceId string = lawModule.outputs.customerId output apimServiceId string = apimModule.outputs.id -output apimGatewayUrl string = apimModule.outputs.gatewayUrl +output apimResourceGatewayURL string = apimModule.outputs.gatewayUrl output apimSubscriptions array = apimModule.outputs.apimSubscriptions output aiGatewayUrl string = '${apimModule.outputs.gatewayUrl}/${inferenceAPIPath}' output foundryProjectEndpoint string = foundryModule.outputs.extendedAIServicesConfig[0].foundryProjectEndpoint diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/README.md b/labs/ai-foundry-hosted-agents-custom-framework/src/frameworks/README.md similarity index 82% rename from labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/README.md rename to labs/ai-foundry-hosted-agents-custom-framework/src/frameworks/README.md index 2c10d21d..37278baf 100644 --- a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/README.md +++ b/labs/ai-foundry-hosted-agents-custom-framework/src/frameworks/README.md @@ -4,17 +4,11 @@ This directory contains multiple framework implementations for deploying custom ## Quick Start -1. **Setup infrastructure first** (if you haven't already): - - Run the **infrastructure deployment notebook** to create Foundry services, APIM, and ACR - - Save the deployment outputs (APIM suffix, subscription key, Foundry endpoint) - -2. **Choose your framework**: +1. **Choose your framework** in the lab notebook by setting the `framework` variable to `strands` or `pydantic`: - [**Strands Framework**](#strands-framework) - [**Pydantic AI Framework**](#pydantic-ai-framework) -3. **Run the corresponding setup notebook**: - - For Strands: `01_hosted_agent_strands_setup.ipynb` - - For Pydantic AI: `02_hosted_agent_pydantic_setup.ipynb` +2. **Run the lab notebook** [ai-foundry-hosted-agents-custom-framework.ipynb](../../../../ai-foundry-hosted-agents-custom-framework.ipynb) top-to-bottom. It deploys the infrastructure, builds the selected framework's image, registers the hosted agent, and tests it directly and through APIM. ## Framework Overview @@ -30,14 +24,12 @@ https://pydantic.dev/docs/ai/core-concepts/agent/ ``` frameworks/ -├── 01_hosted_agent_strands_setup.ipynb # Deploy Strands-based agent -├── 02_hosted_agent_pydantic_setup.ipynb # Deploy Pydantic AI agent ├── strands/ # Strands framework implementation │ ├── main.py # Agent entry point │ ├── Dockerfile # Container image definition │ ├── requirements-strands.txt # Strands framework dependencies │ ├── README.md # Strands-specific documentation -│ ├── .env # Environment variables template +│ ├── example.env # Environment variables template │ ├── .gitignore │ └── .dockerignore │ @@ -46,7 +38,7 @@ frameworks/ ├── Dockerfile # Container image definition ├── requirements-pydantic.txt # Pydantic dependencies ├── README.md # Pydantic-specific documentation - ├── .env # Environment variables template + ├── example.env # Environment variables template ├── .gitignore └── .dockerignore ``` @@ -60,9 +52,9 @@ frameworks/ - Direct control over agent behavior and response formatting - Ideal for domain-specific agent implementations -### How it works (in `01_hosted_agent_strands_setup.ipynb`) -1. **Builds Docker image** from `strands/` directory -2. **Deploys to Foundry** using image from ACR +### How it works (in the lab notebook, `framework = 'strands'`) +1. **Builds the image in ACR** from the `strands/` directory with `az acr build` +2. **Deploys to Foundry** using the image from ACR 3. **Tests direct API** - calls Foundry Responses API with bearer token 4. **Tests via APIM** - routes through API Management gateway with subscription key @@ -89,9 +81,9 @@ frameworks/ - Automatic request/response validation via Pydantic models - Streamlined agent development with minimal boilerplate -### How it works (in `02_hosted_agent_pydantic_setup.ipynb`) -1. **Builds Docker image** from `pydantic/` directory -2. **Deploys to Foundry** using image from ACR +### How it works (in the lab notebook, `framework = 'pydantic'`) +1. **Builds the image in ACR** from the `pydantic/` directory with `az acr build` +2. **Deploys to Foundry** using the image from ACR 3. **Tests direct API** - calls Foundry Responses API with bearer token 4. **Tests via APIM** - routes through API Management gateway with subscription key @@ -140,14 +132,14 @@ Both frameworks expect these environment variables (set in Foundry agent definit ## Workflow: Direct vs APIM -### Direct Call (Section 3 in notebooks) +### Direct Call - **URL**: `https://foundry-agents-{suffix}.services.ai.azure.com/api/projects/default-foundry-agents/agents/{AGENT_NAME}/endpoint/protocols/openai/responses?api-version=v1` - **Auth**: Bearer token (from `az login` → `https://ai.azure.com/.default`) - **Use case**: Development, validation that agent is running correctly - **Pros**: Direct connection, best for debugging - **Cons**: Requires Azure credentials on client -### APIM Gateway (Section 4 in notebooks) +### APIM Gateway - **URL**: `https://apim-{APIM_SUFFIX}.azure-api.net/hosted-agent-responses/agents/{AGENT_NAME}/endpoint/protocols/openai/responses?api-version=v1` - **Auth**: API key header (`api-key: `) - **Use case**: Production, client applications, rate limiting, monitoring @@ -164,12 +156,8 @@ To add another framework (e.g., CrewAI, AutoGen): - Create `main.py` with your framework initialization - Create `requirements-crew-ai.txt` with framework dependencies - Create `README.md` documenting the framework -3. **Create setup notebook**: Copy `01_hosted_agent_strands_setup.ipynb` and adapt: - - Change `strands_dir = "strands"` to `strands_dir = "crew-ai"` - - Change `IMAGE_NAME` to `crew-ai-agent` - - Update documentation to reference CrewAI - - Update section 2 agent creation code for CrewAI specifics -4. **Update deployment**: If deploying both, register agents with different names +3. **Register the framework in the lab notebook**: add an entry to the `frameworks` map in the initialization cell, for example `'crew-ai': {'agent_name': 'crew-ai-agent', 'image': 'crew-ai-agent'}`, then set `framework = 'crew-ai'` and re-run the build, deploy, and test cells. +4. **Update deployment**: If deploying multiple agents, register them with different names. ## Testing Your Agent @@ -214,7 +202,7 @@ Successful response structure: - Check APIM managed identity has `Contributor` or `Cognitive Services User` role ### Agent not receiving requests -- Check Docker image builds successfully: `docker build -t test:1.0 .` +- Check the image builds successfully in ACR: `az acr build --registry {registry} --image test:1.0 .` - Verify APIM policy correctly injects authentication headers - Check ACR image is pullable by Foundry (check image pull errors in Foundry portal) diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/pydantic/.dockerignore b/labs/ai-foundry-hosted-agents-custom-framework/src/frameworks/pydantic/.dockerignore similarity index 100% rename from labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/pydantic/.dockerignore rename to labs/ai-foundry-hosted-agents-custom-framework/src/frameworks/pydantic/.dockerignore diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/pydantic/.gitignore b/labs/ai-foundry-hosted-agents-custom-framework/src/frameworks/pydantic/.gitignore similarity index 100% rename from labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/pydantic/.gitignore rename to labs/ai-foundry-hosted-agents-custom-framework/src/frameworks/pydantic/.gitignore diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/pydantic/Dockerfile b/labs/ai-foundry-hosted-agents-custom-framework/src/frameworks/pydantic/Dockerfile similarity index 100% rename from labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/pydantic/Dockerfile rename to labs/ai-foundry-hosted-agents-custom-framework/src/frameworks/pydantic/Dockerfile diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/pydantic/README.md b/labs/ai-foundry-hosted-agents-custom-framework/src/frameworks/pydantic/README.md similarity index 83% rename from labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/pydantic/README.md rename to labs/ai-foundry-hosted-agents-custom-framework/src/frameworks/pydantic/README.md index 7a6db333..ed957700 100644 --- a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/pydantic/README.md +++ b/labs/ai-foundry-hosted-agents-custom-framework/src/frameworks/pydantic/README.md @@ -21,15 +21,15 @@ Official reference: - `main.py`: Pydantic AI agent server implementation (Responses protocol + tool calling + streaming). - `Dockerfile`: Container definition for hosting the agent in Foundry Hosted Agents. - `requirements-pydantic.txt`: Python dependencies for this runtime. -- `../02_hosted_agent_pydantic_setup.ipynb`: End-to-end setup and validation notebook. +- `../../../../ai-foundry-hosted-agents-custom-framework.ipynb`: End-to-end lab notebook (set `framework = 'pydantic'`). ## Get Started -1. Deploy infrastructure first with `../../../ai-foundry-hosted-agents-custom-framework.ipynb`. -2. Open and run `../02_hosted_agent_pydantic_setup.ipynb` from top to bottom. -3. Build and push the container image to Azure Container Registry. -4. Create a hosted agent version in your Foundry project. -5. Validate the agent through: +1. Open the lab notebook `../../../../ai-foundry-hosted-agents-custom-framework.ipynb` and set `framework = 'pydantic'` in the initialization cell. +2. Run the notebook from top to bottom. +3. It builds and pushes the container image to Azure Container Registry with `az acr build`. +4. It creates a hosted agent version in your Foundry project. +5. It validates the agent through: - Direct Foundry call (baseline) - APIM call (production-like path) @@ -39,7 +39,6 @@ Official reference: - Permission to push images to the target ACR repository. - Permission to create hosted agent versions in Foundry. - Azure CLI installed and authenticated (`az login`). -- Docker Desktop installed and running. - Python environment with dependencies required by this sample. ## Invocation and Routing diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/pydantic/example.env b/labs/ai-foundry-hosted-agents-custom-framework/src/frameworks/pydantic/example.env similarity index 100% rename from labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/pydantic/example.env rename to labs/ai-foundry-hosted-agents-custom-framework/src/frameworks/pydantic/example.env diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/pydantic/image.png b/labs/ai-foundry-hosted-agents-custom-framework/src/frameworks/pydantic/image.png similarity index 100% rename from labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/pydantic/image.png rename to labs/ai-foundry-hosted-agents-custom-framework/src/frameworks/pydantic/image.png diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/pydantic/main.py b/labs/ai-foundry-hosted-agents-custom-framework/src/frameworks/pydantic/main.py similarity index 100% rename from labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/pydantic/main.py rename to labs/ai-foundry-hosted-agents-custom-framework/src/frameworks/pydantic/main.py diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/pydantic/requirements-pydantic.txt b/labs/ai-foundry-hosted-agents-custom-framework/src/frameworks/pydantic/requirements-pydantic.txt similarity index 100% rename from labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/pydantic/requirements-pydantic.txt rename to labs/ai-foundry-hosted-agents-custom-framework/src/frameworks/pydantic/requirements-pydantic.txt diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/strands/.dockerignore b/labs/ai-foundry-hosted-agents-custom-framework/src/frameworks/strands/.dockerignore similarity index 100% rename from labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/strands/.dockerignore rename to labs/ai-foundry-hosted-agents-custom-framework/src/frameworks/strands/.dockerignore diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/strands/.gitignore b/labs/ai-foundry-hosted-agents-custom-framework/src/frameworks/strands/.gitignore similarity index 100% rename from labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/strands/.gitignore rename to labs/ai-foundry-hosted-agents-custom-framework/src/frameworks/strands/.gitignore diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/strands/Dockerfile b/labs/ai-foundry-hosted-agents-custom-framework/src/frameworks/strands/Dockerfile similarity index 100% rename from labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/strands/Dockerfile rename to labs/ai-foundry-hosted-agents-custom-framework/src/frameworks/strands/Dockerfile diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/strands/README.md b/labs/ai-foundry-hosted-agents-custom-framework/src/frameworks/strands/README.md similarity index 78% rename from labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/strands/README.md rename to labs/ai-foundry-hosted-agents-custom-framework/src/frameworks/strands/README.md index 36870799..787806bd 100644 --- a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/strands/README.md +++ b/labs/ai-foundry-hosted-agents-custom-framework/src/frameworks/strands/README.md @@ -23,7 +23,7 @@ The agent runs in a containerized environment managed by Foundry, with full obse - **`main.py`**: Strands agent server implementing the Responses protocol with tool calling and streaming. - **`Dockerfile`**: Container image definition for Foundry Hosted Agents (builds for Linux amd64). - **`requirements-strands.txt`**: Python dependencies (Strands, FastAPI, etc.). -- **`01_hosted_agent_strands_setup.ipynb`**: End-to-end setup and testing notebook with 4 sections: +- **`../../../../ai-foundry-hosted-agents-custom-framework.ipynb`**: End-to-end lab notebook (set `framework = 'strands'`) covering: 1. Build and push container to ACR 2. Create hosted agent version in Foundry 3. Test agent directly via Foundry Responses API (baseline validation) @@ -62,28 +62,19 @@ OpenAI (GPT-5-Mini) ## Get Started -### Step 1: Configure Your Setup +### Step 1: Configure the lab notebook -Open `01_hosted_agent_strands_setup.ipynb` and fill in the configuration variables at the top: -- `ACR_NAME`: Your Azure Container Registry name -- `IMAGE_NAME`: Container image name (usually `strands-agent`) -- `IMAGE_TAG`: Semantic version (e.g., `1.0.0`) -- `PROJECT_ENDPOINT`: Foundry project endpoint (from infrastructure deployment) -- `AZURE_OPENAI_ENDPOINT`: APIM inference API endpoint -- `APIM_SUBSCRIPTION_KEY`: APIM subscription key -- `APIM_SUFFIX`: Your APIM instance suffix +Open `../../../../ai-foundry-hosted-agents-custom-framework.ipynb`, set `framework = 'strands'` in the initialization cell, and run the deployment cells. The APIM gateway URL, Container Registry name, Foundry agent project endpoint, and subscription key are read automatically from the deployment outputs. ### Step 2: Build & Push Container -Run **Section 1** of the notebook: -- Builds a Docker image: `docker build -t {ACR_URI} --platform linux/amd64 .` -- Pushes to ACR: `docker push {ACR_URI}` - -The `--platform linux/amd64` flag ensures compatibility with Foundry's Linux hosting. +Run the build cell: +- Builds the image in Azure Container Registry: `az acr build --registry {registry} --image strands-agent:1.0.0 src/responses/agents/frameworks/strands` +- No local Docker is required; ACR builds a Linux amd64 image compatible with Foundry hosting. ### Step 3: Create Hosted Agent -Run **Section 2** of the notebook: +Run the deploy cell: - Creates a HostedAgentDefinition with your container image - Specifies resource allocation (1 CPU, 2Gi memory) - Sets environment variables for your agent to reach models @@ -91,9 +82,9 @@ Run **Section 2** of the notebook: Once the agent transitions to "Running" state, it's ready for testing. -### Step 4: Validate Agent Locally +### Step 4: Validate Agent Directly -Run **Section 3** ("Test Direct"): +Run the direct test cell: - Calls Foundry's Responses API directly using your Azure CLI credential - No APIM involvement—validates agent and basic connectivity - Helpful for troubleshooting deployment issues @@ -102,7 +93,7 @@ If this test fails, check agent status in Foundry or review container logs. ### Step 5: Test via APIM Gateway (Production Path) -Run **Section 4** ("Test via APIM"): +Run the APIM test cell: - Routes through APIM gateway using `api-key` header - APIM automatically: - Injects managed identity bearer token @@ -115,10 +106,9 @@ Policy configuration is in `../../hosted-agent-policy.xml` for customization. ## Prerequisites -- Microsoft Foundry resources deployed (see parent [infrastructure notebook](../../ai-foundry-hosted-agents-custom-framework.ipynb)) +- Microsoft Foundry resources deployed (see the parent [lab notebook](../../../../ai-foundry-hosted-agents-custom-framework.ipynb)) - Azure CLI installed and authenticated (`az login`) -- Docker Desktop installed and running -- Python 3.12+ with dependencies: `pip install azure-ai-projects azure-identity requests` +- Python 3.12+ with dependencies from the repo root (`uv sync`) - Azure subscription with permissions to: - Push images to ACR - Create agent versions in Foundry @@ -126,7 +116,7 @@ Policy configuration is in `../../hosted-agent-policy.xml` for customization. ## Key Configuration Notes -- **Agent name**: Use the same value configured as `AGENT_NAME` in the setup notebook. +- **Agent name**: Use the same value configured as `agent_name` in the lab notebook. - **Model endpoint**: Your agent calls the APIM **inference** API, not the hosted-agent API. - **Token audience**: - Direct tests use `https://ai.azure.com/.default` diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/strands/example.env b/labs/ai-foundry-hosted-agents-custom-framework/src/frameworks/strands/example.env similarity index 100% rename from labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/strands/example.env rename to labs/ai-foundry-hosted-agents-custom-framework/src/frameworks/strands/example.env diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/strands/image.png b/labs/ai-foundry-hosted-agents-custom-framework/src/frameworks/strands/image.png similarity index 100% rename from labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/strands/image.png rename to labs/ai-foundry-hosted-agents-custom-framework/src/frameworks/strands/image.png diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/strands/main.py b/labs/ai-foundry-hosted-agents-custom-framework/src/frameworks/strands/main.py similarity index 100% rename from labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/strands/main.py rename to labs/ai-foundry-hosted-agents-custom-framework/src/frameworks/strands/main.py diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/strands/requirements-strands.txt b/labs/ai-foundry-hosted-agents-custom-framework/src/frameworks/strands/requirements-strands.txt similarity index 100% rename from labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/strands/requirements-strands.txt rename to labs/ai-foundry-hosted-agents-custom-framework/src/frameworks/strands/requirements-strands.txt diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/01_hosted_agent_strands_setup.ipynb b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/01_hosted_agent_strands_setup.ipynb deleted file mode 100644 index bfb3b269..00000000 --- a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/01_hosted_agent_strands_setup.ipynb +++ /dev/null @@ -1,502 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d8a4f2a8", - "metadata": {}, - "source": [ - "# Strands Hosted Agent Setup\n", - "\n", - "This notebook helps you build, deploy, and test a **Strands-based custom agent** on Microsoft Foundry Hosted Agents.\n", - "\n", - "### What this notebook does\n", - "\n", - "1. **Build & Push** - Builds a Docker container image for your Strands agent and pushes it to Azure Container Registry (ACR)\n", - "2. **Deploy** - Creates a hosted agent version in your Foundry project, pulling the image from ACR\n", - "3. **Test Direct** - Validates the agent works by calling Foundry's Responses API directly with your Azure credentials\n", - "4. **Test via APIM** - Routes requests through Azure API Management to test the production gateway path\n", - "\n", - "### Prerequisites\n", - "\n", - "Before running this notebook:\n", - "- Complete the **infrastructure deployment** notebook first (creates Foundry resources, APIM, ACR)\n", - "- Have the deployment outputs available:\n", - " - Foundry project endpoint\n", - " - ACR login server\n", - " - APIM suffix\n", - " - APIM subscription key\n", - "- Docker Desktop must be running\n", - "- You must be logged in to Azure CLI (`az login`)" - ] - }, - { - "cell_type": "markdown", - "id": "2ca40d16", - "metadata": {}, - "source": [ - "## 1. Build And Push The Container Image\n", - "\n", - "This builds the image locally with Docker and pushes it to ACR.\n", - "Run this after completing the prerequisites above." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "401a8dd3", - "metadata": {}, - "outputs": [], - "source": [ - "# Central configuration (edit here once, then run notebook top-to-bottom)\n", - "ACR_NAME = \"X\"\n", - "APIM_SUFFIX = \"X\"\n", - "APIM_SUBSCRIPTION_KEY = \"X\"\n", - "PROJECT_ENDPOINT = f\"https://foundry-agents-{APIM_SUFFIX}.services.ai.azure.com/api/projects/default-foundry-agents\"\n", - "\n", - "AGENT_NAME = \"strands-agent\"\n", - "FRAMEWORK_DIR = \"strands\"\n", - "IMAGE_NAME = \"strands-agent\"\n", - "IMAGE_TAG = \"1.0.0\"\n", - "\n", - "AZURE_OPENAI_API_VERSION = \"2024-05-01-preview\"\n", - "AZURE_OPENAI_DEPLOYMENT = \"gpt-5-mini\"\n", - "API_VERSION = \"v1\"\n", - "DEFAULT_CONTENT_TYPE = \"application/json\"\n", - "FOUNDRY_FEATURES_HEADER = \"HostedAgents=V1Preview\"\n", - "DIRECT_TEST_INPUT = \"Hello! What can you help me with? What's the weather in Paris today?\"\n", - "\n", - "ACR_LOGIN_SERVER = f\"{ACR_NAME}.azurecr.io\"\n", - "IMAGE_URI = f\"{ACR_LOGIN_SERVER}/{IMAGE_NAME}:{IMAGE_TAG}\"\n", - "AZURE_OPENAI_ENDPOINT = f\"https://apim-{APIM_SUFFIX}.azure-api.net/inference/models\"\n", - "\n", - "def build_foundry_responses_url(project_endpoint: str, agent_name: str) -> str:\n", - " return f\"{project_endpoint}/agents/{agent_name}/endpoint/protocols/openai/responses\"\n", - "\n", - "def build_apim_responses_url(apim_suffix: str, agent_name: str) -> str:\n", - " return f\"https://apim-{apim_suffix}.azure-api.net/hosted-agent-responses/agents/{agent_name}/endpoint/protocols/openai/responses\"\n", - "\n", - "print(\"Configuration loaded.\")\n", - "print(f\"ACR_LOGIN_SERVER={ACR_LOGIN_SERVER}\")\n", - "print(f\"IMAGE_URI={IMAGE_URI}\")\n", - "print(f\"PROJECT_ENDPOINT={PROJECT_ENDPOINT}\")\n", - "print(f\"AZURE_OPENAI_ENDPOINT={AZURE_OPENAI_ENDPOINT}\")\n", - "print(f\"AGENT_NAME={AGENT_NAME}\")" - ] - }, - { - "cell_type": "markdown", - "id": "e36428d1", - "metadata": {}, - "source": [ - "### Fill in your configuration\n", - "\n", - "Replace the placeholder values above with your actual Azure resources. These should match the outputs from the infrastructure deployment notebook:\n", - "- `ACR_NAME`: Your Azure Container Registry name (e.g., `acrxhep4wovroziu`)\n", - "- `IMAGE_NAME`: Container image name for your Strands agent (usually `strands-agent`)\n", - "- `IMAGE_TAG`: Semantic version tag for your image (e.g., `1.0.0`)\n", - "\n", - "The computed values (`ACR_LOGIN_SERVER`, `IMAGE_URI`) will be used in subsequent steps." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "97767e41", - "metadata": {}, - "outputs": [], - "source": [ - "# Ensure Docker is running\n", - "!az acr login --name {ACR_NAME}" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "905639da", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import subprocess\n", - "\n", - "# Build and push from the framework directory configured above\n", - "original_dir = os.getcwd()\n", - "os.chdir(FRAMEWORK_DIR)\n", - "\n", - "try:\n", - " print(f\"Running: docker build -t {IMAGE_URI} .\")\n", - " subprocess.run([\"docker\", \"build\", \"-t\", IMAGE_URI, \"--platform\", \"linux/amd64\", \".\"], check=True)\n", - "\n", - " print(f\"Running: docker push {IMAGE_URI}\")\n", - " subprocess.run([\"docker\", \"push\", IMAGE_URI], check=True)\n", - "\n", - " print(\"Docker build and push completed successfully.\")\n", - "finally:\n", - " os.chdir(original_dir)" - ] - }, - { - "cell_type": "markdown", - "id": "823d4ecc", - "metadata": {}, - "source": [ - "### Build and push your container\n", - "\n", - "This builds the Strands agent Docker image and pushes it to your ACR. The `--platform linux/amd64` flag ensures the image is compatible with Foundry's Linux-based container hosting.\n", - "\n", - "After pushing, your image will be available at `{ACR_LOGIN_SERVER}/strands-agent:1.0.0` for Foundry to pull and deploy." - ] - }, - { - "cell_type": "markdown", - "id": "0235f974", - "metadata": {}, - "source": [ - "## 2. Create Hosted Agent Version\n", - "\n", - "This section creates your Strands agent as a **Foundry Hosted Agent** using the Responses protocol v1.0.0.\n", - "\n", - "### Important notes\n", - "\n", - "- **Agent name**: Choose any name you want (e.g., `strands-agent`, `my-agent`, etc.). \n", - " - Foundry auto-assigns the version suffix (`:1`, `:2`, etc.) when you create versions\n", - " - This name will be used in the APIM URL path to invoke the agent: `/agents/{agentName}/endpoint/protocols/openai/responses`\n", - "\n", - "- **Model endpoint**: Uses APIM **inference** API for model calls (`https://apim-{suffix}.azure-api.net/inference/models`), not the hosted-agent API.\n", - "\n", - "- **Dependencies**: Install `azure-ai-projects` and `azure-identity` to interact with Foundry APIs.\n", - "\n", - "After creation, your agent will transition through status changes. Once it reaches \"Running\", it's ready to accept requests in sections 3 and 4." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "64490111", - "metadata": {}, - "outputs": [], - "source": [ - "pip install azure-ai-projects==2.3.0 --force-reinstall --no-cache-dir" - ] - }, - { - "cell_type": "markdown", - "id": "83a8752a", - "metadata": {}, - "source": [ - "### Create the hosted agent in Foundry\n", - "\n", - "This cell deploys your Strands container as a **Hosted Agent** in your Foundry project. \n", - "\n", - "**Key configuration:**\n", - "- **Protocol**: Responses v1.0.0 (standard for Foundry hosted agents)\n", - "- **Resources**: 1 CPU, 2Gi memory (adjust based on your agent needs)\n", - "- **Environment variables**: \n", - " - `AZURE_OPENAI_ENDPOINT`: Points to APIM inference API for your agent to call models\n", - " - `APIM_SUBSCRIPTION_KEY`: APIM subscription key for authentication\n", - " - `AZURE_OPENAI_DEPLOYMENT`: Model name to use (e.g., `gpt-5-mini`)\n", - "\n", - "The agent will be created with a version suffix (auto-assigned by Foundry). After creation, it transitions to \"Running\" state and is ready to accept requests via the Responses API." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d4de6ece", - "metadata": {}, - "outputs": [], - "source": [ - "from azure.ai.projects import AIProjectClient\n", - "from azure.ai.projects.models import (\n", - " HostedAgentDefinition,\n", - " ProtocolVersionRecord,\n", - " AgentEndpointProtocol,\n", - " ContainerConfiguration,\n", - " )\n", - "from azure.identity import AzureCliCredential\n", - "\n", - "print(f\"PROJECT_ENDPOINT: {PROJECT_ENDPOINT}\")\n", - "print(f\"AGENT_NAME: {AGENT_NAME}\")\n", - "print(f\"IMAGE_URI: {IMAGE_URI}\")\n", - "print(f\"AZURE_OPENAI_ENDPOINT: {AZURE_OPENAI_ENDPOINT}\")\n", - "\n", - "credential = AzureCliCredential()\n", - "\n", - "project = AIProjectClient(\n", - " endpoint=PROJECT_ENDPOINT,\n", - " credential=credential,\n", - " allow_preview=True,\n", - ")\n", - "\n", - "agent = project.agents.create_version(\n", - " agent_name=AGENT_NAME,\n", - " definition=HostedAgentDefinition(\n", - " protocol_versions=[\n", - " ProtocolVersionRecord(protocol=AgentEndpointProtocol.RESPONSES, version=\"1.0.0\")\n", - " ],\n", - " cpu=\"1\",\n", - " memory=\"2Gi\",\n", - " container_configuration=ContainerConfiguration(image=IMAGE_URI),\n", - " environment_variables={\n", - " \"AZURE_OPENAI_ENDPOINT\": AZURE_OPENAI_ENDPOINT,\n", - " \"AZURE_OPENAI_API_VERSION\": AZURE_OPENAI_API_VERSION,\n", - " \"AZURE_OPENAI_DEPLOYMENT\": AZURE_OPENAI_DEPLOYMENT,\n", - " \"APIM_SUBSCRIPTION_KEY\": APIM_SUBSCRIPTION_KEY,\n", - " \"LOG_LEVEL\": \"INFO\",\n", - " \"STRANDS_LOG_LEVEL\": \"INFO\",\n", - " },\n", - " ),\n", - " )\n", - "\n", - "print(f\"Agent created: {agent.name}, version: {agent.version}, id {agent.id}\")" - ] - }, - { - "cell_type": "markdown", - "id": "2e23655c", - "metadata": {}, - "source": [ - "## 3. Test The Hosted Agent (Direct)\n", - "\n", - "**Purpose:** Validate your agent works by calling the Foundry Responses API directly using your Azure CLI credential.\n", - "\n", - "This is your baseline test—if this fails, APIM proxy tests will also fail. Use this to confirm:\n", - "- Agent reached \"Running\" status ✅\n", - "- Network connectivity to Foundry is working ✅\n", - "- Authentication with your credential works ✅\n", - "- Agent payload format is correct ✅\n", - "\n", - "**How it works:**\n", - "- Endpoint: `{PROJECT_ENDPOINT}/agents/{AGENT_NAME}/endpoint/protocols/openai/responses?api-version=v1`\n", - "- Auth: Bearer token with `https://ai.azure.com/.default` audience (from your Azure CLI login)\n", - "- Headers: Includes `Foundry-Features: HostedAgents=V1Preview` (required for preview access)\n", - "\n", - "If this test succeeds, you know the agent itself is working correctly." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "52d31749", - "metadata": {}, - "outputs": [], - "source": [ - "import json\n", - "import requests\n", - "from azure.core.credentials import AccessToken\n", - "from azure.identity import AzureCliCredential\n", - "\n", - "url = build_foundry_responses_url(PROJECT_ENDPOINT, AGENT_NAME)\n", - "\n", - "if \"credential\" not in globals():\n", - " credential = AzureCliCredential()\n", - "\n", - "# Get a token for Foundry Responses API\n", - "token: AccessToken = credential.get_token(\"https://ai.azure.com/.default\")\n", - "\n", - "headers = {\n", - " \"Authorization\": f\"Bearer {token.token}\",\n", - " \"Content-Type\": DEFAULT_CONTENT_TYPE,\n", - " \"Foundry-Features\": FOUNDRY_FEATURES_HEADER,\n", - "}\n", - "\n", - "payload = {\n", - " \"input\": DIRECT_TEST_INPUT,\n", - " \"stream\": False,\n", - "}\n", - "\n", - "print(f\"POST {url}?api-version={API_VERSION}\")\n", - "print(f\"Agent Name: {AGENT_NAME}\")\n", - "print(f\"Payload: {json.dumps(payload, indent=2)}\")\n", - "print()\n", - "\n", - "response = requests.post(url, headers=headers, json=payload, params={\"api-version\": API_VERSION})\n", - "print(f\"Status: {response.status_code}\")\n", - "print(f\"Headers: {dict(response.headers)}\")\n", - "print(f\"Response text (first 500 chars): {response.text[:500]}\")\n", - "print()\n", - "\n", - "if response.status_code == 200:\n", - " try:\n", - " result = response.json()\n", - " print(\"Response JSON:\")\n", - " print(json.dumps(result, indent=2))\n", - " if \"output_text\" in result:\n", - " print(f\"\\nAgent output:\\n{result['output_text']}\")\n", - " except json.JSONDecodeError as e:\n", - " print(f\"Failed to parse JSON: {e}\")\n", - " print(f\"Raw response: {response.text}\")\n", - "else:\n", - " print(f\"Error: {response.status_code}\")\n", - " if response.text:\n", - " try:\n", - " print(json.dumps(response.json(), indent=2))\n", - " except Exception:\n", - " print(response.text)" - ] - }, - { - "cell_type": "markdown", - "id": "3b437f83", - "metadata": {}, - "source": [ - "## 4. Test The Hosted Agent Via APIM\n", - "\n", - "**Purpose:** Route your request through Azure API Management instead of calling Foundry directly.\n", - "\n", - "This validates the production-like path:\n", - "- Client → APIM Gateway (subscription key auth) → Foundry Responses API\n", - "\n", - "**Important: Agent-Specific Routing**\n", - "\n", - "Foundry Hosted Agents **require** the agent name in the URL path. There is no generic `/responses` endpoint that accepts `agent_reference` in the request body. Each agent must have its own URL path:\n", - "\n", - "```\n", - "POST https://apim-{APIM_SUFFIX}.azure-api.net/hosted-agent-responses/agents/{AGENT_NAME}/endpoint/protocols/openai/responses\n", - "```\n", - "\n", - "**What APIM does automatically:**\n", - "- Injects managed identity bearer token for Foundry authentication (audience: `https://ai.azure.com`)\n", - "- Enforces `Content-Type: application/json` header\n", - "- Injects `Foundry-Features: HostedAgents=V1Preview` header for preview access\n", - "- Your client only needs the APIM subscription key (`api-key` header)\n", - "\n", - "**Comparison: Direct vs APIM**\n", - "- **Direct (Section 3):** `https://foundry-agents-{suffix}.services.ai.azure.com/api/projects/default-foundry-agents/agents/{AGENT_NAME}/endpoint/protocols/openai/responses` + Bearer token\n", - "- **APIM (Section 4):** `https://apim-{suffix}.azure-api.net/hosted-agent-responses/agents/{AGENT_NAME}/endpoint/protocols/openai/responses` + API key\n", - "\n", - "**Configuration details** are in [hosted-agent-policy.xml](../../hosted-agent-policy.xml)—update there if you need to change defaults.\n", - "\n", - "Compare this test result with Section 3 to ensure both paths (direct and APIM-proxied) produce consistent responses." - ] - }, - { - "cell_type": "markdown", - "id": "94663b69", - "metadata": {}, - "source": [ - "### Get deployment outputs\n", - "\n", - "Before testing via APIM, retrieve the outputs from your infrastructure deployment notebook and update the **top configuration cell** (Cell 3):\n", - "\n", - "- `APIM_SUFFIX`: The unique suffix for your APIM instance (e.g., `xhep4wovroziu`)\n", - "- `APIM_SUBSCRIPTION_KEY`: The starter subscription key from APIM outputs\n", - "- `PROJECT_ENDPOINT`: The Foundry agents project endpoint (or let it be computed from `APIM_SUFFIX`)\n", - "\n", - "Keeping these values in one place makes reruns and troubleshooting much easier." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d9e3232c", - "metadata": {}, - "outputs": [], - "source": [ - "print(\"Using APIM/Foundry values from the top configuration cell:\")\n", - "print(f\"APIM_SUFFIX: {APIM_SUFFIX}\")\n", - "print(f\"APIM_SUBSCRIPTION_KEY: {APIM_SUBSCRIPTION_KEY[:20]}...\" if len(APIM_SUBSCRIPTION_KEY) > 20 else f\"APIM_SUBSCRIPTION_KEY: {APIM_SUBSCRIPTION_KEY}\")\n", - "print(f\"PROJECT_ENDPOINT: {PROJECT_ENDPOINT}\")\n", - "print()\n", - "print(\"If these are placeholders, update Cell 3 before running APIM tests.\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "447dbe86", - "metadata": {}, - "outputs": [], - "source": [ - "import json\n", - "import requests\n", - "\n", - "url = build_apim_responses_url(APIM_SUFFIX, AGENT_NAME)\n", - "\n", - "headers = {\n", - " \"api-key\": APIM_SUBSCRIPTION_KEY,\n", - " \"Content-Type\": DEFAULT_CONTENT_TYPE,\n", - " \"Foundry-Features\": FOUNDRY_FEATURES_HEADER,\n", - "}\n", - "\n", - "payload = {\n", - " \"input\": DIRECT_TEST_INPUT,\n", - " \"stream\": False,\n", - "}\n", - "\n", - "print(f\"POST {url}?api-version={API_VERSION}\")\n", - "print(f\"APIM Suffix: {APIM_SUFFIX}\")\n", - "print(f\"Agent Name (in URL path): {AGENT_NAME}\")\n", - "print(f\"Content-Type: {DEFAULT_CONTENT_TYPE}\")\n", - "print(f\"Headers: api-key={APIM_SUBSCRIPTION_KEY[:20]}..., Content-Type, Foundry-Features\")\n", - "print(f\"Payload: {json.dumps(payload, indent=2)}\")\n", - "print()\n", - "\n", - "response = requests.post(url, headers=headers, json=payload, params={\"api-version\": API_VERSION})\n", - "print(f\"Status: {response.status_code}\")\n", - "print()\n", - "\n", - "# Extract response from payload\n", - "apim_response = None\n", - "agent_text = None\n", - "\n", - "if response.status_code == 200:\n", - " try:\n", - " result = response.json()\n", - " apim_response = result\n", - "\n", - " # Extract agent text from nested structure\n", - " if \"output\" in result and len(result[\"output\"]) > 0:\n", - " message = result[\"output\"][0]\n", - " if \"content\" in message and len(message[\"content\"]) > 0:\n", - " agent_text = message[\"content\"][0].get(\"text\", \"\")\n", - "\n", - " print(\"=\" * 80)\n", - " print(\"AGENT RESPONSE (via APIM):\")\n", - " print(\"=\" * 80)\n", - " if agent_text:\n", - " print(agent_text)\n", - " else:\n", - " print(\"Full response:\")\n", - " print(json.dumps(result, indent=2))\n", - " print(\"=\" * 80)\n", - "\n", - " except json.JSONDecodeError as e:\n", - " print(f\"Failed to parse JSON: {e}\")\n", - " print(f\"Raw response: {response.text}\")\n", - "else:\n", - " print(f\"Error: {response.status_code}\")\n", - " if response.text:\n", - " try:\n", - " apim_response = response.json()\n", - " print(json.dumps(apim_response, indent=2))\n", - " except Exception:\n", - " print(response.text)\n", - "\n", - "print(\"\\nExtracted response stored in 'apim_response' variable\")\n", - "print(\"Agent text stored in 'agent_text' variable\")" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.12.10" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/02_hosted_agent_pydantic_setup.ipynb b/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/02_hosted_agent_pydantic_setup.ipynb deleted file mode 100644 index 4fa16695..00000000 --- a/labs/ai-foundry-hosted-agents-custom-framework/src/responses/agents/frameworks/02_hosted_agent_pydantic_setup.ipynb +++ /dev/null @@ -1,497 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "7db1b3cb", - "metadata": {}, - "source": [ - "# Pydantic AI Hosted Agent Setup\n", - "\n", - "This notebook helps you build, deploy, and test a **Pydantic AI-based custom agent** on Microsoft Foundry Hosted Agents.\n", - "\n", - "### What this notebook does\n", - "\n", - "1. **Build & Push** - Builds a Docker container image for your Pydantic AI agent and pushes it to Azure Container Registry (ACR)\n", - "2. **Deploy** - Creates a hosted agent version in your Foundry project, pulling the image from ACR\n", - "3. **Test Direct** - Validates the agent works by calling Foundry's Responses API directly with your Azure credentials\n", - "4. **Test via APIM** - Routes requests through Azure API Management to test the production gateway path\n", - "\n", - "### Prerequisites\n", - "\n", - "Before running this notebook:\n", - "- Complete the **infrastructure deployment** notebook first (creates Foundry resources, APIM, ACR)\n", - "- Have the deployment outputs available:\n", - " - Foundry project endpoint\n", - " - ACR login server\n", - " - APIM suffix\n", - " - APIM subscription key\n", - "- Docker Desktop must be running\n", - "- You must be logged in to Azure CLI (`az login`)" - ] - }, - { - "cell_type": "markdown", - "id": "75c76518", - "metadata": {}, - "source": [ - "## 1. Build And Push The Container Image\n", - "\n", - "This builds the image locally with Docker and pushes it to ACR.\n", - "Run this after completing the prerequisites above." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b9ba6016", - "metadata": {}, - "outputs": [], - "source": [ - "# Central configuration (edit here once, then run notebook top-to-bottom)\n", - "ACR_NAME = \"X\"\n", - "APIM_SUFFIX = \"X\"\n", - "APIM_SUBSCRIPTION_KEY = \"X\"\n", - "PROJECT_ENDPOINT = f\"https://foundry-agents-{APIM_SUFFIX}.services.ai.azure.com/api/projects/default-foundry-agents\"\n", - "\n", - "AGENT_NAME = \"pydantic-agent\"\n", - "FRAMEWORK_DIR = \"pydantic\"\n", - "IMAGE_NAME = \"pydantic-agent\"\n", - "IMAGE_TAG = \"1.0.0\"\n", - "\n", - "AZURE_OPENAI_API_VERSION = \"2024-05-01-preview\"\n", - "AZURE_OPENAI_DEPLOYMENT = \"gpt-5-mini\"\n", - "API_VERSION = \"v1\"\n", - "DEFAULT_CONTENT_TYPE = \"application/json\"\n", - "FOUNDRY_FEATURES_HEADER = \"HostedAgents=V1Preview\"\n", - "DIRECT_TEST_INPUT = \"Hello! What can you help me with?\"\n", - "\n", - "ACR_LOGIN_SERVER = f\"{ACR_NAME}.azurecr.io\"\n", - "IMAGE_URI = f\"{ACR_LOGIN_SERVER}/{IMAGE_NAME}:{IMAGE_TAG}\"\n", - "AZURE_OPENAI_ENDPOINT = f\"https://apim-{APIM_SUFFIX}.azure-api.net/inference/models\"\n", - "\n", - "def build_foundry_responses_url(project_endpoint: str, agent_name: str) -> str:\n", - " return f\"{project_endpoint}/agents/{agent_name}/endpoint/protocols/openai/responses\"\n", - "\n", - "def build_apim_responses_url(apim_suffix: str, agent_name: str) -> str:\n", - " return f\"https://apim-{apim_suffix}.azure-api.net/hosted-agent-responses/agents/{agent_name}/endpoint/protocols/openai/responses\"\n", - "\n", - "print(\"Configuration loaded.\")\n", - "print(f\"ACR_LOGIN_SERVER={ACR_LOGIN_SERVER}\")\n", - "print(f\"IMAGE_URI={IMAGE_URI}\")\n", - "print(f\"PROJECT_ENDPOINT={PROJECT_ENDPOINT}\")\n", - "print(f\"AZURE_OPENAI_ENDPOINT={AZURE_OPENAI_ENDPOINT}\")\n", - "print(f\"AGENT_NAME={AGENT_NAME}\")" - ] - }, - { - "cell_type": "markdown", - "id": "a144ea9b", - "metadata": {}, - "source": [ - "### Fill in your configuration\n", - "\n", - "Replace the placeholder values above with your actual Azure resources. These should match the outputs from the infrastructure deployment notebook:\n", - "- `ACR_NAME`: Your Azure Container Registry name (e.g., `acrxhep4wovroziu`)\n", - "- `IMAGE_NAME`: Container image name for your Pydantic agent (usually `pydantic-agent`)\n", - "- `IMAGE_TAG`: Semantic version tag for your image (e.g., `1.0.0`)\n", - "\n", - "The computed values (`ACR_LOGIN_SERVER`, `IMAGE_URI`) will be used in subsequent steps." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ace1aa5f", - "metadata": {}, - "outputs": [], - "source": [ - "# Ensure Docker is running\n", - "!az acr login --name {ACR_NAME}" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a49cb256", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import subprocess\n", - "\n", - "# Build and push from the framework directory configured above\n", - "original_dir = os.getcwd()\n", - "os.chdir(FRAMEWORK_DIR)\n", - "\n", - "try:\n", - " print(f\"Running: docker build -t {IMAGE_URI} .\")\n", - " subprocess.run([\"docker\", \"build\", \"-t\", IMAGE_URI, \"--platform\", \"linux/amd64\", \".\"], check=True)\n", - "\n", - " print(f\"Running: docker push {IMAGE_URI}\")\n", - " subprocess.run([\"docker\", \"push\", IMAGE_URI], check=True)\n", - "\n", - " print(\"Docker build and push completed successfully.\")\n", - "finally:\n", - " os.chdir(original_dir)" - ] - }, - { - "cell_type": "markdown", - "id": "1f4a77ab", - "metadata": {}, - "source": [ - "### Build and push your container\n", - "\n", - "This builds the Pydantic AI agent Docker image and pushes it to your ACR. The `--platform linux/amd64` flag ensures the image is compatible with Foundry's Linux-based container hosting.\n", - "\n", - "After pushing, your image will be available at `{ACR_LOGIN_SERVER}/pydantic-agent:1.0.0` for Foundry to pull and deploy." - ] - }, - { - "cell_type": "markdown", - "id": "ce9910fc", - "metadata": {}, - "source": [ - "## 2. Create Hosted Agent Version\n", - "\n", - "This section creates your Pydantic AI agent as a **Foundry Hosted Agent** using the Responses protocol v1.0.0.\n", - "\n", - "### Important notes\n", - "\n", - "- **Agent name**: Choose any name you want (e.g., `pydantic-agent`, `my-agent`, etc.). \n", - " - Foundry auto-assigns the version suffix (`:1`, `:2`, etc.) when you create versions\n", - " - This name will be used in the APIM URL path to invoke the agent: `/agents/{agentName}/endpoint/protocols/openai/responses`\n", - "\n", - "- **Model endpoint**: Uses APIM **inference** API for model calls (`https://apim-{suffix}.azure-api.net/inference/models`), not the hosted-agent API.\n", - "\n", - "- **Dependencies**: Install `azure-ai-projects` and `azure-identity` to interact with Foundry APIs.\n", - "\n", - "After creation, your agent will transition through status changes. Once it reaches \"Running\", it's ready to accept requests in sections 3 and 4." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a471f202", - "metadata": {}, - "outputs": [], - "source": [ - "pip install azure-ai-projects==2.3.0 " - ] - }, - { - "cell_type": "markdown", - "id": "25e4cc10", - "metadata": {}, - "source": [ - "### Create the hosted agent in Foundry\n", - "\n", - "This cell deploys your Pydantic AI container as a **Hosted Agent** in your Foundry project. \n", - "\n", - "**Key configuration:**\n", - "- **Protocol**: Responses v1.0.0 (standard for Foundry hosted agents)\n", - "- **Resources**: 1 CPU, 2Gi memory (adjust based on your agent needs)\n", - "- **Environment variables**: \n", - " - `AZURE_OPENAI_ENDPOINT`: Points to APIM inference API for your agent to call models\n", - " - `APIM_SUBSCRIPTION_KEY`: APIM subscription key for authentication\n", - " - `AZURE_OPENAI_DEPLOYMENT`: Model name to use (e.g., `gpt-5-mini`)\n", - "\n", - "The agent will be created with a version suffix (auto-assigned by Foundry). After creation, it transitions to \"Running\" state and is ready to accept requests via the Responses API." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e6e2ec6a", - "metadata": {}, - "outputs": [], - "source": [ - "from azure.ai.projects import AIProjectClient\n", - "from azure.ai.projects.models import (\n", - " HostedAgentDefinition,\n", - " ProtocolVersionRecord,\n", - " AgentEndpointProtocol,\n", - " ContainerConfiguration,\n", - " )\n", - "from azure.identity import AzureCliCredential\n", - "\n", - "print(f\"PROJECT_ENDPOINT: {PROJECT_ENDPOINT}\")\n", - "print(f\"AGENT_NAME: {AGENT_NAME}\")\n", - "print(f\"IMAGE_URI: {IMAGE_URI}\")\n", - "print(f\"AZURE_OPENAI_ENDPOINT: {AZURE_OPENAI_ENDPOINT}\")\n", - "\n", - "credential = AzureCliCredential()\n", - "\n", - "project = AIProjectClient(\n", - " endpoint=PROJECT_ENDPOINT,\n", - " credential=credential,\n", - " allow_preview=True,\n", - ")\n", - "\n", - "agent = project.agents.create_version(\n", - " agent_name=AGENT_NAME,\n", - " definition=HostedAgentDefinition(\n", - " protocol_versions=[\n", - " ProtocolVersionRecord(protocol=AgentEndpointProtocol.RESPONSES, version=\"1.0.0\")\n", - " ],\n", - " cpu=\"1\",\n", - " memory=\"2Gi\",\n", - " container_configuration=ContainerConfiguration(image=IMAGE_URI),\n", - " environment_variables={\n", - " \"AZURE_OPENAI_ENDPOINT\": AZURE_OPENAI_ENDPOINT,\n", - " \"AZURE_OPENAI_API_VERSION\": AZURE_OPENAI_API_VERSION,\n", - " \"AZURE_OPENAI_DEPLOYMENT\": AZURE_OPENAI_DEPLOYMENT,\n", - " \"APIM_SUBSCRIPTION_KEY\": APIM_SUBSCRIPTION_KEY,\n", - " \"LOG_LEVEL\": \"INFO\",\n", - " },\n", - " ),\n", - " )\n", - "\n", - "print(f\"Agent created: {agent.name}, version: {agent.version}, id {agent.id}\")" - ] - }, - { - "cell_type": "markdown", - "id": "b56c768b", - "metadata": {}, - "source": [ - "## 3. Test The Hosted Agent (Direct)\n", - "\n", - "**Purpose:** Validate your agent works by calling the Foundry Responses API directly using your Azure CLI credential.\n", - "\n", - "This is your baseline test—if this fails, APIM proxy tests will also fail. Use this to confirm:\n", - "- Agent reached \"Running\" status ✅\n", - "- Network connectivity to Foundry is working ✅\n", - "- Authentication with your credential works ✅\n", - "- Agent payload format is correct ✅\n", - "\n", - "**How it works:**\n", - "- Endpoint: `{PROJECT_ENDPOINT}/agents/{AGENT_NAME}/endpoint/protocols/openai/responses?api-version=v1`\n", - "- Auth: Bearer token with `https://ai.azure.com/.default` audience (from your Azure CLI login)\n", - "- Headers: Includes `Foundry-Features: HostedAgents=V1Preview` (required for preview access)\n", - "\n", - "If this test succeeds, you know the agent itself is working correctly." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2c0c6c90", - "metadata": {}, - "outputs": [], - "source": [ - "import json\n", - "import requests\n", - "from azure.core.credentials import AccessToken\n", - "from azure.identity import AzureCliCredential\n", - "\n", - "url = build_foundry_responses_url(PROJECT_ENDPOINT, AGENT_NAME)\n", - "\n", - "if \"credential\" not in globals():\n", - " credential = AzureCliCredential()\n", - "\n", - "# Get a token for Foundry Responses API\n", - "token: AccessToken = credential.get_token(\"https://ai.azure.com/.default\")\n", - "\n", - "headers = {\n", - " \"Authorization\": f\"Bearer {token.token}\",\n", - " \"Content-Type\": DEFAULT_CONTENT_TYPE,\n", - " \"Foundry-Features\": FOUNDRY_FEATURES_HEADER,\n", - "}\n", - "\n", - "payload = {\n", - " \"input\": DIRECT_TEST_INPUT,\n", - " \"stream\": False,\n", - "}\n", - "\n", - "print(f\"POST {url}?api-version={API_VERSION}\")\n", - "print(f\"Agent Name: {AGENT_NAME}\")\n", - "print(f\"Payload: {json.dumps(payload, indent=2)}\")\n", - "print()\n", - "\n", - "response = requests.post(url, headers=headers, json=payload, params={\"api-version\": API_VERSION})\n", - "print(f\"Status: {response.status_code}\")\n", - "print(f\"Headers: {dict(response.headers)}\")\n", - "print(f\"Response text (first 500 chars): {response.text[:500]}\")\n", - "print()\n", - "\n", - "if response.status_code == 200:\n", - " try:\n", - " result = response.json()\n", - " print(\"Response JSON:\")\n", - " print(json.dumps(result, indent=2))\n", - " if \"output_text\" in result:\n", - " print(f\"\\nAgent output:\\n{result['output_text']}\")\n", - " except json.JSONDecodeError as e:\n", - " print(f\"Failed to parse JSON: {e}\")\n", - " print(f\"Raw response: {response.text}\")\n", - "else:\n", - " print(f\"Error: {response.status_code}\")\n", - " if response.text:\n", - " try:\n", - " print(json.dumps(response.json(), indent=2))\n", - " except Exception:\n", - " print(response.text)" - ] - }, - { - "cell_type": "markdown", - "id": "39e7b9ff", - "metadata": {}, - "source": [ - "## 4. Test The Hosted Agent Via APIM\n", - "\n", - "**Purpose:** Route your request through Azure API Management instead of calling Foundry directly.\n", - "\n", - "This validates the production-like path:\n", - "- Client → APIM Gateway (subscription key auth) → Foundry Responses API\n", - "\n", - "**Important: Agent-Specific Routing**\n", - "\n", - "Foundry Hosted Agents **require** the agent name in the URL path. There is no generic `/responses` endpoint that accepts `agent_reference` in the request body. Each agent must have its own URL path:\n", - "\n", - "```\n", - "POST https://apim-{APIM_SUFFIX}.azure-api.net/hosted-agent-responses/agents/{AGENT_NAME}/endpoint/protocols/openai/responses\n", - "```\n", - "\n", - "**What APIM does automatically:**\n", - "- Injects managed identity bearer token for Foundry authentication (audience: `https://ai.azure.com`)\n", - "- Enforces `Content-Type: application/json` header\n", - "- Injects `Foundry-Features: HostedAgents=V1Preview` header for preview access\n", - "- Your client only needs the APIM subscription key (`api-key` header)\n", - "\n", - "**Configuration details** are in [hosted-agent-policy.xml](../../hosted-agent-policy.xml)—update there if you need to change defaults.\n", - "\n", - "Compare this test result with Section 3 to ensure both paths (direct and APIM-proxied) produce consistent responses." - ] - }, - { - "cell_type": "markdown", - "id": "e7d2c90c", - "metadata": {}, - "source": [ - "### Get deployment outputs\n", - "\n", - "Before testing via APIM, retrieve the outputs from your infrastructure deployment notebook and update the **top configuration cell** (Cell 3):\n", - "\n", - "- `APIM_SUFFIX`: The unique suffix for your APIM instance\n", - "- `APIM_SUBSCRIPTION_KEY`: The starter subscription key from APIM outputs\n", - "- `PROJECT_ENDPOINT`: The Foundry agents project endpoint (or let it be computed from `APIM_SUFFIX`)\n", - "\n", - "Keeping these values in one place makes reruns and troubleshooting much easier." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "06ed7a7f", - "metadata": {}, - "outputs": [], - "source": [ - "print(\"Using APIM/Foundry values from the top configuration cell:\")\n", - "print(f\"APIM_SUFFIX: {APIM_SUFFIX}\")\n", - "print(f\"APIM_SUBSCRIPTION_KEY: {APIM_SUBSCRIPTION_KEY[:20]}...\" if len(APIM_SUBSCRIPTION_KEY) > 20 else f\"APIM_SUBSCRIPTION_KEY: {APIM_SUBSCRIPTION_KEY}\")\n", - "print(f\"PROJECT_ENDPOINT: {PROJECT_ENDPOINT}\")\n", - "print()\n", - "print(\"If these are placeholders, update Cell 3 before running APIM tests.\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b474be31", - "metadata": {}, - "outputs": [], - "source": [ - "import json\n", - "import requests\n", - "\n", - "url = build_apim_responses_url(APIM_SUFFIX, AGENT_NAME)\n", - "\n", - "headers = {\n", - " \"api-key\": APIM_SUBSCRIPTION_KEY,\n", - " \"Content-Type\": DEFAULT_CONTENT_TYPE,\n", - " \"Foundry-Features\": FOUNDRY_FEATURES_HEADER,\n", - "}\n", - "\n", - "payload = {\n", - " \"input\": DIRECT_TEST_INPUT,\n", - " \"stream\": False,\n", - "}\n", - "\n", - "print(f\"POST {url}?api-version={API_VERSION}\")\n", - "print(f\"APIM Suffix: {APIM_SUFFIX}\")\n", - "print(f\"Agent Name (in URL path): {AGENT_NAME}\")\n", - "print(f\"Content-Type: {DEFAULT_CONTENT_TYPE}\")\n", - "print(f\"Headers: api-key={APIM_SUBSCRIPTION_KEY[:20]}..., Content-Type, Foundry-Features\")\n", - "print(f\"Payload: {json.dumps(payload, indent=2)}\")\n", - "print()\n", - "\n", - "response = requests.post(url, headers=headers, json=payload, params={\"api-version\": API_VERSION})\n", - "print(f\"Status: {response.status_code}\")\n", - "print()\n", - "\n", - "# Extract response from payload\n", - "apim_response = None\n", - "agent_text = None\n", - "\n", - "if response.status_code == 200:\n", - " try:\n", - " result = response.json()\n", - " apim_response = result\n", - "\n", - " # Extract agent text from nested structure\n", - " if \"output\" in result and len(result[\"output\"]) > 0:\n", - " message = result[\"output\"][0]\n", - " if \"content\" in message and len(message[\"content\"]) > 0:\n", - " agent_text = message[\"content\"][0].get(\"text\", \"\")\n", - "\n", - " print(\"=\" * 80)\n", - " print(\"AGENT RESPONSE (via APIM):\")\n", - " print(\"=\" * 80)\n", - " if agent_text:\n", - " print(agent_text)\n", - " else:\n", - " print(\"Full response:\")\n", - " print(json.dumps(result, indent=2))\n", - " print(\"=\" * 80)\n", - "\n", - " except json.JSONDecodeError as e:\n", - " print(f\"Failed to parse JSON: {e}\")\n", - " print(f\"Raw response: {response.text}\")\n", - "else:\n", - " print(f\"Error: {response.status_code}\")\n", - " if response.text:\n", - " try:\n", - " apim_response = response.json()\n", - " print(json.dumps(apim_response, indent=2))\n", - " except Exception:\n", - " print(response.text)\n", - "\n", - "print(\"\\nExtracted response stored in 'apim_response' variable\")\n", - "print(\"Agent text stored in 'agent_text' variable\")" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.12.10" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/modules/cognitive-services/v3/foundry.bicep b/modules/cognitive-services/v3/foundry.bicep index cb7bbe9a..7d3dd3b3 100644 --- a/modules/cognitive-services/v3/foundry.bicep +++ b/modules/cognitive-services/v3/foundry.bicep @@ -28,6 +28,10 @@ param foundryProjectName string = 'default' @secure() param appInsightsInstrumentationKey string = '' +@description('The connection string for Application Insights. When provided, it is used as the App Insights connection credential so runtimes (for example, Foundry Hosted Agents) can configure Azure Monitor correctly.') +@secure() +param appInsightsConnectionString string = '' + @description('The resource ID for Application Insights') param appInsightsId string = '' @@ -123,7 +127,7 @@ resource appInsightsConnection 'Microsoft.CognitiveServices/accounts/connections ResourceId: appInsightsId } credentials: { - key: appInsightsInstrumentationKey + key: empty(appInsightsConnectionString) ? appInsightsInstrumentationKey : appInsightsConnectionString } } }] diff --git a/modules/monitor/v1/appinsights.bicep b/modules/monitor/v1/appinsights.bicep index dac55cef..3e993f63 100644 --- a/modules/monitor/v1/appinsights.bicep +++ b/modules/monitor/v1/appinsights.bicep @@ -84,5 +84,6 @@ resource workbook 'Microsoft.Insights/workbooks@2022-04-01' = if (useWorkbook) { output id string = applicationInsights.id output name string = applicationInsights.name output instrumentationKey string = applicationInsights.properties.InstrumentationKey +output connectionString string = applicationInsights.properties.ConnectionString output appId string = applicationInsights.properties.AppId output applicationInsightsName string = applicationInsightsName From 97073fe84b78e11b237851f9e86cee29fb0537d2 Mon Sep 17 00:00:00 2001 From: George Ollis Date: Fri, 10 Jul 2026 14:36:53 +0100 Subject: [PATCH 17/17] Fix framework source path and update Python version in notebook metadata --- .../ai-foundry-hosted-agents-custom-framework.ipynb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/labs/ai-foundry-hosted-agents-custom-framework/ai-foundry-hosted-agents-custom-framework.ipynb b/labs/ai-foundry-hosted-agents-custom-framework/ai-foundry-hosted-agents-custom-framework.ipynb index e3af81ec..e99b7d76 100644 --- a/labs/ai-foundry-hosted-agents-custom-framework/ai-foundry-hosted-agents-custom-framework.ipynb +++ b/labs/ai-foundry-hosted-agents-custom-framework/ai-foundry-hosted-agents-custom-framework.ipynb @@ -257,7 +257,7 @@ "build_version = build_version + 1\n", "agent_name = frameworks[framework]['agent_name']\n", "agent_image_tag = f\"{frameworks[framework]['image']}:{build_version}\"\n", - "framework_src = f\"src/responses/agents/frameworks/{framework}\"\n", + "framework_src = f\"src/frameworks/{framework}\"\n", "model_deployment_name = models_config[0]['name']\n", "\n", "output = utils.run(\n", @@ -444,7 +444,7 @@ ], "metadata": { "kernelspec": { - "display_name": "pip2uv", + "display_name": "Python 3", "language": "python", "name": "python3" }, @@ -458,7 +458,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.13" + "version": "3.12.10" } }, "nbformat": 4,