Skip to content

Add Voice Agents to Foundry Python SDK - #48939

Closed
xitzhang (xitzhang) wants to merge 79 commits into
mainfrom
xitzhang/voice-agent-pupr-ready
Closed

Add Voice Agents to Foundry Python SDK#48939
xitzhang (xitzhang) wants to merge 79 commits into
mainfrom
xitzhang/voice-agent-pupr-ready

Conversation

@xitzhang

@xitzhang xitzhang (xitzhang) commented Sep 9, 2026

Copy link
Copy Markdown
Member

Description

Adds Voice Agents to the Foundry Python SDK: a new agent kind for real-time, speech-to-speech conversational AI unified with the rest of the Agents API. Define a voice agent's model, audio, turn detection, greeting, and tools; manage it like any other agent; hold a live conversation with it over a WebSocket with barge-in and persisted conversation history/audio; and reach it through telephony (inbound bindings or outbound calls/campaigns).

This SDK is regenerated based on the following API spec changes:

Spec: foundrysdk_specs/specs/agents/voice_agents/spec.md
TypeSpec: Unify voice agents with the Agents API and add the v1 voice data plane · Azure/azure-rest-api-specs@9759481
Add Foundry Voice Agent batch 2 APIs by yulin-li · Pull Request #45852 · Azure/azure-rest-api-specs
Auto-generated (from TypeSpec)
The voice agent surface itself: VoiceAgentDefinition and its audio/turn-detection/greeting/tool/avatar config models, managed through the existing project_client.agents CRUD/versioning methods.
New agent_endpoint_conversations operation group to read back persisted transcripts and audio.
New agent_telephony operation group for outbound call jobs and campaigns, plus telephony bindings/call management on project_client.agents.
WebRTC transport, sub-agent consultation, and conversation-engine delegation on VoiceAgentDefinition.
Hand-written
A new client.realtime / async_client.realtime WebSocket client (not TypeSpec-generated, modeled after the OpenAI Python realtime client's ergonomics) for sending/receiving strongly-typed realtime events.
11 new samples under samples/agents/voice/ covering lifecycle, live audio/text conversation, function tools, versioning, and conversation read-back.
New unit (mocked) and live/recorded test coverage for the realtime client, voice agent CRUD/conversations/telephony.
CHANGELOG, README, and optional websockets/aiohttp dependency updates.

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.

Xiting Zhang and others added 30 commits August 6, 2026 14:03
Co-authored-by: xitzhang <11403681+xitzhang@users.noreply.github.com>
Co-authored-by: xitzhang <11403681+xitzhang@users.noreply.github.com>
Co-authored-by: xitzhang <11403681+xitzhang@users.noreply.github.com>
Co-authored-by: xitzhang <11403681+xitzhang@users.noreply.github.com>
…ient and samples, remove azure-ai-voiceagents

- Emit azure-ai-projects from TypeSpec at PR #45357 (unify voice agents with Agents API)
- Add hand-written async realtime WebSocket client (AIProjectClient.realtime), ported from azure-ai-voiceagents
- Add 9 new samples under samples/agents/voice/
- Update patch files, tests, README, and docs/public-methods.md for the new voice agent surface
- Remove sdk/voiceagents/azure-ai-voiceagents (superseded by unified azure-ai-projects voice agents)
- Revert VOICE_AGENTS_V1_PREVIEW from _AGENT_OPERATION_FEATURE_HEADERS (service not ready, breaks existing recordings)
- Fix mypy: undefined _unions self-reference, missing realtime/. AsyncRealtime* stubs in aio/_patch.pyi, add targeted overrides for known generated overload-widening signatures in patch_agents/patch_evaluation_rules
- Fix pylint: reimported AgentKind in types.py, self-import in _unions.py
- Fix voice/optimization sample type errors with targeted type: ignore comments
- Add pcma/pcmu to sdk/ai/cspell.yaml word list
Co-authored-by: xitzhang <11403681+xitzhang@users.noreply.github.com>
Co-authored-by: xitzhang <11403681+xitzhang@users.noreply.github.com>
…ec (PR 45357); add sync live-text-conversation sample
…e APIs

Co-authored-by: xitzhang <11403681+xitzhang@users.noreply.github.com>
- Work around aiohttp response-decompression bug on agents/agent_endpoint_conversations (async client)
- Fix pyright errors: self-referencing forward-refs in _unions.py, subprotocols typing in _realtime.py
- Fix Sphinx doc build failure (malformed RST in get_session_log_stream docstring)
- Remove non-functional generated voice_agent_web_socket operation group from public client surface
- Guard connection_url override against token exfiltration to untrusted hosts in realtime client
- Don't swallow BaseException (e.g. CancelledError) when wrapping realtime connection failures
- Add recorded tests for voice-agent CRUD (sync/async) and agent_endpoint_conversations header injection
- Update stale expected Foundry-Features header constants to include VoiceAgents=V1Preview
…ientEvent/ConversationItem/ServerEvent from _patch; sanitize Foundry-Features header in test recordings
Xiting Zhang and others added 3 commits September 8, 2026 15:52
…d sample playback

azure-storage-blob's generated client hardcodes Accept: application/xml for
blob uploads, but some CI environments have been observed sending Accept: */*
instead (a transport/dependency-version difference unrelated to any SDK code
here). The test-proxy's strict default matcher treats this single header
difference as a full playback miss even when the URL, method, query params,
and body all match exactly, intermittently failing
sample_models_create_and_poll, sample_datasets, sample_datasets_download, and
sample_models_basic_async - confirmed already flaky on main independent of
this branch (main build 6791141/6796410/6800289 failed with this exact
signature, 6790806/6800869 passed).

Add add_remove_header_sanitizer(headers="Accept") to tests/conftest.py,
following the same established pattern already used here for
Foundry-Features and Content-Encoding: strip a benign, non-tested header from
matching instead of exact-matching it. Verified by forcing an Accept: */*
mismatch locally (reproduces the exact CI failure without this fix, passes
with it), and reran the full suite (1489 passed, 123 skipped, 0 failed,
unchanged from before).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ephony tests

- _realtime.py / aio/_realtime.py: fix critical bug sending a literal
  placeholder Authorization header instead of a real Bearer token; URL-encode
  agent_name in the websocket URL.
- Remove dead VoiceAgentWebSocketOperations export from operations/__init__.py
  and aio/operations/__init__.py; extend PostEmitter.ps1 to strip it on future
  regeneration; regenerate api.md/api.metadata.yml accordingly.
- sample_voice_agent_live_text_conversation.py/_async.py: fix a bug where the
  agent's auto-greeting response raced with the reply to the user's first
  message, silently dropping the real answer; drain/display the greeting
  before the interactive loop.
- sample_voice_agent_live_audio_conversation_async.py: fix the same
  field-dropping bug by reusing the generated agent definition as-is instead
  of reconstructing a partial one.
- Add actual (not estimated) audio payload size tracking to all three
  streaming samples: byte counts, human-readable size, and format/sample
  rate/channels/duration are now printed for sent/received audio.
- Add mocked protocol-level tests for all 13 agent_telephony operations
  (call jobs + campaigns); live/recorded tests are not yet possible since the
  routes return 400 UnsupportedApiVersion on the current test resource.
- Update test_realtime_client.py/_async.py assertions for the auth fix.
- Move PSTN/pstn cspell entries from the repo-wide .vscode/cspell.json to the
  package-level sdk/ai/cspell.yaml, which can resolve them on its own.
- Correct FOUNDRY_VOICE_MODEL_NAME description in .env.template.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…e-release fix into Features Added, add Sample updates section

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).
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.

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.

