Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 3 additions & 6 deletions sdk/ai/azure-ai-projects/.env.template
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,9 @@ TEAMS_CONNECTION_NAME=
TEAMS_CHANNEL_URL=

# Read by the samples under samples/agents/voice/ (model deployment name, agent name, model type,
# and a conversation ID for the read-conversation samples). Distinct from FOUNDRY_VOICE_MODEL_NAME below.
FOUNDRY_VOICE_MODEL=
# and a conversation ID for the read-conversation samples). Also read by the recorded voice-agent
# CRUD, conversation, realtime, and telephony tests (tests/test_base.py and friends).
FOUNDRY_VOICE_AGENT_MODEL=
Comment on lines 106 to +109
FOUNDRY_VOICE_MODEL_TYPE=
FOUNDRY_VOICE_AGENT_NAME=
FOUNDRY_VOICE_CONVERSATION_ID=
Expand All @@ -123,10 +124,6 @@ AZURE_SKIP_LIVE_RECORDING=true
#Used by hosted agent
FOUNDRY_HOSTED_AGENT_NAME=

# Read by the recorded voice-agent CRUD, conversation, realtime-live, and telephony tests
# (tests/test_base.py and friends), not by any sample.
FOUNDRY_VOICE_MODEL_NAME=

# Used in Fine-tuning tests
COMPLETED_OAI_MODEL_SFT_FINE_TUNING_JOB_ID=
COMPLETED_OAI_MODEL_RFT_FINE_TUNING_JOB_ID=
Expand Down
6 changes: 3 additions & 3 deletions sdk/ai/azure-ai-projects/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ Breaking changes in beta classes:

* Added `sample_voice_agent_basic.py` under `samples/agents/voice/`, demonstrating the Voice Agent management lifecycle.
* Added `sample_voice_agent_generate.py`, demonstrating guided Voice Agent authoring with `.beta.agents.create_from_prompt()`.
* Added `sample_voice_agent_live_text_conversation.py`, demonstrating a persisted, typed realtime Voice Agent conversation.
* Added `sample_voice_agent_live_audio_conversation_async.py`, demonstrating a hands-free realtime audio conversation with barge-in.
* Added `sample_voice_agent_live_function_tool.py`, demonstrating client-side function execution during a realtime Voice Agent session.
* Added `sample_voice_agent_realtime_text_conversation.py`, demonstrating a persisted, typed realtime Voice Agent conversation.
* Added `sample_voice_agent_realtime_audio_conversation_async.py`, demonstrating a hands-free realtime audio conversation with barge-in.
* Added `sample_voice_agent_realtime_function_tool.py`, demonstrating client-side function execution during a realtime Voice Agent session.
* Added `sample_voice_agent_read_conversation.py`, demonstrating how to read a persisted Voice Agent conversation and transcript.
* Added `sample_voice_agent_read_conversation_audio.py`, demonstrating how to retrieve merged conversation audio and individual audio segments.
* Added `sample_voice_agent_versions.py`, demonstrating Voice Agent version and draft management.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
Set these environment variables with your own values:
1) FOUNDRY_PROJECT_ENDPOINT - The Azure AI Project endpoint, as found in the Overview
page of your Microsoft Foundry portal.
2) FOUNDRY_VOICE_MODEL - Optional. The realtime model deployment name.
Defaults to "gpt-realtime".
2) FOUNDRY_VOICE_AGENT_MODEL - Optional. The managed (service-hosted) realtime model
identifier. Defaults to "gpt-realtime".
3) FOUNDRY_VOICE_AGENT_NAME - Optional. The name of the voice agent. If not
set, defaults to "MyVoiceAgent".
"""
Expand All @@ -47,7 +47,7 @@
load_dotenv()

endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"]
model = os.environ.get("FOUNDRY_VOICE_MODEL") or "gpt-realtime"
model = os.environ.get("FOUNDRY_VOICE_AGENT_MODEL") or "gpt-realtime"
agent_name = os.environ.get("FOUNDRY_VOICE_AGENT_NAME") or "MyVoiceAgent"

with (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
Set these environment variables with your own values:
1) FOUNDRY_PROJECT_ENDPOINT - The Azure AI Project endpoint, as found in the Overview
page of your Microsoft Foundry portal.
2) FOUNDRY_VOICE_MODEL - Optional. The realtime model deployment name.
Defaults to "gpt-realtime".
2) FOUNDRY_VOICE_AGENT_MODEL - Optional. The managed (service-hosted) realtime model
identifier. Defaults to "gpt-realtime".
3) FOUNDRY_VOICE_AGENT_NAME - Optional. The name of the voice agent. If not
set, defaults to "MyVoiceAgentAsync".
"""
Expand All @@ -38,7 +38,7 @@

async def main() -> None:
endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"]
model = os.environ.get("FOUNDRY_VOICE_MODEL") or "gpt-realtime"
model = os.environ.get("FOUNDRY_VOICE_AGENT_MODEL") or "gpt-realtime"
agent_name = os.environ.get("FOUNDRY_VOICE_AGENT_NAME") or "MyVoiceAgentAsync"

async with (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@
conversation owned by FOUNDRY_VOICE_AGENT_NAME. If unset, this sample
holds one short realtime text turn to produce one; see
voice_sample_util.py in this folder and
sample_voice_agent_live_text_conversation.py for a full interactive
sample_voice_agent_realtime_text_conversation.py for a full interactive
version.
4) FOUNDRY_VOICE_MODEL - Optional. The realtime model deployment name,
used only when creating the temporary agent. Defaults to "gpt-realtime".
4) FOUNDRY_VOICE_AGENT_MODEL - Optional. The managed (service-hosted) realtime model
identifier, used only when creating the temporary agent. Defaults to "gpt-realtime".
"""

import os
Expand All @@ -67,7 +67,7 @@
endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"]
agent_name = os.environ.get("FOUNDRY_VOICE_AGENT_NAME")
conversation_id = os.environ.get("FOUNDRY_VOICE_CONVERSATION_ID")
model = os.environ.get("FOUNDRY_VOICE_MODEL") or "gpt-realtime"
model = os.environ.get("FOUNDRY_VOICE_AGENT_MODEL") or "gpt-realtime"
# Only create (and later clean up) a temporary agent when the caller didn't name their own --
# creating a version on someone's existing agent could unexpectedly mutate it, and deleting that
# version afterward could delete the agent entirely if it was the agent's only version.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@
conversation owned by FOUNDRY_VOICE_AGENT_NAME. If unset, this sample
holds one short realtime text turn to produce one; see
voice_sample_util.py in this folder and
sample_voice_agent_live_text_conversation.py for a full interactive
sample_voice_agent_realtime_text_conversation.py for a full interactive
version.
4) FOUNDRY_VOICE_MODEL - Optional. The realtime model deployment name,
used only when creating the temporary agent. Defaults to "gpt-realtime".
4) FOUNDRY_VOICE_AGENT_MODEL - Optional. The managed (service-hosted) realtime model
identifier, used only when creating the temporary agent. Defaults to "gpt-realtime".
"""

import os
Expand Down Expand Up @@ -158,7 +158,7 @@ def main() -> None:
endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"]
agent_name = os.environ.get("FOUNDRY_VOICE_AGENT_NAME")
conversation_id = os.environ.get("FOUNDRY_VOICE_CONVERSATION_ID")
model = os.environ.get("FOUNDRY_VOICE_MODEL") or "gpt-realtime"
model = os.environ.get("FOUNDRY_VOICE_AGENT_MODEL") or "gpt-realtime"
# Only create (and later clean up) a temporary agent when the caller didn't name their own --
# creating a version on someone's existing agent could unexpectedly mutate it, and deleting
# that version afterward could delete the agent entirely if it was its only version.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,15 @@
pip install "azure-ai-projects[voice]>=2.7.0" azure-identity pyaudio

USAGE:
python sample_voice_agent_live_audio_conversation_async.py
python sample_voice_agent_realtime_audio_conversation_async.py

Environment variables:
1) FOUNDRY_PROJECT_ENDPOINT (required) - Foundry project endpoint:
https://<account>.services.ai.azure.com/api/projects/<project>
2) FOUNDRY_VOICE_MODEL - Optional. The realtime model deployment name.
Defaults to "gpt-realtime".
2) FOUNDRY_VOICE_AGENT_MODEL - Optional. The managed (service-hosted) realtime model
identifier. Defaults to "gpt-realtime".
3) FOUNDRY_VOICE_AGENT_NAME - Optional. Name for the agent created by this
sample. Defaults to "sample-live-audio-conversation-agent-async".
sample. Defaults to "sample-realtime-audio-conversation-agent-async".

Runs until you press Ctrl-C. Authenticates with DefaultAzureCredential, so
sign in first (e.g. `az login`).
Expand Down Expand Up @@ -416,8 +416,8 @@ async def _read_conversation(client: AIProjectClient, agent_name: str, conversat

async def audio_conversation() -> None:
endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"]
model = os.environ.get("FOUNDRY_VOICE_MODEL") or "gpt-realtime"
agent_name = os.environ.get("FOUNDRY_VOICE_AGENT_NAME") or "sample-live-audio-conversation-agent-async"
model = os.environ.get("FOUNDRY_VOICE_AGENT_MODEL") or "gpt-realtime"
agent_name = os.environ.get("FOUNDRY_VOICE_AGENT_NAME") or "sample-realtime-audio-conversation-agent-async"

async with (
DefaultAzureCredential() as credential,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,16 @@
`response.create` so the agent can finish its reply using the tool output.

USAGE:
python sample_voice_agent_live_function_tool.py
python sample_voice_agent_realtime_function_tool.py

Before running the sample:

pip install "azure-ai-projects[voice]>=2.7.0" azure-identity python-dotenv

Set these environment variables with your own values:
1) FOUNDRY_PROJECT_ENDPOINT - The Azure AI Project endpoint.
2) FOUNDRY_VOICE_MODEL - Optional. The realtime model deployment name.
Defaults to "gpt-realtime".
2) FOUNDRY_VOICE_AGENT_MODEL - Optional. The managed (service-hosted) realtime model
identifier. Defaults to "gpt-realtime".
3) FOUNDRY_VOICE_AGENT_NAME - Optional. Name for the sample voice agent
created and deleted by this script. Defaults to
"sample-voice-agent-function-tool".
Expand Down Expand Up @@ -158,7 +158,7 @@ def _run_turn_with_tool_support(client: AIProjectClient, agent_name: str, prompt

def main() -> None:
endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"]
model = os.environ.get("FOUNDRY_VOICE_MODEL") or "gpt-realtime"
model = os.environ.get("FOUNDRY_VOICE_AGENT_MODEL") or "gpt-realtime"
agent_name = os.environ.get("FOUNDRY_VOICE_AGENT_NAME") or "sample-voice-agent-function-tool"

get_weather_tool = VoiceAgentFunctionTool(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,23 @@

Reply audio is PCM16, mono, 24 kHz and plays through the speakers when
``pyaudio`` is installed; runs headless otherwise. For a hands-free mic
conversation with barge-in, see sample_voice_agent_live_audio_conversation_async.py
conversation with barge-in, see sample_voice_agent_realtime_audio_conversation_async.py
(that sample needs concurrent send/receive so it stays async-only; see
sample_voice_agent_live_text_conversation_async.py for the async version of
sample_voice_agent_realtime_text_conversation_async.py for the async version of
this one).

pip install "azure-ai-projects[voice]>=2.7.0" azure-identity pyaudio

USAGE:
python sample_voice_agent_live_text_conversation.py
python sample_voice_agent_realtime_text_conversation.py

Environment variables:
1) FOUNDRY_PROJECT_ENDPOINT (required) - Foundry project endpoint:
https://<account>.services.ai.azure.com/api/projects/<project>
2) FOUNDRY_VOICE_MODEL - Optional. The realtime model deployment name.
Defaults to "gpt-realtime".
2) FOUNDRY_VOICE_AGENT_MODEL - Optional. The managed (service-hosted) realtime model
identifier. Defaults to "gpt-realtime".
3) FOUNDRY_VOICE_AGENT_NAME - Optional. Name for the agent created by this
sample. Defaults to "sample-live-text-conversation-agent".
sample. Defaults to "sample-realtime-text-conversation-agent".

Authenticates with DefaultAzureCredential, so sign in first (e.g. `az login`).
"""
Expand Down Expand Up @@ -349,8 +349,8 @@ def _read_conversation(client: AIProjectClient, agent_name: str, conversation_id

def text_conversation() -> None:
endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"]
model = os.environ.get("FOUNDRY_VOICE_MODEL") or "gpt-realtime"
agent_name = os.environ.get("FOUNDRY_VOICE_AGENT_NAME") or "sample-live-text-conversation-agent"
model = os.environ.get("FOUNDRY_VOICE_AGENT_MODEL") or "gpt-realtime"
agent_name = os.environ.get("FOUNDRY_VOICE_AGENT_NAME") or "sample-realtime-text-conversation-agent"

with (
DefaultAzureCredential() as credential,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,20 @@

Reply audio is PCM16, mono, 24 kHz and plays through the speakers when
``pyaudio`` is installed; runs headless otherwise. For a hands-free mic
conversation with barge-in, see sample_voice_agent_live_audio_conversation_async.py.
conversation with barge-in, see sample_voice_agent_realtime_audio_conversation_async.py.

pip install "azure-ai-projects[voice]>=2.7.0" azure-identity pyaudio

USAGE:
python sample_voice_agent_live_text_conversation_async.py
python sample_voice_agent_realtime_text_conversation_async.py

Environment variables:
1) FOUNDRY_PROJECT_ENDPOINT (required) - Foundry project endpoint:
https://<account>.services.ai.azure.com/api/projects/<project>
2) FOUNDRY_VOICE_MODEL - Optional. The realtime model deployment name.
Defaults to "gpt-realtime".
2) FOUNDRY_VOICE_AGENT_MODEL - Optional. The managed (service-hosted) realtime model
identifier. Defaults to "gpt-realtime".
3) FOUNDRY_VOICE_AGENT_NAME - Optional. Name for the agent created by this
sample. Defaults to "sample-live-text-conversation-agent-async".
sample. Defaults to "sample-realtime-text-conversation-agent-async".

Authenticates with DefaultAzureCredential, so sign in first (e.g. `az login`).
"""
Expand Down Expand Up @@ -356,8 +356,8 @@ async def _read_conversation(client: AIProjectClient, agent_name: str, conversat

async def text_conversation() -> None:
endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"]
model = os.environ.get("FOUNDRY_VOICE_MODEL") or "gpt-realtime"
agent_name = os.environ.get("FOUNDRY_VOICE_AGENT_NAME") or "sample-live-text-conversation-agent-async"
model = os.environ.get("FOUNDRY_VOICE_AGENT_MODEL") or "gpt-realtime"
agent_name = os.environ.get("FOUNDRY_VOICE_AGENT_NAME") or "sample-realtime-text-conversation-agent-async"

async with (
DefaultAzureCredential() as credential,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@

Set these environment variables with your own values:
1) FOUNDRY_PROJECT_ENDPOINT - The Azure AI Project endpoint.
2) FOUNDRY_VOICE_MODEL - Optional. The realtime model deployment name.
Defaults to "gpt-realtime".
2) FOUNDRY_VOICE_AGENT_MODEL - Optional. The managed (service-hosted) realtime model
identifier. Defaults to "gpt-realtime".
3) FOUNDRY_VOICE_AGENT_NAME - Optional. The name of the voice agent. If not
set, defaults to "sample-versioned-voice-agent".
"""
Expand All @@ -35,7 +35,7 @@
load_dotenv()

endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"]
model = os.environ.get("FOUNDRY_VOICE_MODEL") or "gpt-realtime"
model = os.environ.get("FOUNDRY_VOICE_AGENT_MODEL") or "gpt-realtime"
agent_name = os.environ.get("FOUNDRY_VOICE_AGENT_NAME") or "sample-versioned-voice-agent"


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@

Set these environment variables with your own values:
1) FOUNDRY_PROJECT_ENDPOINT - The Azure AI Project endpoint.
2) FOUNDRY_VOICE_MODEL - Optional. The realtime model (managed) or the
Foundry deployment name (BYOM). Defaults to "gpt-realtime".
2) FOUNDRY_VOICE_AGENT_MODEL - Optional. The realtime model (managed) or the
Foundry deployment name (BYOM). Defaults to "gpt-realtime". (FOUNDRY_VOICE_MODEL
is a deprecated alias for this variable, still read as a fallback for compatibility
with earlier samples.)
3) FOUNDRY_VOICE_MODEL_TYPE - Optional. "managed" (default) for a
service-hosted model, or "self_deployed" to bring your own deployment.
4) FOUNDRY_VOICE_AGENT_NAME - Optional. The name of the voice agent. If not
Expand Down Expand Up @@ -61,7 +63,10 @@
load_dotenv()

endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"]
model = os.environ.get("FOUNDRY_VOICE_MODEL") or "gpt-realtime"
# FOUNDRY_VOICE_MODEL is a deprecated alias for FOUNDRY_VOICE_AGENT_MODEL, read as a fallback so
# an existing self_deployed (BYOM) configuration doesn't silently start targeting "gpt-realtime"
# instead of the user's actual deployment name.
model = os.environ.get("FOUNDRY_VOICE_AGENT_MODEL") or os.environ.get("FOUNDRY_VOICE_MODEL") or "gpt-realtime"
# "managed" runs a service-hosted model; "self_deployed" (BYOM) uses your own
# Foundry deployment named by `model`. The service derives whether the model is
# realtime or cascaded; you don't set that here.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def hold_sample_conversation(
samples can run without requiring a conversation id up front. The agent named ``agent_name``
must already exist (see sample_voice_agent_basic.py) and be configured with ``store=True`` so
its conversations are persisted. For a full interactive conversation and a fuller explanation
of the realtime event flow used here, see sample_voice_agent_live_text_conversation.py.
of the realtime event flow used here, see sample_voice_agent_realtime_text_conversation.py.

:param project_client: The Foundry project client.
:param agent_name: The name of an existing voice agent, configured with ``store=True``.
Expand Down
68 changes: 68 additions & 0 deletions sdk/ai/azure-ai-projects/test-resources.bicep
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
//
// Provisions the Microsoft Foundry account/project used by the azure-ai-projects live Voice
// Agents realtime tests (tests/agents/test_voice_agent_realtime_livetest.py and its _async
// counterpart). See tests/README.md for details. The tests use a service-hosted realtime model
// (VoiceModelType.MANAGED), so no model deployment step is needed here.

@description('The client OID to grant Foundry User access to the test resources.')
param testApplicationOid string

@description('The base resource name.')
param baseName string = resourceGroup().name

@description('The location of the resource. By default, this is the same as the resource group.')
param location string = resourceGroup().location

var foundryAccountName = '${toLower(baseName)}-ai'
var foundryProjectName = '${toLower(baseName)}-project'
// Built-in "Foundry User" role -- lets the test principal create/manage voice agents in the project.
var foundryUserRoleId = subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '53ca6127-db72-4b80-b1b0-d745d6d5456d')

resource foundryAccount 'Microsoft.CognitiveServices/accounts@2025-04-01-preview' = {
name: foundryAccountName
location: location
kind: 'AIServices'
sku: {
name: 'S0'
}
identity: {
type: 'SystemAssigned'
}
properties: {
customSubDomainName: toLower(foundryAccountName)
allowProjectManagement: true
defaultProjectName: foundryProjectName
publicNetworkAccess: 'Enabled'
}

resource foundryProject 'projects' = {
name: foundryProjectName
location: location
identity: {
type: 'SystemAssigned'
}
sku: {
name: 'S0'
}
properties: {
displayName: foundryProjectName
description: 'Foundry project used by the azure-ai-projects live voice-agents-realtime tests.'
}
}
}

resource foundryUserRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(resourceGroup().id, foundryAccount.id, foundryUserRoleId)
scope: foundryAccount
properties: {
roleDefinitionId: foundryUserRoleId
principalId: testApplicationOid
}
}

// Outputs become environment variables injected into the test run. The live tests authenticate
// with Azure AD (see tests/test_base.py's use of devtools_testutils.get_credential), so no API
// key is exported here.
output FOUNDRY_PROJECT_ENDPOINT string = '${foundryAccount.properties.endpoints['AI Foundry API']}api/projects/${foundryProjectName}'
Loading
Loading