diff --git a/docs/copilot/DeploymentGuide.md b/docs/copilot/DeploymentGuide.md index 01fc82d5..a61924ee 100644 --- a/docs/copilot/DeploymentGuide.md +++ b/docs/copilot/DeploymentGuide.md @@ -74,16 +74,20 @@ After import, add the Fabric and Foundry agents again in Copilot Studio. Use Fab 5. Select **Microsoft Foundry**. 6. Authenticate with Microsoft Entra. 7. Provide the Azure AI Foundry project endpoint configured during the Foundry deployment. The article uses the format `https://.services.ai.azure.com/api/projects/`. -8. Save the connection and confirm the Foundry agent appears in the connected-agent list. - - +8. Set the following: + - **Name**: ChatAgent + - **Description**: You are a data analyst assistant for Microsoft IQ with access to documents and reference materials. + - **Agent Id**: ChatAgent + - This is the same name as the agent in Foundry. +9. Save the connection and confirm the Foundry agent appears in the connected-agent list. + ### 4.2 Add the Fabric Data Agent 1. Stay in the same **Microsoft IQ Accelerator** agent. 2. Navigate to **Agents** from the top pane and then select + Add to add agents. 3. Select **Connect to an external agent** and select **Microsoft Fabric** from the dropdown. 4. If there's already a connection between Microsoft Fabric and the Microsoft IQ agent, you can select **Next** and move to next step. Otherwise, select the dropdown and select Create new connection to establish a connection between Microsoft Fabric and Copilot Studio. -5. Pick the published **Fabric Data Agent** that belongs to this solution. +5. Pick the published **Fabric Data Agent** named **RetailSC Ontology Agent** that belongs to this solution. 6. Save the connection and make sure the Fabric agent now shows up in the list of connected agents. --- @@ -115,4 +119,17 @@ After import, add the Fabric and Foundry agents again in Copilot Studio. Use Fab 3. Click **Publish** and wait for publishing to complete (1-2 minutes) 4. Configure Teams as a channel: **Channels** → **Microsoft Teams** → **Turn on Teams** -The solution is now active and ready to test. See the [Testing Guide](./TestingGuide.md) for the golden path QA flow. \ No newline at end of file +The solution is now active and ready to test. See the [Testing Guide](./TestingGuide.md) for the golden path QA flow. + +## Troubleshooting + +- **The connector 'Azure AI Foundry Agent Service' returned an HTTP error with code 400. Inner Error: Agent ChatAgent endpoint does not support activity. Please update the agent endpoint to support this protocol.** + - This error means the Foundry Agent doesn't have the `ActivityProtocol` enabled. This can occur on new deployments of agents. You will need to [programmatically enable this setting](https://learn.microsoft.com/en-us/azure/foundry/agents/how-to/configure-agent?tabs=rest#enable-protocols-and-authorization-schemes) on your `ChatAgent`. You can do this via the Azure CLI. + ```shell + az rest \ + --method patch \ + --url https://.services.ai.azure.com/api/projects//agents/ChatAgent?api-version=v1 \ + --resource https://ai.azure.com \ + --headers 'Content-Type=application/merge-patch+json' \ + --body '{"agent_endpoint": {"protocol_configuration": {"activity": {}, "responses": {}, "invocations": {}, "a2a": {}}, "authorization_schemes": [{"type": "Entra"}, {"type": "BotServiceRbac"}]}}' + ``` diff --git a/infra/scripts/foundry/agent_api.py b/infra/scripts/foundry/agent_api.py index 5068988a..bff6e599 100755 --- a/infra/scripts/foundry/agent_api.py +++ b/infra/scripts/foundry/agent_api.py @@ -6,6 +6,7 @@ - Building the default Knowledge Base agent instructions. - Creating a RemoteTool project connection for a Knowledge Base MCP endpoint. - Creating or replacing an AI Foundry agent with the Knowledge Base MCP tool. +- Enabling the Activity protocol and authorization schemes on an agent endpoint. """ import logging @@ -160,7 +161,9 @@ def create_kb_mcp_connection( ) credential = DefaultAzureCredential() - token = get_bearer_token_provider(credential, "https://management.azure.com/.default")() + token = get_bearer_token_provider( + credential, "https://management.azure.com/.default" + )() headers = {"Authorization": f"Bearer {token}"} url = ( @@ -249,3 +252,50 @@ def create_or_update_agent( agent_name=agent_name, definition=agent_definition, ) + + +def enable_activity_protocol(project_endpoint: str, agent_name: str) -> None: + """Enable Activity and Responses protocols on an AI Foundry agent endpoint. + + Configures the authorization schemes required for Microsoft Copilot Studio + to communicate with the agent through the Activity protocol. + + Args: + project_endpoint: Azure AI Project endpoint URL. + agent_name: Name of the agent resource to update. + + Raises: + RuntimeError: If the agent endpoint configuration cannot be updated. + """ + import requests as http_requests + from azure.identity import DefaultAzureCredential, get_bearer_token_provider + + credential = DefaultAzureCredential() + token = get_bearer_token_provider(credential, "https://ai.azure.com/.default")() + headers = { + "Authorization": f"Bearer {token}", + "Content-Type": "application/merge-patch+json", + } + url = f"{project_endpoint.rstrip('/')}/agents/{agent_name}?api-version=v1" + body = { + "agent_endpoint": { + "protocol_configuration": { + "activity": {}, + "responses": {}, + "invocations": {}, + "a2a": {}, + }, + "authorization_schemes": [ + {"type": "Entra"}, + {"type": "BotServiceRbac"}, + ], + } + } + + response = http_requests.patch(url, headers=headers, json=body) + if response.status_code == 200: + return + raise RuntimeError( + "Activity protocol configuration failed " + f"({response.status_code}): {response.text[:500]}" + ) diff --git a/infra/scripts/foundry/step_agent_setup.py b/infra/scripts/foundry/step_agent_setup.py index b114bd05..317d4c42 100755 --- a/infra/scripts/foundry/step_agent_setup.py +++ b/infra/scripts/foundry/step_agent_setup.py @@ -11,12 +11,14 @@ from pathlib import Path from common.config import DATA_DIR + from foundry.agent_api import ( CHAT_AGENT_NAME, build_agent_instructions, create_agent_client, create_kb_mcp_connection, create_or_update_agent, + enable_activity_protocol, ) # Module-level logger — inherits configuration from the root logger set up @@ -55,9 +57,13 @@ def setup_agent( """ # Default scenario info _data_path = Path(DATA_DIR) - _config_dir = _data_path / "config" if (_data_path / "config").exists() else _data_path + _config_dir = ( + _data_path / "config" if (_data_path / "config").exists() else _data_path + ) _scenario_name = solution_name - _scenario_desc = "Managing delivery operations, inventory logistics, and supplier relationships." + _scenario_desc = ( + "Managing delivery operations, inventory logistics, and supplier relationships." + ) # Build agent instructions _instructions = build_agent_instructions(_scenario_name, _scenario_desc) @@ -104,4 +110,9 @@ def setup_agent( mcp_endpoint=_mcp_ep, connection_name=kb_mcp_connection_name, ) + logger.info(" Enabling Activity protocol and authorization…") + enable_activity_protocol( + project_endpoint=agent_endpoint, + agent_name=CHAT_AGENT_NAME, + ) logger.info(f" Agent '{_agent.name}' ready (id: {_agent.id})")