🟡 Changes recommended

There are at least two concrete repo-impacting issues (a type-checking problem in a new sample and an incorrectly named tsp-location file) that should be corrected before approval.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR adds Voice Agents support to azure-ai-projects, introducing a new voice-agent kind integrated into the existing Agents API, plus realtime (WebSocket) client support, new operation groups for conversation readback and telephony, and accompanying samples/tests and test-resource provisioning updates.

Changes:

  • Adds voice-agent API surface (CRUD/versioning, conversation read-back, telephony) and updates feature-header behaviors for preview opt-in.
  • Introduces sync/async realtime streaming clients (client.realtime / async_client.realtime) with optional dependencies and extensive samples.
  • Adds new recorded/unit/live tests plus test resource provisioning assets for live realtime scenarios.
File summaries
File Description
sdk/ai/cspell.yaml Adds voice-agent related terms to spellcheck allowlist.
sdk/ai/azure-ai-projects/tsp-location.yaml.saved Tracks TypeSpec source location/commit for regeneration (but file naming needs attention).
sdk/ai/azure-ai-projects/tests/test_base.py Adds a sanitized env var placeholder for voice model deployment in tests.
sdk/ai/azure-ai-projects/tests/samples/test_samples.py Adds voice samples to sample test matrix with appropriate skips for WS/unrecordable flows.
sdk/ai/azure-ai-projects/tests/samples/test_samples_async.py Adds async voice samples to sample test matrix with WS-related skips.
sdk/ai/azure-ai-projects/tests/foundry_features_header/test_foundry_features_header_on_ga_operations.py Expands header override coverage to include different header casing variants.
sdk/ai/azure-ai-projects/tests/foundry_features_header/test_foundry_features_header_on_ga_operations_async.py Async counterpart for header override casing tests.
sdk/ai/azure-ai-projects/tests/foundry_features_header/test_agent_telephony_protocol.py Adds protocol-level request construction tests for telephony call-job/campaign routes.
sdk/ai/azure-ai-projects/tests/foundry_features_header/test_agent_telephony_protocol_async.py Async protocol tests for telephony request construction.
sdk/ai/azure-ai-projects/tests/foundry_features_header/foundry_features_header_test_base.py Updates expected Foundry-Features opt-ins and adds coverage for conversations/telephony groups.
sdk/ai/azure-ai-projects/tests/conftest.py Sanitizer changes to reduce cassette drift (header matching) for stable playback.
sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_telephony.py Adds recorded tests for agent telephony bindings/calls/transfer targets and generated-audio reads (currently skipped pending service support).
sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_telephony_campaign.py Adds recorded tests for outbound telephony call jobs/campaigns (currently skipped pending API-version enablement).
sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_telephony_campaign_async.py Async counterpart for outbound telephony call-job/campaign tests (currently skipped).
sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_realtime_live.py Adds live-only realtime WebSocket tests for sync client.
sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_realtime_live_async.py Adds live-only realtime WebSocket tests for async client.
sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_crud.py Adds recorded CRUD/versioning tests for voice agents via project_client.agents.
sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_crud_async.py Async CRUD/versioning tests for voice agents.
sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_conversations.py Adds recorded tests for conversation transcript/audio read-back with live-only setup for recording.
sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_conversations_async.py Async counterpart for conversation read-back tests.
sdk/ai/azure-ai-projects/tests.yml Adds a live-test pipeline configuration for voice-agent live tests in a supported region.
sdk/ai/azure-ai-projects/test-resources.bicep Adds Bicep template to provision Foundry resources required for voice-agent live tests.
sdk/ai/azure-ai-projects/test-resources-post.ps1 Adds post-deploy script to create the gpt-realtime deployment with retry/wait logic.
sdk/ai/azure-ai-projects/samples/hosted_agents/sample_session_log_stream.py Updates session log stream sample to explicitly request streaming.
sdk/ai/azure-ai-projects/samples/hosted_agents/sample_session_log_stream_async.py Async version of explicit streaming request update.
sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_with_tools.py Adds voice-agent definition sample showing audio config and tool configuration.
sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_versions.py Adds sample showing voice-agent versioning flows.
sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_read_conversation.py Adds sample showing conversation transcript readback via agent_endpoint_conversations.
sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_read_conversation_audio.py Adds sample showing conversation audio readback + file streaming.
sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_live_function_tool.py Adds sample showing function tool round-trip during a live realtime session.
sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_generate.py Adds sample for guided authoring via agents.generate_agent(kind="voice").
sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_basic.py Adds basic sync voice-agent lifecycle sample.
sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_basic_async.py Adds basic async voice-agent lifecycle sample.
sdk/ai/azure-ai-projects/samples/agents/sample_workflow_multi_agent_with_mcp_approval.py Adjusts typing ignores for workflow action item access.
sdk/ai/azure-ai-projects/samples/agents/sample_workflow_multi_agent_async.py Async counterpart typing-ignore adjustment.
sdk/ai/azure-ai-projects/README.md Adds voice agents (preview) to the operation group table and links to relevant docs.
sdk/ai/azure-ai-projects/pyproject.toml Bumps package to beta classifier and adds realtime optional dependencies.
sdk/ai/azure-ai-projects/docs/public-methods.md Updates public method inventory and includes new operation groups/methods.
sdk/ai/azure-ai-projects/dev_requirements.txt Adds websockets to development requirements.
sdk/ai/azure-ai-projects/CHANGELOG.md Adds a 2.7.0b1 entry describing voice agents, realtime, conversation readback, and telephony.
sdk/ai/azure-ai-projects/azure/ai/projects/operations/_patch.py Exports new operation group patch types.
sdk/ai/azure-ai-projects/azure/ai/projects/operations/_patch_evaluators.py Refactors typing aliases/imports and adds type ignores for overrides.
sdk/ai/azure-ai-projects/azure/ai/projects/operations/_patch_evaluation_rules.py Adds override typing ignores and tightens typing for super calls.
sdk/ai/azure-ai-projects/azure/ai/projects/operations/_patch_datasets.py Refactors typing alias import and adds typing ignores for overrides.
sdk/ai/azure-ai-projects/azure/ai/projects/operations/init.py Exposes new operation group classes from operations namespace.
sdk/ai/azure-ai-projects/azure/ai/projects/models/_patch.py Adds VoiceAgents preview opt-in to the agents header composition and documents client placement.
sdk/ai/azure-ai-projects/azure/ai/projects/aio/operations/_patch.py Exports async patch types for new operation group.
sdk/ai/azure-ai-projects/azure/ai/projects/aio/operations/_patch_evaluators_async.py Async typing alias refactor + override ignores.
sdk/ai/azure-ai-projects/azure/ai/projects/aio/operations/_patch_evaluation_rules_async.py Async override typing ignores and arg-type ignore for super call.
sdk/ai/azure-ai-projects/azure/ai/projects/aio/operations/_patch_datasets_async.py Async typing alias import + override ignores.
sdk/ai/azure-ai-projects/azure/ai/projects/aio/operations/init.py Exposes new async operation group classes.
sdk/ai/azure-ai-projects/azure/ai/projects/aio/_patch.pyi Exposes realtime types and realtime property in async client typing stubs.
sdk/ai/azure-ai-projects/azure/ai/projects/aio/_patch.py Adds async realtime property + opt-in header proxying and accept-encoding workaround.
sdk/ai/azure-ai-projects/azure/ai/projects/aio/_client.py Adds generated async operation group attributes for conversations and telephony.
sdk/ai/azure-ai-projects/azure/ai/projects/_version.py Bumps package version to 2.7.0b1.
sdk/ai/azure-ai-projects/azure/ai/projects/_utils/utils.py Adds ETag quoting and match-condition header preparation helpers.
sdk/ai/azure-ai-projects/azure/ai/projects/_unions.py Adds new voice-agent related union types/literals.
sdk/ai/azure-ai-projects/azure/ai/projects/_patch.pyi Exposes realtime types and realtime property in sync client typing stubs.
sdk/ai/azure-ai-projects/azure/ai/projects/_patch.py Adds sync realtime property + opt-in header proxying and exports realtime types.
sdk/ai/azure-ai-projects/azure/ai/projects/_client.py Adds generated operation group attributes for conversations and telephony.
sdk/ai/azure-ai-projects/assets.json Updates azure-sdk-assets tag reference.
sdk/ai/azure-ai-projects/api.metadata.yml Updates api.md hash and package version metadata for 2.7.0b1.
sdk/ai/azure-ai-projects/.env.template Adds environment variables for voice tests and voice samples.
scripts/devops_tasks/test_run_samples.py Excludes interactive/live-only voice samples from non-interactive sample runner.
eng/tools/azure-sdk-tools/azpysdk/samples.py Excludes interactive/live-only voice samples from azpysdk sample execution.
Review details
  • Files reviewed: 81/85 changed files
  • Comments generated: 2
  • Review effort level: Lite

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

