[Fixes] A2a Gateway - ensure azure foundry agents work (#17943)

* add agents  v2 fixes azure

* fix auth

* get_azure_ad_token fix

* docs foundry
This commit is contained in:
Ishaan Jaff 2025-12-13 16:08:03 -08:00 • committed by GitHub
parent 232bb33fec
commit 14eed8aff7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 234 additions and 91 deletions

View file

@ -9,7 +9,47 @@ Call Azure AI Foundry Agents in the OpenAI Request/Response format.
|----------|---------|
| Description | Azure AI Foundry Agents provides hosted agent runtimes that can execute agentic workflows with foundation models, tools, and code interpreters. |
| Provider Route on LiteLLM | `azure_ai/agents/{AGENT_ID}` |
| Provider Doc | [Azure AI Foundry Agents ↗](https://learn.microsoft.com/en-us/rest/api/aifoundry/aiagents/create-thread-and-run/create-thread-and-run) |
| Provider Doc | [Azure AI Foundry Agents ↗](https://learn.microsoft.com/en-us/azure/ai-foundry/agents/quickstart) |
## Authentication
Azure AI Foundry Agents require **Azure AD authentication** (not API keys). You can authenticate using:
### Option 1: Service Principal (Recommended for Production)
Set these environment variables:
```bash
export AZURE_TENANT_ID="your-tenant-id"
export AZURE_CLIENT_ID="your-client-id"
export AZURE_CLIENT_SECRET="your-client-secret"
```
LiteLLM will automatically obtain an Azure AD token using these credentials.
### Option 2: Azure AD Token (Manual)
Pass a token directly via `api_key`:
```bash
# Get token via Azure CLI
az account get-access-token --resource "https://ai.azure.com" --query accessToken -o tsv
```
### Required Azure Role
Your Service Principal or user must have the **Azure AI Developer** or **Azure AI User** role on your Azure AI Foundry project.
To assign via Azure CLI:
```bash
az role assignment create \
--assignee-object-id "<service-principal-object-id>" \
--assignee-principal-type "ServicePrincipal" \
--role "Azure AI Developer" \
--scope "/subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.CognitiveServices/accounts/<resource>"
```
Or add via **Azure AI Foundry Portal** → Your Project → **Project users** → **+ New user**.
## Quick Start
@ -34,6 +74,7 @@ You can find the Agent ID in your Azure AI Foundry portal under Agents.
import litellm
# Make a completion request to your Azure AI Foundry Agent
# Uses AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET env vars for auth
response = litellm.completion(
model="azure_ai/agents/asst_abc123",
messages=[
@ -42,8 +83,7 @@ response = litellm.completion(
"content": "Explain machine learning in simple terms"
}
],
api_base="https://your-project.services.ai.azure.com",
api_key="your-api-key",
api_base="https://your-resource.services.ai.azure.com/api/projects/your-project",
)
print(response.choices[0].message.content)
@ -62,8 +102,7 @@ response = await litellm.acompletion(
"content": "What are the key principles of software architecture?"
}
],
api_base="https://your-project.services.ai.azure.com",
api_key="your-api-key",
api_base="https://your-resource.services.ai.azure.com/api/projects/your-project",
stream=True,
)
@ -84,14 +123,18 @@ model_list:
- model_name: azure-agent-1
litellm_params:
model: azure_ai/agents/asst_abc123
api_base: https://your-project.services.ai.azure.com
api_key: os.environ/AZURE_API_KEY
api_base: https://your-resource.services.ai.azure.com/api/projects/your-project
# Service Principal auth (recommended)
tenant_id: os.environ/AZURE_TENANT_ID
client_id: os.environ/AZURE_CLIENT_ID
client_secret: os.environ/AZURE_CLIENT_SECRET
- model_name: azure-agent-math-tutor
litellm_params:
model: azure_ai/agents/asst_def456
api_base: https://your-project.services.ai.azure.com
api_key: os.environ/AZURE_API_KEY
api_base: https://your-resource.services.ai.azure.com/api/projects/your-project
# Or pass Azure AD token directly
api_key: os.environ/AZURE_AD_TOKEN
```
</TabItem>
@ -196,16 +239,16 @@ for chunk in stream:
## Environment Variables
You can set the following environment variables to configure Azure AI Foundry Agents:
| Variable | Description |
|----------|-------------|
| `AZURE_API_BASE` | The Azure AI Foundry project endpoint (e.g., `https://your-project.services.ai.azure.com`) |
| `AZURE_API_KEY` | Your Azure AI Foundry API key |
| `AZURE_TENANT_ID` | Azure AD tenant ID for Service Principal auth |
| `AZURE_CLIENT_ID` | Application (client) ID of your Service Principal |
| `AZURE_CLIENT_SECRET` | Client secret for your Service Principal |
```bash
export AZURE_API_BASE="https://your-project.services.ai.azure.com"
export AZURE_API_KEY="your-api-key"
export AZURE_TENANT_ID="your-tenant-id"
export AZURE_CLIENT_ID="your-client-id"
export AZURE_CLIENT_SECRET="your-client-secret"
```
## Conversation Continuity (Thread Management)
@ -219,8 +262,7 @@ import litellm
response1 = await litellm.acompletion(
model="azure_ai/agents/asst_abc123",
messages=[{"role": "user", "content": "My name is Alice"}],
api_base="https://your-project.services.ai.azure.com",
api_key="your-api-key",
api_base="https://your-resource.services.ai.azure.com/api/projects/your-project",
)
# Get the thread_id from the response
@ -230,8 +272,7 @@ thread_id = response1._hidden_params.get("thread_id")
response2 = await litellm.acompletion(
model="azure_ai/agents/asst_abc123",
messages=[{"role": "user", "content": "What's my name?"}],
api_base="https://your-project.services.ai.azure.com",
api_key="your-api-key",
api_base="https://your-resource.services.ai.azure.com/api/projects/your-project",
thread_id=thread_id, # Pass the thread_id to continue conversation
)
@ -256,8 +297,7 @@ response = litellm.completion(
"content": "Analyze this data and provide insights",
}
],
api_base="https://your-project.services.ai.azure.com",
api_key="your-api-key",
api_base="https://your-resource.services.ai.azure.com/api/projects/your-project",
thread_id="thread_abc123", # Optional: Continue existing conversation
instructions="Be concise and focus on key insights", # Optional: Override agent instructions
)
@ -271,8 +311,10 @@ model_list:
- model_name: azure-agent-analyst
litellm_params:
model: azure_ai/agents/asst_abc123
api_base: https://your-project.services.ai.azure.com
api_key: os.environ/AZURE_API_KEY
api_base: https://your-resource.services.ai.azure.com/api/projects/your-project
tenant_id: os.environ/AZURE_TENANT_ID
client_id: os.environ/AZURE_CLIENT_ID
client_secret: os.environ/AZURE_CLIENT_SECRET
instructions: "Be concise and focus on key insights"
```

View file

@ -294,20 +294,18 @@ def get_azure_ad_token(
Azure AD token as string if successful, None otherwise
"""
# Extract parameters
# Use `or` instead of default parameter to handle cases where key exists but value is None
azure_ad_token_provider = litellm_params.get("azure_ad_token_provider")
azure_ad_token = litellm_params.get("azure_ad_token", None) or get_secret_str(
azure_ad_token = litellm_params.get("azure_ad_token") or get_secret_str(
"AZURE_AD_TOKEN"
)
tenant_id = litellm_params.get("tenant_id", os.getenv("AZURE_TENANT_ID"))
client_id = litellm_params.get("client_id", os.getenv("AZURE_CLIENT_ID"))
client_secret = litellm_params.get(
"client_secret", os.getenv("AZURE_CLIENT_SECRET")
)
azure_username = litellm_params.get("azure_username", os.getenv("AZURE_USERNAME"))
azure_password = litellm_params.get("azure_password", os.getenv("AZURE_PASSWORD"))
scope = litellm_params.get(
"azure_scope",
os.getenv("AZURE_SCOPE", "https://cognitiveservices.azure.com/.default"),
tenant_id = litellm_params.get("tenant_id") or os.getenv("AZURE_TENANT_ID")
client_id = litellm_params.get("client_id") or os.getenv("AZURE_CLIENT_ID")
client_secret = litellm_params.get("client_secret") or os.getenv("AZURE_CLIENT_SECRET")
azure_username = litellm_params.get("azure_username") or os.getenv("AZURE_USERNAME")
azure_password = litellm_params.get("azure_password") or os.getenv("AZURE_PASSWORD")
scope = litellm_params.get("azure_scope") or os.getenv(
"AZURE_SCOPE", "https://cognitiveservices.azure.com/.default"
)
if scope is None:
scope = "https://cognitiveservices.azure.com/.default"

View file

@ -1,5 +1,5 @@
"""
Handler for Azure AI Agent Service API.
Handler for Azure Foundry Agent Service API.
This handler executes the multi-step agent flow:
1. Create thread (or use existing)
@ -8,8 +8,14 @@ This handler executes the multi-step agent flow:
4. Retrieve the assistant's response messages
Model format: azure_ai/agents/<agent_id>
API Base format: https://<AIFoundryResourceName>.services.ai.azure.com/api/projects/<ProjectName>
Authentication: Uses Azure AD Bearer tokens (not API keys)
Get token via: az account get-access-token --resource 'https://ai.azure.com'
Supports both polling-based and native streaming (SSE) modes.
See: https://learn.microsoft.com/en-us/azure/ai-foundry/agents/quickstart
"""
import asyncio
@ -60,24 +66,27 @@ class AzureAIAgentsHandler:
# -------------------------------------------------------------------------
# URL Builders
# -------------------------------------------------------------------------
# Azure Foundry Agents API uses /assistants, /threads, etc. directly
# See: https://learn.microsoft.com/en-us/azure/ai-foundry/agents/quickstart
# -------------------------------------------------------------------------
def _build_thread_url(self, api_base: str, api_version: str) -> str:
return f"{api_base}/openai/threads?api-version={api_version}"
return f"{api_base}/threads?api-version={api_version}"
def _build_messages_url(self, api_base: str, thread_id: str, api_version: str) -> str:
return f"{api_base}/openai/threads/{thread_id}/messages?api-version={api_version}"
return f"{api_base}/threads/{thread_id}/messages?api-version={api_version}"
def _build_runs_url(self, api_base: str, thread_id: str, api_version: str) -> str:
return f"{api_base}/openai/threads/{thread_id}/runs?api-version={api_version}"
return f"{api_base}/threads/{thread_id}/runs?api-version={api_version}"
def _build_run_status_url(self, api_base: str, thread_id: str, run_id: str, api_version: str) -> str:
return f"{api_base}/openai/threads/{thread_id}/runs/{run_id}?api-version={api_version}"
return f"{api_base}/threads/{thread_id}/runs/{run_id}?api-version={api_version}"
def _build_list_messages_url(self, api_base: str, thread_id: str, api_version: str) -> str:
return f"{api_base}/openai/threads/{thread_id}/messages?api-version={api_version}"
return f"{api_base}/threads/{thread_id}/messages?api-version={api_version}"
def _build_create_thread_and_run_url(self, api_base: str, api_version: str) -> str:
"""URL for the create-thread-and-run endpoint (supports streaming)."""
return f"{api_base}/openai/threads/runs?api-version={api_version}"
return f"{api_base}/threads/runs?api-version={api_version}"
# -------------------------------------------------------------------------
# Response Helpers
@ -140,12 +149,21 @@ class AzureAIAgentsHandler:
optional_params: dict,
headers: Optional[dict],
) -> tuple:
"""Prepare common parameters for completion."""
"""Prepare common parameters for completion.
Azure Foundry Agents API uses Bearer token authentication:
- Authorization: Bearer <token> (Azure AD token from 'az account get-access-token --resource https://ai.azure.com')
See: https://learn.microsoft.com/en-us/azure/ai-foundry/agents/quickstart
"""
if headers is None:
headers = {}
headers["Content-Type"] = "application/json"
# Azure Foundry Agents uses Bearer token authentication
# The api_key here is expected to be an Azure AD token
if api_key:
headers["api-key"] = api_key
headers["Authorization"] = f"Bearer {api_key}"
api_version = optional_params.get("api_version", self.config.DEFAULT_API_VERSION)
agent_id = self.config._get_agent_id(model, optional_params)

View file

@ -1,17 +1,24 @@
"""
Transformation for Azure AI Agent Service API.
Transformation for Azure Foundry Agent Service API.
Azure AI Agent Service provides an Assistants-like API for running agents.
Azure Foundry Agent Service provides an Assistants-like API for running agents.
This follows the OpenAI Assistants pattern: create thread -> add messages -> create/poll run.
Model format: azure_ai/agents/<agent_id>
API Base format: https://<AIFoundryResourceName>.services.ai.azure.com/api/projects/<ProjectName>
Authentication: Uses Azure AD Bearer tokens (not API keys)
Get token via: az account get-access-token --resource 'https://ai.azure.com'
The API uses these endpoints:
- POST /openai/threads - Create a thread
- POST /openai/threads/{thread_id}/messages - Add message to thread
- POST /openai/threads/{thread_id}/runs - Create a run
- GET /openai/threads/{thread_id}/runs/{run_id} - Poll run status
- GET /openai/threads/{thread_id}/messages - List messages in thread
- POST /threads - Create a thread
- POST /threads/{thread_id}/messages - Add message to thread
- POST /threads/{thread_id}/runs - Create a run
- GET /threads/{thread_id}/runs/{run_id} - Poll run status
- GET /threads/{thread_id}/messages - List messages in thread
See: https://learn.microsoft.com/en-us/azure/ai-foundry/agents/quickstart
"""
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple, Union
@ -59,8 +66,10 @@ class AzureAIAgentsConfig(BaseConfig):
4. Retrieve the assistant's response messages
"""
# Default API version for Azure AI Agent Service
DEFAULT_API_VERSION = "2024-07-01-preview"
# Default API version for Azure Foundry Agent Service
# GA version: 2025-05-01, Preview: 2025-05-15-preview
# See: https://learn.microsoft.com/en-us/azure/ai-foundry/agents/quickstart
DEFAULT_API_VERSION = "2025-05-01"
# Polling configuration
MAX_POLL_ATTEMPTS = 60
@ -236,13 +245,19 @@ class AzureAIAgentsConfig(BaseConfig):
api_base: Optional[str] = None,
) -> dict:
"""
Validate and set up environment for Azure Agents requests.
Validate and set up environment for Azure Foundry Agents requests.
Azure Foundry Agents uses Bearer token authentication with Azure AD tokens.
Get token via: az account get-access-token --resource 'https://ai.azure.com'
See: https://learn.microsoft.com/en-us/azure/ai-foundry/agents/quickstart
"""
headers["Content-Type"] = "application/json"
# Add API key if provided
# Azure Foundry Agents uses Bearer token authentication
# The api_key here is expected to be an Azure AD token
if api_key:
headers["api-key"] = api_key
headers["Authorization"] = f"Bearer {api_key}"
return headers
@ -310,15 +325,38 @@ class AzureAIAgentsConfig(BaseConfig):
headers: Optional[dict] = None,
) -> Any:
"""
Dispatch method for Azure AI Agents completion.
Dispatch method for Azure Foundry Agents completion.
Routes to sync or async completion based on acompletion flag.
Supports native streaming via SSE when stream=True and acompletion=True.
Authentication: Uses Azure AD Bearer tokens.
- Pass api_key directly as an Azure AD token
- Or set up Azure AD credentials via environment variables for automatic token retrieval:
- AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET (Service Principal)
See: https://learn.microsoft.com/en-us/azure/ai-foundry/agents/quickstart
"""
from litellm.llms.azure.common_utils import get_azure_ad_token
from litellm.llms.azure_ai.agents.handler import azure_ai_agents_handler
from litellm.types.router import GenericLiteLLMParams
# If no api_key is provided, try to get Azure AD token
if api_key is None:
raise ValueError("api_key is required for Azure AI Agents")
# Try to get Azure AD token using the existing Azure auth mechanisms
# This uses the scope for Azure AI (ai.azure.com) instead of cognitive services
# Create a GenericLiteLLMParams with the scope override for Azure Foundry Agents
azure_auth_params = dict(litellm_params) if litellm_params else {}
azure_auth_params["azure_scope"] = "https://ai.azure.com/.default"
api_key = get_azure_ad_token(GenericLiteLLMParams(**azure_auth_params))
if api_key is None:
raise ValueError(
"api_key (Azure AD token) is required for Azure Foundry Agents. "
"Either pass api_key directly, or set AZURE_TENANT_ID, AZURE_CLIENT_ID, "
"and AZURE_CLIENT_SECRET environment variables for Service Principal auth. "
"Manual token: az account get-access-token --resource 'https://ai.azure.com'"
)
if acompletion:
if stream:
# Native async streaming via SSE - return the async generator directly

View file

@ -93,8 +93,8 @@
{
"key": "api_base",
"label": "Azure AI API Base",
"placeholder": "https://your-project.services.ai.azure.com",
"tooltip": "The base URL for your Azure AI Foundry project endpoint",
"placeholder": "https://your-resource.services.ai.azure.com/api/projects/your-project",
"tooltip": "The base URL for your Azure AI Foundry project endpoint (e.g., https://your-resource.services.ai.azure.com/api/projects/your-project)",
"required": true,
"field_type": "text",
"default_value": null,
@ -102,10 +102,40 @@
},
{
"key": "api_key",
"label": "Azure AI API Key",
"label": "Azure AD Token",
"placeholder": null,
"tooltip": "API key for authenticating with your Azure AI Foundry project",
"required": true,
"tooltip": "Azure AD Bearer token for authentication. Optional if using Service Principal credentials below. Get via: az account get-access-token --resource https://ai.azure.com",
"required": false,
"field_type": "password",
"default_value": null,
"include_in_litellm_params": true
},
{
"key": "tenant_id",
"label": "Azure Tenant ID",
"placeholder": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"tooltip": "Azure AD Tenant ID for Service Principal authentication. Find in Azure Portal > Azure Active Directory > Overview",
"required": false,
"field_type": "text",
"default_value": null,
"include_in_litellm_params": true
},
{
"key": "client_id",
"label": "Azure Client ID",
"placeholder": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"tooltip": "Application (client) ID of your Service Principal. Find in Azure Portal > App registrations > your app",
"required": false,
"field_type": "text",
"default_value": null,
"include_in_litellm_params": true
},
{
"key": "client_secret",
"label": "Azure Client Secret",
"placeholder": null,
"tooltip": "Client secret for your Service Principal. Create in Azure Portal > App registrations > your app > Certificates & secrets",
"required": false,
"field_type": "password",
"default_value": null,
"include_in_litellm_params": true

View file

@ -1,9 +1,9 @@
"""
Tests for Azure AI Agent Service integration.
Tests for Azure Foundry Agent Service integration.
These tests require an Azure AI Agent Service endpoint and a pre-configured agent.
These tests require an Azure Foundry Agent Service endpoint and a pre-configured agent.
The Azure AI Agent Service uses the Assistants API pattern:
The Azure Foundry Agent Service uses the Assistants API pattern:
1. Create a thread
2. Add messages to the thread
3. Create and poll a run
@ -11,9 +11,16 @@ The Azure AI Agent Service uses the Assistants API pattern:
Model format: azure_ai/agents/<agent_id>
API Base format: https://<AIFoundryResourceName>.services.ai.azure.com/api/projects/<ProjectName>
Authentication: Uses Azure AD Bearer tokens (not API keys)
Get token via: az account get-access-token --resource 'https://ai.azure.com'
Example environment variables:
AZURE_AI_API_BASE=https://your-project.services.ai.azure.com
AZURE_AI_API_KEY=your-api-key
AZURE_AGENTS_API_BASE=https://litellm-ci-cd-prod.services.ai.azure.com/api/projects/litellm-ci-cd
AZURE_AGENTS_API_KEY=<Azure AD Bearer token>
See: https://learn.microsoft.com/en-us/azure/ai-foundry/agents/quickstart
"""
import os
@ -29,13 +36,15 @@ import litellm
@pytest.mark.asyncio
async def test_azure_ai_agents_acompletion_non_streaming():
"""
Test non-streaming acompletion call to Azure AI Agent Service.
Test non-streaming acompletion call to Azure Foundry Agent Service.
Uses the multi-step flow: create thread -> add messages -> create/poll run -> get messages
"""
api_base = os.environ.get("AZURE_API_BASE")
api_key = os.environ.get("AZURE_API_KEY")
agent_id = "asst_shNRIVxMPuvSRVWP5WvVe4jE"
api_base = os.environ.get("AZURE_AGENTS_API_BASE")
api_key = os.environ.get("AZURE_AGENTS_API_KEY")
agent_id = os.environ.get("AZURE_AGENTS_AGENT_ID", "asst_hbnoK9BOCcHhC3lC4MDroVGG")
if not api_base or not api_key:
pytest.skip("AZURE_AGENTS_API_BASE and AZURE_AGENTS_API_KEY environment variables required")
response = await litellm.acompletion(
model=f"azure_ai/agents/{agent_id}",
@ -62,12 +71,15 @@ async def test_azure_ai_agents_acompletion_non_streaming():
@pytest.mark.asyncio
async def test_azure_ai_agents_acompletion_streaming():
"""
Test native streaming acompletion call to Azure AI Agent Service.
Test native streaming acompletion call to Azure Foundry Agent Service.
Uses the create-thread-and-run endpoint with stream=True for SSE streaming.
"""
api_base = os.environ.get("AZURE_API_BASE")
api_key = os.environ.get("AZURE_API_KEY")
agent_id = os.environ.get("AZURE_AGENTS_AGENT_ID", "asst_shNRIVxMPuvSRVWP5WvVe4jE")
api_base = os.environ.get("AZURE_AGENTS_API_BASE")
api_key = os.environ.get("AZURE_AGENTS_API_KEY")
agent_id = os.environ.get("AZURE_AGENTS_AGENT_ID", "asst_hbnoK9BOCcHhC3lC4MDroVGG")
if not api_base or not api_key:
pytest.skip("AZURE_AGENTS_API_BASE and AZURE_AGENTS_API_KEY environment variables required")
response = await litellm.acompletion(
model=f"azure_ai/agents/{agent_id}",
@ -223,7 +235,7 @@ def test_azure_ai_agents_config_transform_request():
assert request["messages"][0]["role"] == "system"
assert request["messages"][1]["role"] == "user"
assert "api_version" in request
assert request["api_version"] == "2024-07-01-preview"
assert request["api_version"] == "2025-05-01"
def test_azure_ai_agents_provider_detection():
@ -243,7 +255,9 @@ def test_azure_ai_agents_provider_detection():
def test_azure_ai_agents_validate_environment():
"""
Test that headers are correctly set up.
Test that headers are correctly set up with Bearer token authentication.
Azure Foundry Agents uses Bearer token authentication (Azure AD tokens).
"""
from litellm.llms.azure_ai.agents.transformation import AzureAIAgentsConfig
@ -255,41 +269,44 @@ def test_azure_ai_agents_validate_environment():
messages=[],
optional_params={},
litellm_params={},
api_key="test-api-key",
api_base="https://test.services.ai.azure.com",
api_key="test-azure-ad-token",
api_base="https://test.services.ai.azure.com/api/projects/test-project",
)
assert headers["Content-Type"] == "application/json"
assert headers["api-key"] == "test-api-key"
assert headers["Authorization"] == "Bearer test-azure-ad-token"
def test_azure_ai_agents_handler_url_builders():
"""
Test the URL building methods in the handler.
Azure Foundry Agents API uses direct paths without /openai/ prefix.
See: https://learn.microsoft.com/en-us/azure/ai-foundry/agents/quickstart
"""
from litellm.llms.azure_ai.agents.handler import AzureAIAgentsHandler
handler = AzureAIAgentsHandler()
api_base = "https://test.services.ai.azure.com"
api_version = "2024-07-01-preview"
api_base = "https://test.services.ai.azure.com/api/projects/test-project"
api_version = "2025-05-01"
thread_id = "thread_abc123"
run_id = "run_xyz789"
# Test thread URL - uses /openai/ prefix
# Test thread URL - direct path without /openai/ prefix
thread_url = handler._build_thread_url(api_base, api_version)
assert thread_url == f"{api_base}/openai/threads?api-version={api_version}"
assert thread_url == f"{api_base}/threads?api-version={api_version}"
# Test messages URL
messages_url = handler._build_messages_url(api_base, thread_id, api_version)
assert messages_url == f"{api_base}/openai/threads/{thread_id}/messages?api-version={api_version}"
assert messages_url == f"{api_base}/threads/{thread_id}/messages?api-version={api_version}"
# Test runs URL
runs_url = handler._build_runs_url(api_base, thread_id, api_version)
assert runs_url == f"{api_base}/openai/threads/{thread_id}/runs?api-version={api_version}"
assert runs_url == f"{api_base}/threads/{thread_id}/runs?api-version={api_version}"
# Test run status URL
status_url = handler._build_run_status_url(api_base, thread_id, run_id, api_version)
assert status_url == f"{api_base}/openai/threads/{thread_id}/runs/{run_id}?api-version={api_version}"
assert status_url == f"{api_base}/threads/{thread_id}/runs/{run_id}?api-version={api_version}"
def test_azure_ai_agents_extract_content_from_messages():
@ -340,12 +357,12 @@ async def test_azure_ai_agents_conversation_continuity():
"""
Test that thread_id can be used for conversation continuity.
"""
api_base = os.environ.get("AZURE_AI_API_BASE")
api_key = os.environ.get("AZURE_AI_API_KEY")
agent_id = os.environ.get("AZURE_AI_AGENTS_AGENT_ID", "asst_shNRIVxMPuvSRVWP5WvVe4jE")
api_base = os.environ.get("AZURE_AGENTS_API_BASE")
api_key = os.environ.get("AZURE_AGENTS_API_KEY")
agent_id = os.environ.get("AZURE_AGENTS_AGENT_ID", "asst_hbnoK9BOCcHhC3lC4MDroVGG")
if not api_base or not api_key:
pytest.skip("AZURE_AI_API_BASE and AZURE_AI_API_KEY environment variables required")
pytest.skip("AZURE_AGENTS_API_BASE and AZURE_AGENTS_API_KEY environment variables required")
try:
# First message