Skip to content

[AI Agents] Add GPT Live WebSocket support, samples, and tests - #50877

Open
Mike Guo (guotuofeng) wants to merge 13 commits into
myguo/gpt-live-autofrom
myguo/gpt-live-websocket
Open

Mike Guo (guotuofeng) wants to merge 13 commits into
myguo/gpt-live-autofrom
myguo/gpt-live-websocket

Conversation

@guotuofeng

@guotuofeng Mike Guo (guotuofeng) commented Oct 20, 2026 •

Copy link
Copy Markdown
Member

Description

Add handwritten native GPT Live WebSocket clients, interactive voice examples, and regression tests for Azure AI Agents.

Depends on #50875. Merge #50875 first. This PR remains based on myguo/gpt-live-auto so its diff contains only the additional handwritten work. The parent PR supplies the generated models, REST clients, TypeSpec pinning, and generation customizations for Azure/azure-rest-api-specs#47196.

Changes

  • Add synchronous and asynchronous native GPT Live connection/session clients through AgentsClientBuilder.beta(), with raw JSON events kept separate from the Realtime protocol.
  • Add Live-specific connection options and reuse the existing transport's authentication, proxy, header, buffering, and lifecycle behavior.
  • Add synchronous/asynchronous interactive text, microphone/speaker audio, and Responses function-tool examples, with agent cleanup and scripted text mode.
  • Support spoken greetings and replies, typed input, frontend transcripts, demand-aware silent PCM input, and explicit service/transport errors. Model configuration is parsed directly in each example; defaults are gpt-live-1 and gpt-5.6-terra.
  • Reuse the existing audio helpers and fix the related Realtime text example's fixed-name conflict replacement and cleanup.
  • Update README, JavaDoc, and CHANGELOG, and add local WebSocket/mock-HTTP regression coverage.

Interactive behavior

Native GPT Live does not provide a speech-finished event. Greeting and transcript utterance boundaries therefore use a one-second speech-inactivity heuristic and ignore silent/very-low-level output PCM. Completed captions wait until Enter while input is active; partial captions are not split at typed/backend turn boundaries. Long speech pauses can still divide utterances.

Interactive text mode streams paced silent PCM without a microphone; voice usage remains billable while typing or waiting. A noninterruptible console read may require Enter after a remote disconnect. Shared Reactor schedulers are shut down only by the standalone sample entry points.

Stack maintenance

Keep this PR based on myguo/gpt-live-auto while #50875 is open. After #50875 merges, rebase onto the updated feature/foundry-sdk/vnext as necessary, retarget this PR to that branch, and verify its diff before merging.

Validation

Run from sdk\ai in PowerShell:

mvn --% -f azure-ai-agents\pom.xml test checkstyle:check spotbugs:check -Dtest=VoiceAgent*WebSocket*Tests,GptLiveSamplesTests,VoiceAgentLive*SampleTests -Dspotless.skip=true -Dspotbugs.skip=false
  • Tests: passed, 179 tests, zero failures/errors/skips across native Live clients, shared synchronous/asynchronous WebSocket transport, GPT Live samples, and related Realtime sample coverage.
  • Checkstyle: passed, zero violations.
  • SpotBugs: failed, 42 findings in files unchanged by this PR, matching the existing baseline documented in [AI Agents] Regenerate SDK for GPT Live voice agents #50875. The combined command exits nonzero at this final step. No SpotBugs rules or exclusions were disabled or changed.
  • git --no-pager diff --cached --check: passed before committing.
  • Live Azure service sessions were not run during this validation. Remote CI for the new head has not yet been confirmed green.

All SDK Contribution checklist:

  • The pull request does not introduce [breaking changes]
  • CHANGELOG is updated for new features, bug fixes or other significant changes.
  • I have read the contribution guidelines.

General Guidelines and Best Practices

  • Title of the pull request is clear and informative.
  • There are a small number of commits, each of which have an informative message. This means that previously merged commits do not appear in the history of the PR. For more information on cleaning up the commits in your PR, see this page.