Comment on lines 1 to 5
directory: specification/ai-foundry/data-plane/Foundry/src/sdk-python-js-azure-ai-projects
commit: 675e111febec298cdc8e640d9f8653cc287c5dd1
commit: b538ac90619e094630e3c773d5231070809caf48
repo: Azure/azure-rest-api-specs
additionalDirectories:
- specification/ai-foundry/data-plane/Foundry/src/agents
Xiting Zhang and others added 2 commits September 9, 2026 13:07
…pupr-ready

# Conflicts:
#	sdk/ai/azure-ai-projects/CHANGELOG.md
#	sdk/ai/azure-ai-projects/assets.json
#	sdk/ai/azure-ai-projects/azure/ai/projects/_version.py
…iceAgentEndConversationSystemTool, fix data-gen-jobs regression

- Regenerated from TypeSpec commit fcea6bee2d387de983f3ba6dea6c0df92a79b595.
- Added VoiceAgentEndConversationSystemTool, a dedicated system-tool subclass for
  ending a call; updated sample_voice_agent_with_tools.py to use it instead of the
  generic VoiceAgentSystemTool(name=...) construction, and added a CHANGELOG
  mention. Live-verified the full create/get/list round-trip.
- Fixed a regression introduced by this TypeSpec commit in an unrelated area:
  SimulationSeedDataGenerationJobOptions lost its max_samples field entirely
  (confirmed against the actual .tsp source), while its 3 sibling job-type
  classes correctly kept theirs -- this broke the existing, unrelated
  sample_synthetic_multiturn_evaluation.py sample/test. Restored max_samples
  client-side via models/_patch.py (using the SDK's own rest_field mechanism),
  preserving existing behavior without touching generated files directly.
- Fixed a non-idempotency bug in PostEmitter.ps1's get_session_log_stream fixup:
  its regex matched its own previously-applied output, so re-running the script
  (needed here due to a transient file lock) inserted a duplicate line. Narrowed
  the match to the raw generator output only and corrected the resulting
  duplicate in both _operations.py files, which now byte-match origin/main
  exactly for that function.
- Accepted unrelated, non-breaking additions that came along via the shared
  TypeSpec branch (BrowserAutomationTool/BrowserAutomationToolboxTool,
  DataGenerationJobOutputWriteMode, trace_ids filtering) without adding
  Voice-Agents-unrelated samples/changelog entries for them.
- Re-verified all 11 Voice Agents samples live end-to-end against
  voice-live-tip-resource: REST/CRUD status codes, realtime streaming events,
  function-tool invocation, and byte-accurate audio input/output size tracking.
- Full regression suite: 1516 passed, 123 skipped, 0 failed. pylint 10.00/10.
  mypy clean (only pre-existing, unrelated errors). black clean.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings September 10, 2026 00:25

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.

🔵 Needs a closer look

The change set introduces substantial new public surface area (realtime WebSocket client + new operation groups) and modifies testing/packaging/infrastructure, requiring careful human validation of API and test strategy decisions.

Review details
  • Files reviewed: 82/86 changed files
  • Comments generated: 5
  • Review effort level: Lite

Comment on lines +79 to +82
@pytest.mark.skip(
reason="Telephony routes are defined in the TypeSpec/SDK but not yet deployed on the live "
"test service (empty-body 404s at the routing layer). Un-skip once the service deploys them."
)
Comment on lines +67 to +70
return VoiceAgentDefinition(
model_type="managed",
model=model,
instructions="You are a helpful voice assistant.",
Comment on lines +66 to +70
@pytest.mark.skip(
reason="agent_telephony routes are registered but return 400 UnsupportedApiVersion for "
"api-version 'v1' on the live test service. Un-skip once the service supports 'v1' for "
"this operation group."
)
Comment on lines +66 to +70
@pytest.mark.skip(
reason="agent_telephony routes are registered but return 400 UnsupportedApiVersion for "
"api-version 'v1' on the live test service. Un-skip once the service supports 'v1' for "
"this operation group."
)
Comment on lines 19 to 20
# Can't include those, because they are not supported in Python 3.9. Samples that use these package
# cannot be run as pytest, because the pipeline will fail on Python 3.9 jobs.
@github-actions

Copy link
Copy Markdown
Contributor
[Pilot] PR Pipeline Failure Analysis

What failed

Build 6808203 (python - pullrequest) failed on all 6 platforms (Ubuntu2404_313, Ubuntu2404_314, macos311, ubuntu2404_310, ubuntu2404_310_coverage, windows2022_312) x both build variants (sdist, whl) for package azure-ai-projects, totaling 4,704 failed test cases. All failures trace back to three related root causes introduced with this PR's new test coverage, none of which are infrastructure/transient issues.

1) Test-proxy recording/playback failure (~9,168 of the underlying error events, the overwhelming majority of failures)

Every test that uses @recorded_by_proxy/@recorded_by_proxy_async fails identically at start_record_or_playback:

test_id = 'sdk/ai/azure-ai-projects/tests/recordings/agents/telemetry/test_ai_agents_instrumentor.pyTestAiAgentsInstrumentortest_agent_creation_with_tracing_content_recording_enabled'

    def start_record_or_playback(test_id: str) -> "Tuple[str, Dict[str, str]]":
        ...
        else:
            result = http_client.request(
                method="POST",
                url=PLAYBACK_START_URL,
                body=encoded_payload,
            )
            if result.status != 200:
>               raise HttpResponseError(message=result.data)
E               azure.core.exceptions.HttpResponseError: Operation returned an invalid status 'None'

.venv/.../devtools_testutils/proxy_testcase.py:117: HttpResponseError

This affects essentially every recorded test added/touched by this PR (agents telemetry instrumentor tests, responses instrumentor tests, voice agent tests, session/file CRUD tests, samples tests, etc.) on every platform - the test-proxy cannot find or match a valid recording for the test IDs, most likely because the recordings for these newly added/renamed tests are missing or assets.json wasn't updated/pushed to match.

2) AttributeError: 'LegacyAPIResponse' object has no attribute 'close' (96 occurrences)

In sdk/ai/azure-ai-projects/tests/agents/telemetry/test_responses_instrumentor_raw_response.py, several TestRawResponseStreaming tests call raw.close() on the object returned by client.responses.with_raw_response.create(...), e.g.:

tests/agents/telemetry/test_responses_instrumentor_raw_response.py:208
    raw = await client.responses.with_raw_response.create(model="gpt-4o", input="hi", stream=True)
    await raw.close()  # pyright: ignore[reportAttributeAccessIssue]
E   AttributeError: 'LegacyAPIResponse' object has no attribute 'close'

The OpenAI SDK's LegacyAPIResponse object doesn't expose a close() method - this is a test bug (wrong API usage) in the newly written raw-response streaming tests, not an infrastructure issue. Affects test_async_with_raw_response_close_finalizes_unconsumed_stream, test_async_with_raw_response_close_finalizes_partially_consumed_stream, and their sync counterparts.

3) Missing telemetry spans for raw-response streaming (144 occurrences)

Same test file, related tests assert spans were recorded but get zero:

tests/agents/telemetry/test_responses_instrumentor_raw_response.py:168
    spans = self.exporter.get_spans()
>   assert len(spans) >= 1, f"Expected at least 1 span, got {len(spans)}"
E   AssertionError: Expected at least 1 span, got 0

This cascades from the same raw-response close/parse handling issue in #2 - the instrumentation isn't finalizing/emitting a span for the raw-response streaming path being exercised by these new tests.

Relevant pipeline output
azure.core.exceptions.HttpResponseError: Operation returned an invalid status 'None'
  at devtools_testutils/proxy_testcase.py:117 (start_record_or_playback -> PLAYBACK_START_URL)

AttributeError: 'LegacyAPIResponse' object has no attribute 'close'
  at tests/agents/telemetry/test_responses_instrumentor_raw_response.py:208

AssertionError: Expected at least 1 span, got 0
  at tests/agents/telemetry/test_responses_instrumentor_raw_response.py:168

Recommended next steps

  • Re-record test-proxy recordings for the new/changed tests in azure-ai-projects (agents telemetry, voice agent, session/file, samples, foundry_features_header) and confirm sdk/ai/azure-ai-projects/assets.json is updated/pushed to point at those recordings. This workflow does not have Azure DevOps/test-proxy recording credentials, so re-recording must be done by the author.
  • Fix sdk/ai/azure-ai-projects/tests/agents/telemetry/test_responses_instrumentor_raw_response.py - replace the invalid raw.close() calls (lines ~208, ~226 and sync equivalents) with the correct OpenAI LegacyAPIResponse API (e.g., closing the underlying .response/httpx stream) so raw-response close/finalize and the associated span-emission tests pass.
  • See https://aka.ms/ci-fix

Copilot detected the failing pipeline and generated the analysis above. To have it attempt a
fix automatically, reply with @copilot please fix the failing pipeline on this PR.

Generated by Pipeline Analysis Next Steps · auto · 316.3 AIC · ⌖ 2.11 AIC · ⊞ 9.2K ·

@howieleung

Copy link
Copy Markdown
Member

Found this PR difficult to review since it has many changes for unrelated.
I am trying to merge this PR with the latest emitted from feature/foundry-release
Then you can target to your PR to feature/azure-ai-projects/vnext, so you get a clean PR.
I also need to understand better about realtime

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants