Repository navigation
[azure-ai-projects] Add GPT Live WebSocket clients and samples - #49631
Open
xitzhang (xitzhang) wants to merge 18 commits into
Open
xitzhang (xitzhang) wants to merge 18 commits into
xitzhang (xitzhang) wants to merge 18 commits into
Conversation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Azure Pipelines: 10 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
Input-recording overwrite protection, mapping serialization, and concurrent asynchronous cleanup require correction.
3 open issues
What changed in this PR
Adds handwritten GPT Live WebSocket support to Azure AI Projects, building on the generated APIs in #49629, which must merge first.
Changes:
- Adds synchronous and asynchronous Live clients using shared Realtime transport.
- Adds lifecycle, multi-turn text, WAV streaming, and function-tool samples with deterministic tests.
- Updates documentation, public exports, and API reports.
Paths below are relative to sdk/ai/azure-ai-projects/.
| File | Description |
|---|---|
tests/samples/test_live_samples.py |
Adds offline sample guards. |
tests/agents/test_realtime_client.py |
Adapts shared-transport identification checks. |
tests/agents/test_realtime_client_async.py |
Adapts asynchronous identification checks. |
tests/agents/test_live_client.py |
Covers Live protocol and transport behavior. |
samples/agents/voice/sample_voice_agent_live_text_conversation.py |
Demonstrates synchronous multi-turn text. |
samples/agents/voice/sample_voice_agent_live_text_conversation_async.py |
Demonstrates asynchronous multi-turn text. |
samples/agents/voice/sample_voice_agent_live_function_tool.py |
Demonstrates Responses function results. |
samples/agents/voice/sample_voice_agent_live_connection.py |
Demonstrates session lifecycle. |
samples/agents/voice/sample_voice_agent_live_audio_conversation_async.py |
Streams WAV audio and captures replies. |
samples/agents/voice/live_sample_utils.py |
Shares lifecycle and event helpers. |
README.md |
Documents Live usage and limitations. |
docs/public-methods.md |
Lists the Live entry point. |
docs/GeneratePublicMethodsDoc.ps1 |
Includes Live in method discovery. |
CHANGELOG.md |
Records Live support and samples. |
azure/ai/projects/operations/_patch.py |
Exposes synchronous Live operations. |
azure/ai/projects/aio/operations/_patch.py |
Exposes asynchronous Live operations. |
azure/ai/projects/aio/_realtime.py |
Extracts shared asynchronous transport. |
azure/ai/projects/aio/_live.py |
Implements asynchronous Live support. |
azure/ai/projects/_realtime.py |
Extracts shared synchronous transport. |
azure/ai/projects/_live.py |
Implements synchronous Live support. |
azure/ai/projects/_live_utils.py |
Defines shared Live protocol helpers. |
api.metadata.yml |
Refreshes the API hash. |
api.md |
Reports updated public APIs. |
Review effort: Balanced
…t stack Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Validate generated event registry values through a Mapping of objects so Pyright correctly narrows model classes without casts. Add invalid-registry regression coverage. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add sync and async REST-only samples for stored conversation, item, and recording APIs, with opt-in downloads and deletion. Add 42 enabled offline guards and related documentation. Verified all 18 sync/async REST targets against the real service and 555 focused unit cases. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
xitzhang (xitzhang)
marked this pull request as ready for review
October 21, 2026 18:24
xitzhang (xitzhang)
requested review from
a team,
Darren Cohen (dargilco),
Glenn Harper (glharper),
Howie Leung (howieleung),
kingernupur,
Nikolay Rovinskiy (nick863) and
Travis Angevine (trangevi)
as code owners
October 21, 2026 18:24
Protect input WAV recordings from hard-linked output aliases, normalize mapping inputs in Live serialization, and await cancellation-safe shared asynchronous transport cleanup. Add deterministic regressions for all three findings while preserving existing close-error behavior. Verified 580 focused unit cases and type/lint/build checks. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Extend the existing audio sample with optional PyAudio microphone capture and speaker playback, preserving WAV mode. Bound device buffering, surface callback/send errors, report actual audio bytes, and gracefully close the session on Ctrl+C. Add 24 microphone guards and related documentation. Verified 162 focused tests, both CLI modes against the live service, and user-confirmed physical microphone operation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Cover all nine dedicated Live REST methods in sync and async Test Proxy lifecycles, including pagination, audio content, HTTP statuses, deletion and safe fixture cleanup. Reference the published recording assets and add offline playback regressions. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Synchronize with TypeSpec e30cf6f0dcfbca167edf731d4e48874a63639e8b. Adapt consumer model references and sample fixtures, verify managed ownership through both public Live clients, refresh paired API reports, and document the effective Foundry delegation owner. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…e/azure-sdk-for-python into xitzhang/gpt-live-websocket
Howie Leung (howieleung)
requested changes
Oct 26, 2026
…e/azure-sdk-for-python into xitzhang/gpt-live-websocket
…e/azure-sdk-for-python into xitzhang/gpt-live-websocket
Consolidate Live samples, remove CLI arguments, use user-temporary audio output, and cover resource ownership and sample conventions. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
niuzheng168
pushed a commit
to niuzheng168/voice-agent
that referenced
this pull request
Oct 27, 2026
Rebuild the bundled azure-ai-projects 2.10.0 wheel from source on xitzhang/gpt-live-websocket (c69c028, Azure/azure-sdk-for-python#49631), which adds beta.voice_agents.live on top of the GPT Live models. The samples now open audio sessions with project.beta.voice_agents.live instead of the OpenAI Live SDK, so openai[realtime] is no longer a requirement; the wheel's [voice] extra brings aiohttp for the client. The SDK yields generated models for known Live events and dicts for the unmodeled session.managed_delegation.* events, so event handling uses mapping access for the type. Offline tests now route the SDK's wss:// Live handshake to a local WebSocket server. Co-Authored-By: Claude <noreply@anthropic.com>
niuzheng168
pushed a commit
to niuzheng168/voice-agent
that referenced
this pull request
Oct 27, 2026
Rebuild the bundled azure-ai-projects 2.10.0 wheel from source on xitzhang/gpt-live-websocket (c69c028, Azure/azure-sdk-for-python#49631), which adds beta.voice_agents.live on top of the GPT Live models. The samples now open audio sessions with project.beta.voice_agents.live instead of the OpenAI Live SDK, so openai[realtime] is no longer a requirement; the wheel's [voice] extra brings aiohttp for the client. The SDK yields generated models for known Live events and dicts for the unmodeled session.managed_delegation.* events, so event handling uses mapping access for the type. Offline tests now route the SDK's wss:// Live handshake to a local WebSocket server. Co-Authored-By: Claude <noreply@anthropic.com>
niuzheng168
pushed a commit
to niuzheng168/voice-agent
that referenced
this pull request
Oct 27, 2026
Rebuild the bundled azure-ai-projects 2.10.0 wheel from source on xitzhang/gpt-live-websocket (c69c028, Azure/azure-sdk-for-python#49631), which adds beta.voice_agents.live on top of the GPT Live models. The samples now open audio sessions with project.beta.voice_agents.live instead of the OpenAI Live SDK, so openai[realtime] is no longer a requirement; the wheel's [voice] extra brings aiohttp for the client. The SDK yields generated models for known Live events and dicts for the unmodeled session.managed_delegation.* events, so event handling uses mapping access for the type. Offline tests now route the SDK's wss:// Live handshake to a local WebSocket server.
Howie Leung (howieleung)
self-requested a review
October 27, 2026 20:43
Create and clean up a stored greeting conversation when no existing ID is supplied. Preserve read-only behavior for supplied IDs and remove source-shape and filename assertions per review while retaining behavioral coverage. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Reuse the existing REST fixture for success and failure cleanup checks. Remove the simulated greeting, clock, and persistence test setup without changing the sample. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
szhaomsft
pushed a commit
to microsoft/voice-agent
that referenced
this pull request
Oct 28, 2026
…S sample (#72) * Use the preview Projects SDK for GPT Live agent lifecycle The GPT Live samples now define agents with the azure-ai-projects VoiceAgentLiveDefinition and PromptAgentDefinition models and create, read back, and delete them through AIProjectClient.agents instead of raw httpx REST calls. Audio still uses the OpenAI Live SDK because the preview build has no Live WebSocket client. The GPT Live models are not on PyPI yet, so bundle the unmodified azure_ai_projects-2.10.0 wheel from azure-sdk build 6995855 (Azure/azure-sdk-for-python#49629) in dist/ and install it from the gpt_live requirements. dist/README.md records its source and SHA-256. Offline lifecycle tests now drive the real SDK client against an in-memory transport and also cover response_delegation.py. * Stream GPT Live audio with the Projects SDK Live client Rebuild the bundled azure-ai-projects 2.10.0 wheel from source on xitzhang/gpt-live-websocket (c69c028, Azure/azure-sdk-for-python#49631), which adds beta.voice_agents.live on top of the GPT Live models. The samples now open audio sessions with project.beta.voice_agents.live instead of the OpenAI Live SDK, so openai[realtime] is no longer a requirement; the wheel's [voice] extra brings aiohttp for the client. The SDK yields generated models for known Live events and dicts for the unmodeled session.managed_delegation.* events, so event handling uses mapping access for the type. Offline tests now route the SDK's wss:// Live handshake to a local WebSocket server. * Drop session.managed_delegation.* handling from GPT Live samples The service no longer emits session.managed_delegation.* events. For foundry_managed_agent delegation it sends session.delegation.created, the prompt agent's Responses stream as response.event with that delegation ID, and session.commentary/thinking.appended when Foundry forwards an accepted section to GPT Live. The Delegation pane now shows managed backend status and raw tagged-text output from response.event, and marks the latest delegation when Foundry acknowledges forwarding. Managed backend failures stay visible without ending the session. ManagedToolHandler no longer waits for the removed completion events. * Add JavaScript GPT Live samples with the preview Projects SDK Add samples/gpt_live_js: Node.js versions of the GPT Live Responses and managed prompt-agent delegation samples. Agents are created, read back, and deleted with AIProjectClient.agents, and audio streams through project.beta.voiceAgents.live. Node has no built-in audio devices, so the samples stream a recorded PCM16/24 kHz WAV question in real time and can save the spoken reply. The JS SDK's GPT Live client is not released and its pull request has no CI build, so bundle a local Node ESM build of @azure/ai-projects 2.10.0 from Azure/azure-sdk-for-js#40419 (4201af1) in dist/, recorded in dist/README.md. Managed delegation follows the current service: session.delegation.created, response.event lifecycle, and session.commentary.appended, with no session.managed_delegation.*. Offline node:test tests drive the real SDK client with an in-memory HTTP client and a scripted Live WebSocket transport. * Split GPT Live samples into python/ and a browser js/ sample Move the Python GPT Live samples into samples/gpt_live/python and keep a shared samples/gpt_live/.env for both languages; update the downloader path, the realtime_stt audio import, and the READMEs. Replace the WAV-based JavaScript CLI samples with samples/gpt_live/js, a simple browser sample with microphone input. A Node.js server creates or reuses the agents with the preview @azure/ai-projects package (Responses delegation by default, --managed for a pinned prompt agent), serves the page, and relays each page's microphone audio to a GPT Live session through project.beta.voiceAgents.live. The page captures 24 kHz PCM16 with an AudioWorklet, plays the teacher's audio, and shows GPT Live, Delegation, and You panes. The credential stays on the server, which listens on 127.0.0.1 and accepts Live connections only from its page. Offline node:test tests cover agent setup, the relay, and the HTTP surface with the real SDK client. * Add a Voice Agent structured-input sample Add samples/voice_agent_with_structured_input.py with its guide and an example input file: declare structured inputs with StructuredInputDefinition, reference them in the saved instructions with Handlebars placeholders, and pass per-session values through the Projects SDK's structured_inputs argument (or the x-ms-voice-structured-inputs header for deployments that reject the query parameter). Offline tests in tests/test_structured_input.py use the real SDK client. * Add MCP and local function tools to the browser sample's managed mode npm run managed now mirrors prompt_agent_delegation_tools.py: the prompt agent gets the public MCP calculator (add only) and a local get_current_datetime function, and the GPT Live agent is told to delegate addition and date/time questions. The server collects completed function calls from response.event, waits for response.completed, sends each function_call_output with response.item.create, then one response.create to resume the managed delegation. This preview JS SDK refuses response.item.create and response.create unless the session uses Responses delegation, and doesn't export its Node transport. live_transport.mjs therefore opens each session with VoiceAgentLiveClient over a small ws transport passed through the public webSocketFactory option, and sends those two commands on it directly; everything else still goes through the SDK. Verified live on voice-live-tip: the MCP calculator answered 17 + 25, and the local function's time (with its IANA timezone) was spoken back. * Connect the browser sample to GPT Live directly instead of relaying The page now opens the agent's Live WebSocket itself with the SDK's VoiceAgentLiveClient, bundled for the browser with esbuild. The local server no longer relays audio or Live events: it creates the agents, serves the page, and returns an access token from az login on POST /token, only to its own page (Host and Origin checks). Browsers cannot set handshake headers, so the page's transport offers the "live" and "authorization.bearer.<token>" subprotocols, which Foundry promotes to an Authorization header and answers with "live", and uses api-version=2025-11-15-preview in place of the Foundry-Features header. The managed tools' local date/time function now runs in the page and still returns its results with response.item.create and response.create on the same socket. --------- Co-authored-by: Zheng Niu <zhn@microsoft.com>
Clarify Realtime and GPT Live setup, sample choices, and client descriptions without changing runtime behavior, public APIs, generated code, or tests. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…o xitzhang/gpt-live-websocket
…/gpt-live-websocket
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Summary
Second PR in the GPT Live stack. Depends on #49629; merge #49629 first.
This PR targets
xitzhang/gpt-live-generatedso its diff contains only handwritten WebSocket support and associated samples, tests, API reports, and documentation. The parent PR supplies the TypeSpec emission and required tooling pin. This custom-code PR owns model-readback compatibility.Handwritten support
beta.voice_agents.livealongside the existing Realtime client, with synchronous and asynchronous clients and matching context-manager behavior._live.py,_live_utils.py, andaio/_live.py.session.started, do not send anothersession.start, and do not negotiate the Realtime subprotocol. Live does not invent aresponse.cancelcommand.Samples and tests
call_idfrom completeresponse.output_item.doneitems.There are no generated SDK source, TypeSpec pin, or dependency changes in this PR. The handwritten voice-definition readback compatibility hook belongs to this custom-code PR. No runtime dependencies or audio-device tooling are added.
Original implementation validation (before metadata regeneration)
--noconftestto avoid unrelated recorded-test proxy bootstrap in the sparse validation checkout.Historical service E2E (before this metadata regeneration)
The runtime and sample source bytes match the implementation exercised against the real configured Foundry project earlier in this session:
gpt-live-1deployment in client-delegation mode. Text/tool examples additionally used an existinggpt-4.1Responses backend; a second model is optional architecture, not a general Live requirement.Known boundaries
last_id/has_morepaging limitation.Stack maintenance
Keep this PR based on
xitzhang/gpt-live-generatedwhile #49629 is open. After #49629 merges, retarget/rebase onto the updatedfeature/azure-ai-projects/vnextas needed and verify the diff before merging.Metadata regeneration update - 2026-10-23
Merged the updated emitted branch from #49629 normally (no rebase/force push), using
Azure/azure-rest-api-specs#47196 at
e30cf6f0dcfbca167edf731d4e48874a63639e8b.Consumer updates
snapshots and delegation creation, including the pinned agent version and exact wire preservation.
model-conversion patch or public WebSocket signature change was needed.
they are not duplicated in this PR's diff against its parent branch.
Current validation
This includes Live/Realtime clients, shared transport, 10 generated-model regressions,
sample/recording-helper guards, and both recorded REST tests.
python/ai/azure-ai-projects_6289cbf17e; no recording or asset-pointer update was needed.connections while verifying the same recorded HTTP/audio responses.
No new live-service sample run was performed for this metadata-only regeneration; the historical
E2E results above are not being presented as new service validation of this refresh.
This PR keeps its existing ready/non-draft state and its
xitzhang/gpt-live-generatedtarget.Handwritten customization relocation - 2026-10-26
The parent emitted PR #49629 has removed the non-emitted
_deserialize_voicehook in commite8fdf78f48e082d235585999daa305407e4ba53d. This custom-code branch retains the same hook in the existingmodels/_patch.py, plus its six enabled readback regression cases and bug-fix changelog entry.The local branch has synced the updated emitted parent using a pending, non-committing merge and retained the customization byte-for-byte. Its source contents are unchanged from the pre-relocation combined SDK; the changed parent makes the customization a child-only diff. This local WebSocket sync has not been committed or pushed, so its publication is still awaiting explicit user approval. The existing remote head remains
069241f86859c5f7e562f0e0835cdab0869a1527.Validation: 679 tests passed, including the six retained readback cases and both published REST playback tests; SDK/all-samples Pyright 0 errors/warnings, SDK Mypy Python 3.10 passed, Pylint 10/10, Black passed. Generated/public API artifacts and runtime dependencies are unchanged by the relocation. No live-service execution or recording update was needed.