Skip to content

Add opt-in unified API mode for prompt voice agents - #9634

Open
JianW (v1212) wants to merge 7 commits into
Azure:mainfrom
v1212:users/wujia/prompt-voice-agent-unified-api
Open

Add opt-in unified API mode for prompt voice agents#9634
JianW (v1212) wants to merge 7 commits into
Azure:mainfrom
v1212:users/wujia/prompt-voice-agent-unified-api

Conversation

@v1212

@v1212 JianW (v1212) commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds an opt-in AZURE_VOICE_AGENT_API mode for prompt voice agents so azd can deploy through the unified /agents API while keeping legacy /voice_agents as the default.
  • Supports legacy, unified, and unified-flat modes to cover current regional rollout and West US 2 TiP/spec validation.
  • Uses a preview-header remote GET to choose unified create vs update, persists unified agent versions, and stores callable wss://.../endpoint/protocols/voice?api-version=v1 endpoints.

Why

  • Existing regions still depend on the legacy /voice_agents API and object-shaped audio.output.voice payload.
  • West US 2 TiP now supports the unified /agents API and the newer flat audio.output.voice shape from the latest REST spec.
  • This PR creates a safe API migration layer before rebasing the advanced prompt voice settings work on top of the unified API.

Validation

  • go test ./... -count=1
  • go build ./...
  • cspell lint 'extensions/**/*.go' 'extensions/**/*.md' --config ./.vscode/cspell.yaml --no-progress
  • Live West US 2 TiP smoke with AZURE_VOICE_AGENT_API=unified-flat: provision, deploy, repeat deploy via remote GET + unified update path, GET assertion for flat output shape, persisted AGENT_<SERVICE>_VERSION, and wss://.../agents/{name}/endpoint/protocols/voice?api-version=v1 endpoint.
  • Adapted full prompt voice test guide flow in West US 2 with AZURE_VOICE_AGENT_API=unified-flat: managed agent init/provision/deploy, BYOM realtime and BYOM cascaded model deployments, BYOM service init/deploy, unified /agents/{name} control-plane GET assertions for managed/self_deployed model types and flat output shape, same-agent redeploy through unified update path, and voice endpoint route smoke (400 expected for non-WebSocket GET).
  • Legacy-to-unified migration smoke in West US 2: first deploy used default legacy mode and /voice_agents, then AZURE_VOICE_AGENT_API=unified-flat redeployed the same agent through /agents/{name} update and returned flat output shape.
  • Legacy default regression in West US 2 without AZURE_VOICE_AGENT_API: managed, BYOM realtime, and BYOM cascaded all deployed through /voice_agents; endpoints remained legacy https://.../voice_agents/{name} markers and AGENT_<SERVICE>_VERSION was cleared/empty.
  • All live test resource groups were cleaned up after validation.

Fixes #9654

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).
20 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

@github-actions github-actions Bot added the ext-agents azure.ai.agents extension label Aug 19, 2026
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).
20 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds opt-in unified API deployment modes for prompt voice agents while retaining legacy behavior.

Changes:

  • Adds legacy, unified, and unified-flat deployment modes.
  • Supports unified create/update, version persistence, and WebSocket endpoints.
  • Adds flat voice payload models, documentation, and tests.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
README.md Documents voice API modes and behavior.
service_target_agent.go Implements mode selection, deployment, and persistence.
service_target_agent_test.go Tests mode resolution and endpoints.
agent_yaml/map.go Builds flat voice payloads.
agent_yaml/map_voice_test.go Tests flat voice mapping.
agent_api/operations.go Adds unified API operations.
agent_api/operations_test.go Tests unified routes and headers.
agent_api/models.go Defines flat voice models.

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread cli/azd/extensions/azure.ai.agents/internal/project/service_target_agent.go Outdated
Comment thread cli/azd/extensions/azure.ai.agents/internal/project/service_target_agent.go Outdated
Copilot AI review requested due to automatic review settings August 20, 2026 04:13

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated no new comments.

Suppressed comments (3)

cli/azd/extensions/azure.ai.agents/internal/pkg/agents/agent_yaml/map_voice_test.go:250

  • [azd-code-reviewer] These unchecked assertions can panic when the generated wire shape changes, hiding which field is malformed. Guard each decoded JSON level so the test fails with a localized diagnostic instead.
	definition := wire["definition"].(map[string]any)
	audio := definition["audio"].(map[string]any)
	output := audio["output"].(map[string]any)

cli/azd/extensions/azure.ai.agents/internal/project/service_target_agent.go:2334

  • [azd-code-reviewer] The new create/update decision tree is not covered by the added tests. The client tests verify each HTTP method in isolation, but they would not catch regressions where a 404 updates, a 200 creates, or a non-404 GET error is ignored. Add orchestration tests for successful GET, 404, and another error status, asserting which follow-up request is issued.
	remoteAgent, getErr := agentClient.GetVoiceAgentUnified(
		ctx, request.Name, agent_api.AgentEndpointAPIVersion, overriddenHost,
	)
	if getErr == nil && remoteAgent != nil {
		progress("Updating voice agent using unified API")

cli/azd/extensions/azure.ai.agents/internal/project/service_target_agent.go:2186

  • [azd-code-reviewer] This new os.Getenv input is missing from the canonical environment-variable reference. cli/azd/docs/environment-variables.md is the source of truth and already has an azure.ai.agents section; add AZURE_VOICE_AGENT_API there with its accepted values, precedence, and legacy default so the README and reference do not drift.
		mode = strings.TrimSpace(os.Getenv(voiceAgentAPIEnvKey))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the timeline of this in the backend? I really don't like having all of this backcompat support for something that's still private preview and clearly in flux. If the backend is actively rolling out, then we should wait for that to complete and just make the full switch.

Comment thread cli/azd/extensions/azure.ai.agents/README.md Outdated
…ice-agent-unified-api

# Conflicts:
#	cli/azd/extensions/azure.ai.agents/README.md
Copilot AI review requested due to automatic review settings August 21, 2026 01:36

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated no new comments.

Suppressed comments (2)

cli/azd/extensions/azure.ai.agents/internal/pkg/agents/agent_yaml/map_voice_test.go:250

  • azd-code-reviewer: These unchecked assertions turn an unexpected serialized shape into a package-stopping panic instead of a useful test failure. Guard each lookup and type assertion before descending into the next map.
	definition := wire["definition"].(map[string]any)
	audio := definition["audio"].(map[string]any)
	output := audio["output"].(map[string]any)

cli/azd/extensions/azure.ai.agents/internal/project/service_target_agent.go:2334

  • azd-code-reviewer: The core 200-vs-404 dispatch is not exercised by automated tests. The added client tests verify each HTTP method independently, so a regression that selects update after a 404, creates after a 200, or mutates after another GET failure would still pass. Add table-driven coverage around this branch for 200, 404, and non-404 failures.
	remoteAgent, getErr := agentClient.GetVoiceAgentUnified(
		ctx, request.Name, agent_api.AgentEndpointAPIVersion, overriddenHost,
	)
	if getErr == nil && remoteAgent != nil {
		progress("Updating voice agent using unified API")

Copilot AI review requested due to automatic review settings August 21, 2026 05:30
@v1212

Copy link
Copy Markdown
Contributor Author

Thanks for the review. I removed the prompt voice API mode details from the public README for now; we'll add public docs when the prompt voice flag is removed. I also created follow-up #9681 to remove the temporary legacy API integration after unified API rollout stabilizes, and updated #9654 to track restoring the docs later.\n\nFor the temporary backcompat: service rollout is still in progress, the service team confirmed the existing /voice_agents API will remain supported for a transition period, and azd needs to line up with the end-of-month public preview timeline. This PR keeps legacy as the default while enabling private regression against the new /agents path; once rollout is stable we can switch the default and remove the compatibility modes via #9681.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated no new comments.

Suppressed comments (4)

cli/azd/extensions/azure.ai.agents/internal/pkg/agents/agent_yaml/map_voice_test.go:250

  • azd-code-reviewer: These unchecked assertions can panic and abort the package when the marshaled wire shape regresses, hiding which JSON level was malformed. Guard each decoded map assertion so the test reports a normal, localized failure.
	definition := wire["definition"].(map[string]any)
	audio := definition["audio"].(map[string]any)
	output := audio["output"].(map[string]any)

cli/azd/extensions/azure.ai.agents/internal/project/service_target_agent.go:2272

  • azd-code-reviewer: Persisting a unified voice version makes the existing contract comments stale: service_target_agent.go:554-556 says every prompt-voice deploy has no version and records only NAME+ENDPOINT, and internal/cmd/doctor/checks_agent_status.go:705-709 makes the same assumption. Update them to distinguish legacy from unified mode; otherwise future changes may incorrectly treat the new VERSION as impossible.
	if apiMode != voiceAgentAPIModeLegacy {
		versionValue = agentObject.Versions.Latest.Version

cli/azd/extensions/azure.ai.agents/internal/project/service_target_agent.go:2173

  • azd-code-reviewer: AZURE_VOICE_AGENT_API is a new user-facing opt-in switch, but a repository-wide search finds no documentation for it outside the implementation. Add it to the extension documentation with the default, accepted values, regional/preview limitations, and precedence between azd environment values and the process environment; otherwise users cannot discover or safely configure the mode after this PR description is gone.

This issue also appears on line 2271 of the same file.

const voiceAgentAPIEnvKey = "AZURE_VOICE_AGENT_API"

cli/azd/extensions/azure.ai.agents/internal/cmd/nextstep/state.go:833

  • azd-code-reviewer: This changes ServiceState.IsDeployed so prompt-voice services are marked deployed from AGENT_<KEY>_ENDPOINT, but its contract in internal/cmd/nextstep/types.go:229-234 still states that deployment always requires a non-empty VERSION. Update that documentation to describe the voice endpoint exception so callers do not rely on the old invariant.
	// Voice deploys use the base ENDPOINT env var as the completion marker. The
	// legacy voice API does not produce AGENT_<KEY>_VERSION, and unified voice
	// deploys write VERSION before ENDPOINT to keep ENDPOINT as the final marker.
	// Require ENDPOINT for voice even when VERSION is present, otherwise a partial
	// env write could be reported as deployed before the callable endpoint was

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ext-agents azure.ai.agents extension

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Track prompt voice unified API deployment mode

4 participants