Testing Guidelines

  • Pull request includes test coverage for the included changes.

@azure-pipelines

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

@guotuofeng
Mike Guo (guotuofeng) marked this pull request as ready for review October 20, 2026 08:06
@guotuofeng
Mike Guo (guotuofeng) requested review from a team as code owners October 20, 2026 08:06

@kaylieee Kaylie (kaylieee) left a comment

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.

Can we expose typed send and receive apis for the new live session clients? We have the live event models available in our pinned openai-java dependency.

@kaylieee

Copy link
Copy Markdown
Member

Can we extract the shared connection, I/O, etc. logic into a shared internal transport class (eg. WebsocketSessionTransport) for both live and realtime? Adding isLive puts live handling logic in the existing realtime session client and receiving client events currently requires wrapping them as RawRealtimeServerEvent to then unwrap them. A neutral transport layer could expose raw messages and leave protocol specific handling to the respective clients.

@guotuofeng

Copy link
Copy Markdown
Member Author

Kaylie (@kaylieee) Following up on your typed Live API review comment: implemented in 2099e09.

Both sync and async Live session clients now expose sendEvent(com.openai.models.live.ClientEvent) and receiveTypedEvents() returning OpenAI Live ServerEvent models. The sync client also provides receiveTypedEvents(Duration). Existing raw JSON APIs remain available, and typed/raw receivers share the single-consumer limit. Tests cover typed commands/events and preservation of unknown events, fields, nested backend payloads, and Foundry conversation IDs.

One API-policy question remains: Checkstyle reports five ExternalDependencyExposedCheck violations because these public signatures expose OpenAI types (three typed receive declarations and two typed send declarations). Making them private/package-private would remove the requested application-facing typed APIs.

Would you agree with adding file-scoped exceptions in sdk/ai/azure-ai-agents/checkstyle-suppressions.xml for BetaVoiceAgentLiveWebSocketSessionClient.java and BetaVoiceAgentLiveWebSocketSessionAsyncClient.java, following the module's existing OpenAI API exceptions? This would preserve the requested model reuse while keeping the rule enabled elsewhere. I have not added suppressions pending your confirmation; Azure-owned event wrappers would be the alternative if exceptions are not acceptable.

Validation: 212 affected tests passed with zero failures/errors/skips; SpotBugs and git diff --check passed. Checkstyle remains failing on those five public API exposure violations. No live Azure service sessions were run.

@guotuofeng

Copy link
Copy Markdown
Member Author

Kaylie (@kaylieee) Following up on your shared transport comment: refactored in 2099e09. Extracted shared internal WebSocketSessionTransport<T> and WebSocketSessionAsyncTransport<T> for connection, authentication, proxy configuration, I/O, buffering, and lifecycle behavior. Blocking and async implementations remain independent, with no sync-over-async. Removed isLive/forLive and Live branches from the Realtime session clients. Each protocol client selects its own URI, handshake headers, subprotocol, and decoder. Live clients no longer wrap/unwrap events through RawRealtimeServerEvent or depend on Realtime session clients. Live transports use OpenAI ServerEvent; the shared generic transport also retains original raw messages so raw APIs preserve the exact wire JSON. Typed/raw receivers use the same bounded buffer and single-consumer claim. Protocol-specific decoders are supplied by the respective clients. This is a generic decoded-event transport with a raw-message view, rather than an exclusively raw transport. Added sync/async regression coverage verifying that Live and Realtime connections created from the same builder keep routes, subprotocols, and structured-input placement independent. Validation: 212 affected tests passed with zero failures/errors/skips; SpotBugs and git diff --check passed. The remaining five Checkstyle violations concern public OpenAI typed API exposure; my typed API follow-up proposes file-scoped exceptions pending your confirmation. No suppressions have been added and no live Azure service sessions were run.

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants