Subchapter 53.67
foundry-agent/create/references/voice-agent-smoke-test.mdMarkdown8 KBView on GitHub
How to verify a deployed Microsoft Foundry Voice Agent — either a Prompt Voice Agent or a Hosted Voice wrapper — over the managed Foundry voice WebSocket endpoint.
Why not
azd ai agent invoke?azd ai agent invokedoes not support Voice Agents. Always verify them over the managedvoiceWebSocket endpoint or in the Microsoft Foundry portal (https://ai.azure.com). You can inspect the deployed endpoint URL withazd ai agent endpoint show <voice-service>.
The bundled text-driven managed Voice WebSocket client validates:
It does not validate microphone capture, real spoken-input STT quality, VAD/turn-taking behavior, barge-in/interruption, playback or voice quality, browser/device behavior, or perceived latency.
After the automated gate passes, use the Voice Agent Playground URL from azd ai agent show --output json and recommend a manual session in the Foundry portal. The user should test microphone input, STT, VAD and turn-taking, interruption, audio playback and voice quality, browser/device behavior, and perceived latency.
Report automated verification and manual acceptance separately. Never claim the portal-only properties were validated by the smoke helper or that the manual step was completed unless the user actually performed it.
wss://<project-host>/api/projects/<project>/agents/<voice-agent-name>/endpoint/protocols/voice?api-version=v1&agent_session_id=<session-id>AZURE_AI_PROJECT_ENDPOINT / FOUNDRY_PROJECT_ENDPOINT (https://<project-host>/api/projects/<project>).Authorization: Entra access token for resource https://ai.azure.com (az account get-access-token --resource https://ai.azure.com --query accessToken -o tsv), formatted dynamically as "{} {}".format("Bearer", token). Never hard-code tokens or API keys in scripts or commits.Foundry-Features: VoiceAgents=V1Previewname.kind: voice wrapper’s name (not the kind: hosted target’s name) to test the full end-to-end Voice pipeline.Install websockets in your Python environment and ensure Azure credentials are already available. The helper tries Azure CLI first and optionally falls back to DefaultAzureCredential when azure-identity is installed.
python -m pip install websocketsRun the paired helper scripts from the microsoft-foundry skill root (plugins/azure-skills/skills/microsoft-foundry):
Both wrappers launch the shared Python client, which owns authentication, protocol handling, response validation, and JSON output.
Note that PowerShell uses PascalCase parameter names (-Endpoint, -AgentName, -Text, -ExpectedMarker, -Timeout, -OutputAudio, -DryRun, -Help), whereas Bash uses kebab-case flags (--endpoint, --agent-name, --text, --expected-marker, --timeout, --output-audio, --dry-run, --help).
Bash
./foundry-agent/create/scripts/smoke-test-voice.sh \
--endpoint "https://<account>.services.ai.azure.com/api/projects/<project>" \
--agent-name "<voice-agent-name>" \
--dry-runPowerShell
.\foundry-agent\create\scripts\smoke-test-voice.ps1 `
-Endpoint "https://<account>.services.ai.azure.com/api/projects/<project>" `
-AgentName "<voice-agent-name>" `
-DryRunBash
./foundry-agent/create/scripts/smoke-test-voice.sh \
--endpoint "$AZURE_AI_PROJECT_ENDPOINT" \
--agent-name "<voice-agent-name>" \
--text "In one short sentence, introduce yourself." \
--timeout 180PowerShell
.\foundry-agent\create\scripts\smoke-test-voice.ps1 `
-Endpoint $env:AZURE_AI_PROJECT_ENDPOINT `
-AgentName "<voice-agent-name>" `
-Text "In one short sentence, introduce yourself." `
-Timeout 180When testing a Hosted Voice Agent running the official voice-live-bridge-basic-python target (or any agent with a deterministic response), pass --expected-marker / -ExpectedMarker (for example, --text "/help" --expected-marker "Commands:") to assert that the returned transcript matches the requested turn rather than a greeting.
| Exit Code | Meaning |
|---|---|
0 | Smoke test passed (response.done for the uniquely tagged requested response with response.status == "completed", non-empty matching response.output_audio_transcript.delta/done, non-empty matching base64 response.output_audio.delta, and optional --expected-marker / -ExpectedMarker matched) or --dry-run / --help succeeded |
1 | Smoke test failed (authentication error, WebSocket error frame, non-completed status, empty transcript, missing expected marker, zero audio deltas, timeout, or missing websockets package) |
2 | Usage or argument validation error (missing --endpoint/-Endpoint, missing --agent-name/-AgentName, invalid --timeout/-Timeout, or unknown option) |
.../agents/<agent>/endpoint/protocols/voice?api-version=v1&agent_session_id=<id> with Foundry-Features: VoiceAgents=V1Preview and an Entra token for https://ai.azure.com (resolved via shutil.which("az.cmd" if os.name == "nt" else "az") or "az" with DefaultAzureCredential fallback).session.updated and Optional Greeting:
session.updated, then applies a short 1.0s greeting-detection grace interval.response.created / response.output_*) starts before or during the grace window, drains the entire greeting through its response.done without recording greeting transcript/audio as the requested turn.{"type": "conversation.item.create", "item": {"type": "message", "role": "user", "content": [{"type": "input_text", "text": "<prompt>"}]}}response.create with a unique metadata marker for the smoke-test turn.response.created ID and ignores greeting or unrelated response events.response.output_audio_transcript.delta (delta) and response.output_audio_transcript.done (transcript).response.output_audio.delta (delta).error event, if response.done reports response.status != "completed", if transcript/audio is empty, or if --expected-marker / -ExpectedMarker is absent from the transcript.agent, prompt_text, response_id, status, transcript, audio_base64_characters, event_types, and optional expected_marker.