From 67426daf5c11da90f082e81c19269a8c3cd5e325 Mon Sep 17 00:00:00 2001 From: xitzhang Date: Tue, 14 Jul 2026 13:17:01 -0700 Subject: [PATCH 1/6] [VoiceLive] Update for API version 2026-07-15 (#49771) * [VoiceLive] Update default API version to 2026-07-15 for 1.1.0 GA - Add VoiceLiveServiceVersion.V2026_07_15 and make it the default (getLatest); keep V2026_04_10 available - Regenerate against 2026-07-15 GA TypeSpec (drops preview-only WebRTC SDP, output audio buffer lifecycle, smart end-of-turn detection) - Remove orphaned unit tests for dropped types; trim AvatarAndAudioBufferEventsTest - Bump version to 1.1.0 (GA); update CHANGELOG, samples, and live/unit tests * [VoiceLive] Update default API version to 2026-07-15 for 1.1.0 GA - Add VoiceLiveServiceVersion.V2026_07_15 and make it the default (getLatest); keep V2026_04_10 available - Regenerate against 2026-07-15 GA TypeSpec (drops preview-only WebRTC SDP, output audio buffer lifecycle, smart end-of-turn detection) - Remove orphaned unit tests for dropped types; trim AvatarAndAudioBufferEventsTest - Bump version to 1.1.0 (GA); update CHANGELOG, samples, and live/unit tests * Replace expired gpt-4o-realtime-preview model in tests/docs and reframe removed-preview note in CHANGELOG * Replace expired gpt-4o-realtime-preview model in tests/docs and reframe removed-preview note in CHANGELOG * Fix duplicated lines in voicelive unit tests from merge conflict * Session expiration API returns OffsetDateTime; add test coverage Regenerate VoiceLiveSessionResponse so getExpiresAt/setExpiresAt use OffsetDateTime (wire format remains epoch seconds). Fix CHANGELOG signature note and add VoiceLiveSessionExpirationTest covering getter/setter, null handling, and JSON round-trip. * update to main branch typespec commit --------- Co-authored-by: Xiting Zhang --- eng/versioning/version_client.txt | 2 +- sdk/voicelive/azure-ai-voicelive/CHANGELOG.md | 17 +- sdk/voicelive/azure-ai-voicelive/README.md | 6 +- sdk/voicelive/azure-ai-voicelive/pom.xml | 2 +- .../ai/voicelive/VoiceLiveServiceVersion.java | 9 +- .../models/ClientEventRtcCallSdpCreate.java | 155 ------------------ .../ai/voicelive/models/ClientEventType.java | 6 - .../ai/voicelive/models/EouDetection.java | 2 - .../voicelive/models/EouDetectionModel.java | 6 - .../models/ResponseCreateParams.java | 6 +- .../voicelive/models/RtcCallErrorDetails.java | 126 -------------- .../ServerEventOutputAudioBufferStarted.java | 102 ------------ .../ServerEventOutputAudioBufferStopped.java | 102 ------------ .../models/ServerEventRtcCallError.java | 151 ----------------- .../models/ServerEventRtcCallSdpCreated.java | 132 --------------- .../ai/voicelive/models/ServerEventType.java | 24 --- .../voicelive/models/SessionClientEvent.java | 2 - .../voicelive/models/SessionServerEvent.java | 8 - .../models/SmartEndOfTurnDetection.java | 144 ---------------- .../models/VoiceLiveSessionResponse.java | 43 +++++ .../META-INF/azure-ai-voicelive_metadata.json | 2 +- .../com/azure/ai/voicelive/AgentV2Sample.java | 2 +- .../com/azure/ai/voicelive/McpSample.java | 2 +- .../implementation/VoiceLiveTracerTest.java | 6 +- .../ai/voicelive/live/VoiceLiveTestBase.java | 2 +- .../live/VoiceLiveToolCallTests.java | 8 +- .../live/VoiceLiveTranscriptionTests.java | 4 +- .../live/VoiceLiveTurnDetectionTests.java | 6 +- .../VoiceLiveAsyncClientStartSessionTest.java | 12 +- .../unit/VoiceLiveClientBuilderTest.java | 6 +- .../VoiceLiveRequestOptionsClientTest.java | 8 +- .../unit/VoiceLiveSessionOptionsTest.java | 2 +- .../AvatarAndAudioBufferEventsTest.java | 33 ---- .../unit/models/RtcCallSdpEventsTest.java | 97 ----------- .../models/SmartEndOfTurnDetectionTest.java | 45 ----- .../TranscriptionAndIncludeOptionsTest.java | 2 +- .../VoiceLiveSessionExpirationTest.java | 82 +++++++++ ...oiceLiveSessionOptionsNewFeaturesTest.java | 14 +- .../azure-ai-voicelive/tsp-location.yaml | 2 +- 39 files changed, 193 insertions(+), 1187 deletions(-) delete mode 100644 sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/ClientEventRtcCallSdpCreate.java delete mode 100644 sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/RtcCallErrorDetails.java delete mode 100644 sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/ServerEventOutputAudioBufferStarted.java delete mode 100644 sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/ServerEventOutputAudioBufferStopped.java delete mode 100644 sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/ServerEventRtcCallError.java delete mode 100644 sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/ServerEventRtcCallSdpCreated.java delete mode 100644 sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/SmartEndOfTurnDetection.java delete mode 100644 sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/unit/models/RtcCallSdpEventsTest.java delete mode 100644 sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/unit/models/SmartEndOfTurnDetectionTest.java create mode 100644 sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/unit/models/VoiceLiveSessionExpirationTest.java diff --git a/eng/versioning/version_client.txt b/eng/versioning/version_client.txt index ef8044d9205e..92c2c7e2139a 100644 --- a/eng/versioning/version_client.txt +++ b/eng/versioning/version_client.txt @@ -60,7 +60,7 @@ com.azure:azure-ai-textanalytics-perf;1.0.0-beta.1;1.0.0-beta.1 com.azure:azure-ai-translation-text;2.0.0;2.1.0-beta.1 com.azure:azure-ai-translation-document;1.0.8;1.1.0-beta.1 com.azure:azure-ai-vision-face;1.0.0-beta.2;1.0.0-beta.3 -com.azure:azure-ai-voicelive;1.0.0;1.1.0-beta.2 +com.azure:azure-ai-voicelive;1.0.0;1.1.0 com.azure:azure-analytics-defender-easm;1.0.0-beta.1;1.0.0-beta.2 com.azure:azure-analytics-purview-datamap;1.0.0-beta.2;1.0.0-beta.3 com.azure:azure-analytics-onlineexperimentation;1.0.0-beta.1;1.0.0-beta.2 diff --git a/sdk/voicelive/azure-ai-voicelive/CHANGELOG.md b/sdk/voicelive/azure-ai-voicelive/CHANGELOG.md index 4acd9b064942..e89aa581480c 100644 --- a/sdk/voicelive/azure-ai-voicelive/CHANGELOG.md +++ b/sdk/voicelive/azure-ai-voicelive/CHANGELOG.md @@ -1,15 +1,28 @@ # Release History -## 1.1.0-beta.2 (Unreleased) +## 1.1.0 (Unreleased) ### Features Added -### Breaking Changes +- **Streaming input text** into a conversation item: + - New `ClientEventInputTextDelta` (`input_text.delta`) and `ClientEventInputTextDone` (`input_text.done`), each with optional `contentIndex` + - New `ClientEventType.INPUT_TEXT_DELTA` and `ClientEventType.INPUT_TEXT_DONE` values +- **Echo cancellation reference source**: `AudioEchoCancellation` is now `@Fluent` and exposes `referenceSource` (new `EchoCancellationReferenceSource` enum with `SERVER` / `CLIENT`) and `channels` for stereo input where channel 1 is the client-supplied echo reference +- **Azure realtime native voices**: new `AzureRealtimeNativeVoice` (type `azure-realtime-native`) and `AzureRealtimeNativeVoiceName` expandable enum (`AARTI`, `ANDREW`, `AVA`, `DENISE`, `DIYA`, `ELSA`, `FLORIAN`, `FRANCISCA`, `MEERA`, `XIAOXIAO`, `YUNXI`, `XIMENA`) for use with the `azure-realtime` model +- **Parallel tool calls**: `VoiceLiveSessionOptions.setParallelToolCalls(Boolean)` / `isParallelToolCalls()` (and matching accessors on `VoiceLiveSessionResponse`) to control whether the model may invoke tools in parallel +- **Hosted agent invocation passthrough**: + - `ResponseCreateParams.setInvokeInput(Map)` / `getInvokeInput()` to attach input data for a hosted agent invocation on a single response request + - New `ServerEventResponseInvocationDelta` (`response.invocation.delta`) and `ServerEventType.RESPONSE_INVOCATION_DELTA` pass through non-speech SSE events from the hosted agent +- **Session expiration**: `VoiceLiveSessionResponse.getExpiresAt()` / `setExpiresAt(OffsetDateTime)` expose the server-assigned session expiration time (serialized on the wire as seconds since epoch) ### Bugs Fixed ### Other Changes +- Regenerated against the `2026-07-15` (GA) VoiceLive TypeSpec. +- Added service API version `V2026_07_15` and made it the default used by `VoiceLiveClientBuilder`. `VoiceLiveServiceVersion.getLatest()` now returns `V2026_07_15`. The previous default `V2026_04_10` remains available for callers that pin to it. +- The following APIs introduced in `1.1.0-beta.1` are not part of this GA release: WebRTC SDP negotiation (`ClientEventRtcCallSdpCreate`, `ServerEventRtcCallSdpCreated`, `ServerEventRtcCallError`, `RtcCallErrorDetails`, and the `rtc.call.*` event-type values), output audio buffer playback lifecycle events (`ServerEventOutputAudioBufferStarted`, `ServerEventOutputAudioBufferStopped`, and the `output_audio_buffer.started` / `output_audio_buffer.stopped` `ServerEventType` values), and smart audio-based end-of-turn detection (`SmartEndOfTurnDetection` and the `EouDetectionModel.SMART_END_OF_TURN_DETECTION` value). + ## 1.1.0-beta.1 (2026-06-02) ### Features Added diff --git a/sdk/voicelive/azure-ai-voicelive/README.md b/sdk/voicelive/azure-ai-voicelive/README.md index 97d440ad9504..3d437fc19075 100644 --- a/sdk/voicelive/azure-ai-voicelive/README.md +++ b/sdk/voicelive/azure-ai-voicelive/README.md @@ -100,7 +100,7 @@ Represents an active WebSocket connection for bidirectional streaming communicat ### VoiceLiveSessionOptions Configuration options for customizing session behavior: -- **Model selection**: Specify the AI model (e.g., "gpt-4o-realtime-preview") +- **Model selection**: Specify the AI model (e.g., "gpt-realtime") - **Voice settings**: Choose from OpenAI voices (Alloy, Ash, Ballad, Coral, Echo, Sage, Shimmer, Verse) or Azure voices - **Modalities**: Configure text and/or audio interaction modes - **Turn detection**: Server-side voice activity detection with configurable thresholds @@ -525,7 +525,7 @@ OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=true When tracing is active, the following span hierarchy is emitted for each voice session: ``` -connect gpt-4o-realtime-preview ← session lifetime span +connect gpt-realtime ← session lifetime span ├── send session.update ← one span per sent event ├── send input_audio_buffer.append ├── send response.create @@ -607,7 +607,7 @@ VoiceLiveSessionOptions sessionOptions = new VoiceLiveSessionOptions() .setTurnDetection(turnDetection); // Start session (null VoiceLiveRequestOptions), then handle events -client.startSession("gpt-4o-realtime-preview", null) +client.startSession("gpt-realtime", null) .flatMap(session -> { // Subscribe to receive server events session.receiveEvents() diff --git a/sdk/voicelive/azure-ai-voicelive/pom.xml b/sdk/voicelive/azure-ai-voicelive/pom.xml index 69983a05d4c3..e902414e4a32 100644 --- a/sdk/voicelive/azure-ai-voicelive/pom.xml +++ b/sdk/voicelive/azure-ai-voicelive/pom.xml @@ -14,7 +14,7 @@ Code generated by Microsoft (R) TypeSpec Code Generator. com.azure azure-ai-voicelive - 1.1.0-beta.2 + 1.1.0 jar Microsoft Azure SDK for VoiceLive diff --git a/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/VoiceLiveServiceVersion.java b/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/VoiceLiveServiceVersion.java index 2dcaa3476257..fd41d3e0066c 100644 --- a/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/VoiceLiveServiceVersion.java +++ b/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/VoiceLiveServiceVersion.java @@ -17,7 +17,12 @@ public enum VoiceLiveServiceVersion implements ServiceVersion { /** * Service version {@code 2026-04-10}. */ - V2026_04_10("2026-04-10"); + V2026_04_10("2026-04-10"), + + /** + * Service version {@code 2026-07-15}. + */ + V2026_07_15("2026-07-15"); private final String version; @@ -39,6 +44,6 @@ public String getVersion() { * @return The latest {@link VoiceLiveServiceVersion}. */ public static VoiceLiveServiceVersion getLatest() { - return V2026_04_10; + return V2026_07_15; } } diff --git a/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/ClientEventRtcCallSdpCreate.java b/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/ClientEventRtcCallSdpCreate.java deleted file mode 100644 index 17cf82727a93..000000000000 --- a/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/ClientEventRtcCallSdpCreate.java +++ /dev/null @@ -1,155 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// Code generated by Microsoft (R) TypeSpec Code Generator. -package com.azure.ai.voicelive.models; - -import com.azure.core.annotation.Fluent; -import com.azure.core.annotation.Generated; -import com.azure.json.JsonReader; -import com.azure.json.JsonToken; -import com.azure.json.JsonWriter; -import java.io.IOException; - -/** - * Sent by the client to initiate a WebRTC session with an SDP offer. - */ -@Fluent -public final class ClientEventRtcCallSdpCreate extends SessionClientEvent { - - /* - * The type of event. - */ - @Generated - private ClientEventType type = ClientEventType.RTC_CALL_SDP_CREATE; - - /* - * The SDP offer from the client for WebRTC negotiation. - */ - @Generated - private final String sdpOffer; - - /* - * Optional initial session configuration. If provided, applied before the session is established. - */ - @Generated - private VoiceLiveSessionOptions session; - - /** - * Creates an instance of ClientEventRtcCallSdpCreate class. - * - * @param sdpOffer the sdpOffer value to set. - */ - @Generated - public ClientEventRtcCallSdpCreate(String sdpOffer) { - this.sdpOffer = sdpOffer; - } - - /** - * Get the type property: The type of event. - * - * @return the type value. - */ - @Generated - @Override - public ClientEventType getType() { - return this.type; - } - - /** - * Get the sdpOffer property: The SDP offer from the client for WebRTC negotiation. - * - * @return the sdpOffer value. - */ - @Generated - public String getSdpOffer() { - return this.sdpOffer; - } - - /** - * Get the session property: Optional initial session configuration. If provided, applied before the session is - * established. - * - * @return the session value. - */ - @Generated - public VoiceLiveSessionOptions getSession() { - return this.session; - } - - /** - * Set the session property: Optional initial session configuration. If provided, applied before the session is - * established. - * - * @param session the session value to set. - * @return the ClientEventRtcCallSdpCreate object itself. - */ - @Generated - public ClientEventRtcCallSdpCreate setSession(VoiceLiveSessionOptions session) { - this.session = session; - return this; - } - - /** - * {@inheritDoc} - */ - @Generated - @Override - public ClientEventRtcCallSdpCreate setEventId(String eventId) { - super.setEventId(eventId); - return this; - } - - /** - * {@inheritDoc} - */ - @Generated - @Override - public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { - jsonWriter.writeStartObject(); - jsonWriter.writeStringField("event_id", getEventId()); - jsonWriter.writeStringField("sdp_offer", this.sdpOffer); - jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); - jsonWriter.writeJsonField("session", this.session); - return jsonWriter.writeEndObject(); - } - - /** - * Reads an instance of ClientEventRtcCallSdpCreate from the JsonReader. - * - * @param jsonReader The JsonReader being read. - * @return An instance of ClientEventRtcCallSdpCreate if the JsonReader was pointing to an instance of it, or null - * if it was pointing to JSON null. - * @throws IllegalStateException If the deserialized JSON object was missing any required properties. - * @throws IOException If an error occurs while reading the ClientEventRtcCallSdpCreate. - */ - @Generated - public static ClientEventRtcCallSdpCreate fromJson(JsonReader jsonReader) throws IOException { - return jsonReader.readObject(reader -> { - String eventId = null; - String sdpOffer = null; - ClientEventType type = ClientEventType.RTC_CALL_SDP_CREATE; - VoiceLiveSessionOptions session = null; - while (reader.nextToken() != JsonToken.END_OBJECT) { - String fieldName = reader.getFieldName(); - reader.nextToken(); - if ("event_id".equals(fieldName)) { - eventId = reader.getString(); - } else if ("sdp_offer".equals(fieldName)) { - sdpOffer = reader.getString(); - } else if ("type".equals(fieldName)) { - type = ClientEventType.fromString(reader.getString()); - } else if ("session".equals(fieldName)) { - session = VoiceLiveSessionOptions.fromJson(reader); - } else { - reader.skipChildren(); - } - } - ClientEventRtcCallSdpCreate deserializedClientEventRtcCallSdpCreate - = new ClientEventRtcCallSdpCreate(sdpOffer); - deserializedClientEventRtcCallSdpCreate.setEventId(eventId); - deserializedClientEventRtcCallSdpCreate.type = type; - deserializedClientEventRtcCallSdpCreate.session = session; - return deserializedClientEventRtcCallSdpCreate; - }); - } -} diff --git a/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/ClientEventType.java b/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/ClientEventType.java index 541917015ae1..93ae8f521044 100644 --- a/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/ClientEventType.java +++ b/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/ClientEventType.java @@ -151,12 +151,6 @@ public static Collection values() { @Generated public static final ClientEventType OUTPUT_AUDIO_BUFFER_CLEAR = fromString("output_audio_buffer.clear"); - /** - * Sent by the client to initiate a WebRTC session with an SDP offer. - */ - @Generated - public static final ClientEventType RTC_CALL_SDP_CREATE = fromString("rtc.call.sdp.create"); - /** * Streamed delta of input text content being appended to an item. */ diff --git a/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/EouDetection.java b/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/EouDetection.java index f1f2ab1664ef..fbe45b780272 100644 --- a/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/EouDetection.java +++ b/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/EouDetection.java @@ -81,8 +81,6 @@ public static EouDetection fromJson(JsonReader jsonReader) throws IOException { return AzureSemanticEouDetectionEn.fromJson(readerToUse.reset()); } else if ("semantic_detection_v1_multilingual".equals(discriminatorValue)) { return AzureSemanticEouDetectionMultilingual.fromJson(readerToUse.reset()); - } else if ("smart_end_of_turn_detection".equals(discriminatorValue)) { - return SmartEndOfTurnDetection.fromJson(readerToUse.reset()); } else if ("semantic_detection_v1".equals(discriminatorValue)) { return AzureSemanticEouDetection.fromJson(readerToUse.reset()); } else { diff --git a/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/EouDetectionModel.java b/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/EouDetectionModel.java index 44ecc2c69ac8..216818c8d33a 100644 --- a/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/EouDetectionModel.java +++ b/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/EouDetectionModel.java @@ -61,10 +61,4 @@ public static EouDetectionModel fromString(String name) { public static Collection values() { return values(EouDetectionModel.class); } - - /** - * Static value smart_end_of_turn_detection for EouDetectionModel. - */ - @Generated - public static final EouDetectionModel SMART_END_OF_TURN_DETECTION = fromString("smart_end_of_turn_detection"); } diff --git a/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/ResponseCreateParams.java b/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/ResponseCreateParams.java index 98e991dab07b..0b659f26f9e8 100644 --- a/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/ResponseCreateParams.java +++ b/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/ResponseCreateParams.java @@ -667,13 +667,13 @@ public ResponseCreateParams setInterimResponse(BinaryData interimResponse) { } /* - * Input data to invoke the hosted agent. This feature is in preview. + * Input data to invoke the hosted agent. */ @Generated private Map invokeInput; /** - * Get the invokeInput property: Input data to invoke the hosted agent. This feature is in preview. + * Get the invokeInput property: Input data to invoke the hosted agent. * * @return the invokeInput value. */ @@ -683,7 +683,7 @@ public Map getInvokeInput() { } /** - * Set the invokeInput property: Input data to invoke the hosted agent. This feature is in preview. + * Set the invokeInput property: Input data to invoke the hosted agent. * * @param invokeInput the invokeInput value to set. * @return the ResponseCreateParams object itself. diff --git a/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/RtcCallErrorDetails.java b/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/RtcCallErrorDetails.java deleted file mode 100644 index 353d8b663af9..000000000000 --- a/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/RtcCallErrorDetails.java +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// Code generated by Microsoft (R) TypeSpec Code Generator. -package com.azure.ai.voicelive.models; - -import com.azure.core.annotation.Generated; -import com.azure.core.annotation.Immutable; -import com.azure.json.JsonReader; -import com.azure.json.JsonSerializable; -import com.azure.json.JsonToken; -import com.azure.json.JsonWriter; -import java.io.IOException; - -/** - * Error details for RTC call errors. - */ -@Immutable -public final class RtcCallErrorDetails implements JsonSerializable { - - /* - * The error category: `invalid_request_error` or `server_error`. - */ - @Generated - private final String type; - - /* - * A machine-readable error code. - */ - @Generated - private String code; - - /* - * A human-readable error description. - */ - @Generated - private final String message; - - /** - * Creates an instance of RtcCallErrorDetails class. - * - * @param type the type value to set. - * @param message the message value to set. - */ - @Generated - private RtcCallErrorDetails(String type, String message) { - this.type = type; - this.message = message; - } - - /** - * Get the type property: The error category: `invalid_request_error` or `server_error`. - * - * @return the type value. - */ - @Generated - public String getType() { - return this.type; - } - - /** - * Get the code property: A machine-readable error code. - * - * @return the code value. - */ - @Generated - public String getCode() { - return this.code; - } - - /** - * Get the message property: A human-readable error description. - * - * @return the message value. - */ - @Generated - public String getMessage() { - return this.message; - } - - /** - * {@inheritDoc} - */ - @Generated - @Override - public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { - jsonWriter.writeStartObject(); - jsonWriter.writeStringField("type", this.type); - jsonWriter.writeStringField("message", this.message); - jsonWriter.writeStringField("code", this.code); - return jsonWriter.writeEndObject(); - } - - /** - * Reads an instance of RtcCallErrorDetails from the JsonReader. - * - * @param jsonReader The JsonReader being read. - * @return An instance of RtcCallErrorDetails if the JsonReader was pointing to an instance of it, or null if it was - * pointing to JSON null. - * @throws IllegalStateException If the deserialized JSON object was missing any required properties. - * @throws IOException If an error occurs while reading the RtcCallErrorDetails. - */ - @Generated - public static RtcCallErrorDetails fromJson(JsonReader jsonReader) throws IOException { - return jsonReader.readObject(reader -> { - String type = null; - String message = null; - String code = null; - while (reader.nextToken() != JsonToken.END_OBJECT) { - String fieldName = reader.getFieldName(); - reader.nextToken(); - if ("type".equals(fieldName)) { - type = reader.getString(); - } else if ("message".equals(fieldName)) { - message = reader.getString(); - } else if ("code".equals(fieldName)) { - code = reader.getString(); - } else { - reader.skipChildren(); - } - } - RtcCallErrorDetails deserializedRtcCallErrorDetails = new RtcCallErrorDetails(type, message); - deserializedRtcCallErrorDetails.code = code; - return deserializedRtcCallErrorDetails; - }); - } -} diff --git a/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/ServerEventOutputAudioBufferStarted.java b/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/ServerEventOutputAudioBufferStarted.java deleted file mode 100644 index eeeac02241e1..000000000000 --- a/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/ServerEventOutputAudioBufferStarted.java +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// Code generated by Microsoft (R) TypeSpec Code Generator. -package com.azure.ai.voicelive.models; - -import com.azure.core.annotation.Generated; -import com.azure.core.annotation.Immutable; -import com.azure.json.JsonReader; -import com.azure.json.JsonToken; -import com.azure.json.JsonWriter; -import java.io.IOException; - -/** - * Returned when model audio output starts playing. - */ -@Immutable -public final class ServerEventOutputAudioBufferStarted extends SessionServerEvent { - - /* - * The type of event. - */ - @Generated - private ServerEventType type = ServerEventType.OUTPUT_AUDIO_BUFFER_STARTED; - - /* - * The ID of the response whose audio started playing. - */ - @Generated - private String responseId; - - /** - * Creates an instance of ServerEventOutputAudioBufferStarted class. - */ - @Generated - private ServerEventOutputAudioBufferStarted() { - } - - /** - * Get the type property: The type of event. - * - * @return the type value. - */ - @Generated - @Override - public ServerEventType getType() { - return this.type; - } - - /** - * Get the responseId property: The ID of the response whose audio started playing. - * - * @return the responseId value. - */ - @Generated - public String getResponseId() { - return this.responseId; - } - - /** - * {@inheritDoc} - */ - @Generated - @Override - public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { - jsonWriter.writeStartObject(); - jsonWriter.writeStringField("event_id", getEventId()); - jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); - jsonWriter.writeStringField("response_id", this.responseId); - return jsonWriter.writeEndObject(); - } - - /** - * Reads an instance of ServerEventOutputAudioBufferStarted from the JsonReader. - * - * @param jsonReader The JsonReader being read. - * @return An instance of ServerEventOutputAudioBufferStarted if the JsonReader was pointing to an instance of it, - * or null if it was pointing to JSON null. - * @throws IOException If an error occurs while reading the ServerEventOutputAudioBufferStarted. - */ - @Generated - public static ServerEventOutputAudioBufferStarted fromJson(JsonReader jsonReader) throws IOException { - return jsonReader.readObject(reader -> { - ServerEventOutputAudioBufferStarted deserializedServerEventOutputAudioBufferStarted - = new ServerEventOutputAudioBufferStarted(); - while (reader.nextToken() != JsonToken.END_OBJECT) { - String fieldName = reader.getFieldName(); - reader.nextToken(); - if ("event_id".equals(fieldName)) { - deserializedServerEventOutputAudioBufferStarted.setEventId(reader.getString()); - } else if ("type".equals(fieldName)) { - deserializedServerEventOutputAudioBufferStarted.type - = ServerEventType.fromString(reader.getString()); - } else if ("response_id".equals(fieldName)) { - deserializedServerEventOutputAudioBufferStarted.responseId = reader.getString(); - } else { - reader.skipChildren(); - } - } - return deserializedServerEventOutputAudioBufferStarted; - }); - } -} diff --git a/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/ServerEventOutputAudioBufferStopped.java b/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/ServerEventOutputAudioBufferStopped.java deleted file mode 100644 index 212b5c37911b..000000000000 --- a/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/ServerEventOutputAudioBufferStopped.java +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// Code generated by Microsoft (R) TypeSpec Code Generator. -package com.azure.ai.voicelive.models; - -import com.azure.core.annotation.Generated; -import com.azure.core.annotation.Immutable; -import com.azure.json.JsonReader; -import com.azure.json.JsonToken; -import com.azure.json.JsonWriter; -import java.io.IOException; - -/** - * Returned when model audio output finishes playing. - */ -@Immutable -public final class ServerEventOutputAudioBufferStopped extends SessionServerEvent { - - /* - * The type of event. - */ - @Generated - private ServerEventType type = ServerEventType.OUTPUT_AUDIO_BUFFER_STOPPED; - - /* - * The ID of the response whose audio stopped playing. - */ - @Generated - private String responseId; - - /** - * Creates an instance of ServerEventOutputAudioBufferStopped class. - */ - @Generated - private ServerEventOutputAudioBufferStopped() { - } - - /** - * Get the type property: The type of event. - * - * @return the type value. - */ - @Generated - @Override - public ServerEventType getType() { - return this.type; - } - - /** - * Get the responseId property: The ID of the response whose audio stopped playing. - * - * @return the responseId value. - */ - @Generated - public String getResponseId() { - return this.responseId; - } - - /** - * {@inheritDoc} - */ - @Generated - @Override - public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { - jsonWriter.writeStartObject(); - jsonWriter.writeStringField("event_id", getEventId()); - jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); - jsonWriter.writeStringField("response_id", this.responseId); - return jsonWriter.writeEndObject(); - } - - /** - * Reads an instance of ServerEventOutputAudioBufferStopped from the JsonReader. - * - * @param jsonReader The JsonReader being read. - * @return An instance of ServerEventOutputAudioBufferStopped if the JsonReader was pointing to an instance of it, - * or null if it was pointing to JSON null. - * @throws IOException If an error occurs while reading the ServerEventOutputAudioBufferStopped. - */ - @Generated - public static ServerEventOutputAudioBufferStopped fromJson(JsonReader jsonReader) throws IOException { - return jsonReader.readObject(reader -> { - ServerEventOutputAudioBufferStopped deserializedServerEventOutputAudioBufferStopped - = new ServerEventOutputAudioBufferStopped(); - while (reader.nextToken() != JsonToken.END_OBJECT) { - String fieldName = reader.getFieldName(); - reader.nextToken(); - if ("event_id".equals(fieldName)) { - deserializedServerEventOutputAudioBufferStopped.setEventId(reader.getString()); - } else if ("type".equals(fieldName)) { - deserializedServerEventOutputAudioBufferStopped.type - = ServerEventType.fromString(reader.getString()); - } else if ("response_id".equals(fieldName)) { - deserializedServerEventOutputAudioBufferStopped.responseId = reader.getString(); - } else { - reader.skipChildren(); - } - } - return deserializedServerEventOutputAudioBufferStopped; - }); - } -} diff --git a/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/ServerEventRtcCallError.java b/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/ServerEventRtcCallError.java deleted file mode 100644 index b50e4b7ab6f6..000000000000 --- a/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/ServerEventRtcCallError.java +++ /dev/null @@ -1,151 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// Code generated by Microsoft (R) TypeSpec Code Generator. -package com.azure.ai.voicelive.models; - -import com.azure.core.annotation.Generated; -import com.azure.core.annotation.Immutable; -import com.azure.json.JsonReader; -import com.azure.json.JsonToken; -import com.azure.json.JsonWriter; -import java.io.IOException; - -/** - * Returned when a WebRTC call operation fails. - */ -@Immutable -public final class ServerEventRtcCallError extends SessionServerEvent { - - /* - * The type of event. - */ - @Generated - private ServerEventType type = ServerEventType.RTC_CALL_ERROR; - - /* - * The operation that caused the error (e.g., `rtc.call.sdp.create`). - */ - @Generated - private String operation; - - /* - * The RTC call identifier, if available. - */ - @Generated - private String rtcCallId; - - /* - * The error details. - */ - @Generated - private final RtcCallErrorDetails error; - - /** - * Creates an instance of ServerEventRtcCallError class. - * - * @param error the error value to set. - */ - @Generated - private ServerEventRtcCallError(RtcCallErrorDetails error) { - this.error = error; - } - - /** - * Get the type property: The type of event. - * - * @return the type value. - */ - @Generated - @Override - public ServerEventType getType() { - return this.type; - } - - /** - * Get the operation property: The operation that caused the error (e.g., `rtc.call.sdp.create`). - * - * @return the operation value. - */ - @Generated - public String getOperation() { - return this.operation; - } - - /** - * Get the rtcCallId property: The RTC call identifier, if available. - * - * @return the rtcCallId value. - */ - @Generated - public String getRtcCallId() { - return this.rtcCallId; - } - - /** - * Get the error property: The error details. - * - * @return the error value. - */ - @Generated - public RtcCallErrorDetails getError() { - return this.error; - } - - /** - * {@inheritDoc} - */ - @Generated - @Override - public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { - jsonWriter.writeStartObject(); - jsonWriter.writeStringField("event_id", getEventId()); - jsonWriter.writeJsonField("error", this.error); - jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); - jsonWriter.writeStringField("operation", this.operation); - jsonWriter.writeStringField("rtc_call_id", this.rtcCallId); - return jsonWriter.writeEndObject(); - } - - /** - * Reads an instance of ServerEventRtcCallError from the JsonReader. - * - * @param jsonReader The JsonReader being read. - * @return An instance of ServerEventRtcCallError if the JsonReader was pointing to an instance of it, or null if it - * was pointing to JSON null. - * @throws IllegalStateException If the deserialized JSON object was missing any required properties. - * @throws IOException If an error occurs while reading the ServerEventRtcCallError. - */ - @Generated - public static ServerEventRtcCallError fromJson(JsonReader jsonReader) throws IOException { - return jsonReader.readObject(reader -> { - String eventId = null; - RtcCallErrorDetails error = null; - ServerEventType type = ServerEventType.RTC_CALL_ERROR; - String operation = null; - String rtcCallId = null; - while (reader.nextToken() != JsonToken.END_OBJECT) { - String fieldName = reader.getFieldName(); - reader.nextToken(); - if ("event_id".equals(fieldName)) { - eventId = reader.getString(); - } else if ("error".equals(fieldName)) { - error = RtcCallErrorDetails.fromJson(reader); - } else if ("type".equals(fieldName)) { - type = ServerEventType.fromString(reader.getString()); - } else if ("operation".equals(fieldName)) { - operation = reader.getString(); - } else if ("rtc_call_id".equals(fieldName)) { - rtcCallId = reader.getString(); - } else { - reader.skipChildren(); - } - } - ServerEventRtcCallError deserializedServerEventRtcCallError = new ServerEventRtcCallError(error); - deserializedServerEventRtcCallError.setEventId(eventId); - deserializedServerEventRtcCallError.type = type; - deserializedServerEventRtcCallError.operation = operation; - deserializedServerEventRtcCallError.rtcCallId = rtcCallId; - return deserializedServerEventRtcCallError; - }); - } -} diff --git a/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/ServerEventRtcCallSdpCreated.java b/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/ServerEventRtcCallSdpCreated.java deleted file mode 100644 index 2a0920e1a9df..000000000000 --- a/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/ServerEventRtcCallSdpCreated.java +++ /dev/null @@ -1,132 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// Code generated by Microsoft (R) TypeSpec Code Generator. -package com.azure.ai.voicelive.models; - -import com.azure.core.annotation.Generated; -import com.azure.core.annotation.Immutable; -import com.azure.json.JsonReader; -import com.azure.json.JsonToken; -import com.azure.json.JsonWriter; -import java.io.IOException; - -/** - * Returned when the WebRTC SDP negotiation completes successfully. - */ -@Immutable -public final class ServerEventRtcCallSdpCreated extends SessionServerEvent { - - /* - * The type of event. - */ - @Generated - private ServerEventType type = ServerEventType.RTC_CALL_SDP_CREATED; - - /* - * The unique identifier for this RTC call session. - */ - @Generated - private final String rtcCallId; - - /* - * The SDP answer from the server for WebRTC negotiation. - */ - @Generated - private final String sdpAnswer; - - /** - * Creates an instance of ServerEventRtcCallSdpCreated class. - * - * @param rtcCallId the rtcCallId value to set. - * @param sdpAnswer the sdpAnswer value to set. - */ - @Generated - private ServerEventRtcCallSdpCreated(String rtcCallId, String sdpAnswer) { - this.rtcCallId = rtcCallId; - this.sdpAnswer = sdpAnswer; - } - - /** - * Get the type property: The type of event. - * - * @return the type value. - */ - @Generated - @Override - public ServerEventType getType() { - return this.type; - } - - /** - * Get the rtcCallId property: The unique identifier for this RTC call session. - * - * @return the rtcCallId value. - */ - @Generated - public String getRtcCallId() { - return this.rtcCallId; - } - - /** - * Get the sdpAnswer property: The SDP answer from the server for WebRTC negotiation. - * - * @return the sdpAnswer value. - */ - @Generated - public String getSdpAnswer() { - return this.sdpAnswer; - } - - /** - * {@inheritDoc} - */ - @Generated - @Override - public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { - jsonWriter.writeStartObject(); - jsonWriter.writeStringField("event_id", getEventId()); - jsonWriter.writeStringField("rtc_call_id", this.rtcCallId); - jsonWriter.writeStringField("sdp_answer", this.sdpAnswer); - jsonWriter.writeStringField("type", this.type == null ? null : this.type.toString()); - return jsonWriter.writeEndObject(); - } - - /** - * Reads an instance of ServerEventRtcCallSdpCreated from the JsonReader. - * - * @param jsonReader The JsonReader being read. - * @return An instance of ServerEventRtcCallSdpCreated if the JsonReader was pointing to an instance of it, or null - * if it was pointing to JSON null. - * @throws IllegalStateException If the deserialized JSON object was missing any required properties. - * @throws IOException If an error occurs while reading the ServerEventRtcCallSdpCreated. - */ - @Generated - public static ServerEventRtcCallSdpCreated fromJson(JsonReader jsonReader) throws IOException { - return jsonReader.readObject(reader -> { - String eventId = null; - String rtcCallId = null; - String sdpAnswer = null; - ServerEventType type = ServerEventType.RTC_CALL_SDP_CREATED; - while (reader.nextToken() != JsonToken.END_OBJECT) { - String fieldName = reader.getFieldName(); - reader.nextToken(); - if ("event_id".equals(fieldName)) { - eventId = reader.getString(); - } else if ("rtc_call_id".equals(fieldName)) { - rtcCallId = reader.getString(); - } else if ("sdp_answer".equals(fieldName)) { - sdpAnswer = reader.getString(); - } else if ("type".equals(fieldName)) { - type = ServerEventType.fromString(reader.getString()); - } else { - reader.skipChildren(); - } - } - ServerEventRtcCallSdpCreated deserializedServerEventRtcCallSdpCreated - = new ServerEventRtcCallSdpCreated(rtcCallId, sdpAnswer); - deserializedServerEventRtcCallSdpCreated.setEventId(eventId); - deserializedServerEventRtcCallSdpCreated.type = type; - return deserializedServerEventRtcCallSdpCreated; - }); - } -} diff --git a/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/ServerEventType.java b/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/ServerEventType.java index 0150f579b2a7..a2f98e0e6133 100644 --- a/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/ServerEventType.java +++ b/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/ServerEventType.java @@ -397,28 +397,4 @@ public static Collection values() { */ @Generated public static final ServerEventType RESPONSE_INVOCATION_DELTA = fromString("response.invocation.delta"); - - /** - * Returned when the WebRTC SDP negotiation completes successfully. - */ - @Generated - public static final ServerEventType RTC_CALL_SDP_CREATED = fromString("rtc.call.sdp.created"); - - /** - * Returned when a WebRTC call operation fails. - */ - @Generated - public static final ServerEventType RTC_CALL_ERROR = fromString("rtc.call.error"); - - /** - * Output audio buffer playback started. - */ - @Generated - public static final ServerEventType OUTPUT_AUDIO_BUFFER_STARTED = fromString("output_audio_buffer.started"); - - /** - * Output audio buffer playback stopped. - */ - @Generated - public static final ServerEventType OUTPUT_AUDIO_BUFFER_STOPPED = fromString("output_audio_buffer.stopped"); } diff --git a/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/SessionClientEvent.java b/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/SessionClientEvent.java index 6adb67f2de15..72e1deff3c82 100644 --- a/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/SessionClientEvent.java +++ b/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/SessionClientEvent.java @@ -142,8 +142,6 @@ public static SessionClientEvent fromJson(JsonReader jsonReader) throws IOExcept return ClientEventConversationItemRetrieve.fromJson(readerToUse.reset()); } else if ("output_audio_buffer.clear".equals(discriminatorValue)) { return ClientEventOutputAudioBufferClear.fromJson(readerToUse.reset()); - } else if ("rtc.call.sdp.create".equals(discriminatorValue)) { - return ClientEventRtcCallSdpCreate.fromJson(readerToUse.reset()); } else if ("session.update".equals(discriminatorValue)) { return ClientEventSessionUpdate.fromJson(readerToUse.reset()); } else { diff --git a/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/SessionServerEvent.java b/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/SessionServerEvent.java index dd1952b4593d..e66a1ecf3fe8 100644 --- a/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/SessionServerEvent.java +++ b/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/SessionServerEvent.java @@ -216,14 +216,6 @@ public static SessionServerEvent fromJson(JsonReader jsonReader) throws IOExcept return ServerEventResponseAudioTranscriptAnnotationAdded.fromJson(readerToUse.reset()); } else if ("response.invocation.delta".equals(discriminatorValue)) { return ServerEventResponseInvocationDelta.fromJson(readerToUse.reset()); - } else if ("rtc.call.sdp.created".equals(discriminatorValue)) { - return ServerEventRtcCallSdpCreated.fromJson(readerToUse.reset()); - } else if ("rtc.call.error".equals(discriminatorValue)) { - return ServerEventRtcCallError.fromJson(readerToUse.reset()); - } else if ("output_audio_buffer.started".equals(discriminatorValue)) { - return ServerEventOutputAudioBufferStarted.fromJson(readerToUse.reset()); - } else if ("output_audio_buffer.stopped".equals(discriminatorValue)) { - return ServerEventOutputAudioBufferStopped.fromJson(readerToUse.reset()); } else if ("error".equals(discriminatorValue)) { return SessionUpdateError.fromJson(readerToUse.reset()); } else { diff --git a/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/SmartEndOfTurnDetection.java b/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/SmartEndOfTurnDetection.java deleted file mode 100644 index a1e4992e0454..000000000000 --- a/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/SmartEndOfTurnDetection.java +++ /dev/null @@ -1,144 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -// Code generated by Microsoft (R) TypeSpec Code Generator. -package com.azure.ai.voicelive.models; - -import com.azure.core.annotation.Fluent; -import com.azure.core.annotation.Generated; -import com.azure.json.JsonReader; -import com.azure.json.JsonToken; -import com.azure.json.JsonWriter; -import java.io.IOException; - -/** - * Audio-based end-of-turn detection. Operates directly on the input audio - * stream rather than text. Use `threshold_level` and `timeout_ms` to tune - * detection. - */ -@Fluent -public final class SmartEndOfTurnDetection extends EouDetection { - - /* - * The model property. - */ - @Generated - private EouDetectionModel model = EouDetectionModel.SMART_END_OF_TURN_DETECTION; - - /* - * Threshold level setting. One of `low`, `medium`, `high`, or `default`. - */ - @Generated - private EouThresholdLevel thresholdLevel; - - /* - * Timeout in milliseconds. - */ - @Generated - private Integer timeoutMs; - - /** - * Creates an instance of SmartEndOfTurnDetection class. - */ - @Generated - public SmartEndOfTurnDetection() { - } - - /** - * Get the model property: The model property. - * - * @return the model value. - */ - @Generated - @Override - public EouDetectionModel getModel() { - return this.model; - } - - /** - * Get the thresholdLevel property: Threshold level setting. One of `low`, `medium`, `high`, or `default`. - * - * @return the thresholdLevel value. - */ - @Generated - public EouThresholdLevel getThresholdLevel() { - return this.thresholdLevel; - } - - /** - * Set the thresholdLevel property: Threshold level setting. One of `low`, `medium`, `high`, or `default`. - * - * @param thresholdLevel the thresholdLevel value to set. - * @return the SmartEndOfTurnDetection object itself. - */ - @Generated - public SmartEndOfTurnDetection setThresholdLevel(EouThresholdLevel thresholdLevel) { - this.thresholdLevel = thresholdLevel; - return this; - } - - /** - * Get the timeoutMs property: Timeout in milliseconds. - * - * @return the timeoutMs value. - */ - @Generated - public Integer getTimeoutMs() { - return this.timeoutMs; - } - - /** - * Set the timeoutMs property: Timeout in milliseconds. - * - * @param timeoutMs the timeoutMs value to set. - * @return the SmartEndOfTurnDetection object itself. - */ - @Generated - public SmartEndOfTurnDetection setTimeoutMs(Integer timeoutMs) { - this.timeoutMs = timeoutMs; - return this; - } - - /** - * {@inheritDoc} - */ - @Generated - @Override - public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { - jsonWriter.writeStartObject(); - jsonWriter.writeStringField("model", this.model == null ? null : this.model.toString()); - jsonWriter.writeStringField("threshold_level", - this.thresholdLevel == null ? null : this.thresholdLevel.toString()); - jsonWriter.writeNumberField("timeout_ms", this.timeoutMs); - return jsonWriter.writeEndObject(); - } - - /** - * Reads an instance of SmartEndOfTurnDetection from the JsonReader. - * - * @param jsonReader The JsonReader being read. - * @return An instance of SmartEndOfTurnDetection if the JsonReader was pointing to an instance of it, or null if it - * was pointing to JSON null. - * @throws IOException If an error occurs while reading the SmartEndOfTurnDetection. - */ - @Generated - public static SmartEndOfTurnDetection fromJson(JsonReader jsonReader) throws IOException { - return jsonReader.readObject(reader -> { - SmartEndOfTurnDetection deserializedSmartEndOfTurnDetection = new SmartEndOfTurnDetection(); - while (reader.nextToken() != JsonToken.END_OBJECT) { - String fieldName = reader.getFieldName(); - reader.nextToken(); - if ("model".equals(fieldName)) { - deserializedSmartEndOfTurnDetection.model = EouDetectionModel.fromString(reader.getString()); - } else if ("threshold_level".equals(fieldName)) { - deserializedSmartEndOfTurnDetection.thresholdLevel - = EouThresholdLevel.fromString(reader.getString()); - } else if ("timeout_ms".equals(fieldName)) { - deserializedSmartEndOfTurnDetection.timeoutMs = reader.getNullable(JsonReader::getInt); - } else { - reader.skipChildren(); - } - } - return deserializedSmartEndOfTurnDetection; - }); - } -} diff --git a/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/VoiceLiveSessionResponse.java b/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/VoiceLiveSessionResponse.java index 0e60c85073db..7cd461065356 100644 --- a/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/VoiceLiveSessionResponse.java +++ b/sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/models/VoiceLiveSessionResponse.java @@ -11,6 +11,9 @@ import com.azure.json.JsonToken; import com.azure.json.JsonWriter; import java.io.IOException; +import java.time.Instant; +import java.time.OffsetDateTime; +import java.time.ZoneOffset; import java.util.List; import java.util.Map; @@ -560,6 +563,7 @@ public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { jsonWriter.writeMapField("metadata", this.metadata, (writer, element) -> writer.writeString(element)); jsonWriter.writeJsonField("agent", this.agent); jsonWriter.writeStringField("id", this.id); + jsonWriter.writeNumberField("expires_at", this.expiresAt); return jsonWriter.writeEndObject(); } @@ -648,6 +652,8 @@ public static VoiceLiveSessionResponse fromJson(JsonReader jsonReader) throws IO deserializedVoiceLiveSessionResponse.agent = RespondingAgentOptions.fromJson(reader); } else if ("id".equals(fieldName)) { deserializedVoiceLiveSessionResponse.id = reader.getString(); + } else if ("expires_at".equals(fieldName)) { + deserializedVoiceLiveSessionResponse.expiresAt = reader.getNullable(JsonReader::getLong); } else { reader.skipChildren(); } @@ -908,4 +914,41 @@ public VoiceLiveSessionResponse setParallelToolCalls(Boolean parallelToolCalls) this.parallelToolCalls = parallelToolCalls; return this; } + + /* + * Expiration time for the session. This value is set by the server and cannot be changed with `session.update`. + */ + @Generated + private Long expiresAt; + + /** + * Get the expiresAt property: Expiration time for the session. This value is set by the server and cannot be + * changed with `session.update`. + * + * @return the expiresAt value. + */ + @Generated + public OffsetDateTime getExpiresAt() { + if (this.expiresAt == null) { + return null; + } + return OffsetDateTime.ofInstant(Instant.ofEpochSecond(this.expiresAt), ZoneOffset.UTC); + } + + /** + * Set the expiresAt property: Expiration time for the session. This value is set by the server and cannot be + * changed with `session.update`. + * + * @param expiresAt the expiresAt value to set. + * @return the VoiceLiveSessionResponse object itself. + */ + @Generated + public VoiceLiveSessionResponse setExpiresAt(OffsetDateTime expiresAt) { + if (expiresAt == null) { + this.expiresAt = null; + } else { + this.expiresAt = expiresAt.toEpochSecond(); + } + return this; + } } diff --git a/sdk/voicelive/azure-ai-voicelive/src/main/resources/META-INF/azure-ai-voicelive_metadata.json b/sdk/voicelive/azure-ai-voicelive/src/main/resources/META-INF/azure-ai-voicelive_metadata.json index c32822678f07..723976c812f7 100644 --- a/sdk/voicelive/azure-ai-voicelive/src/main/resources/META-INF/azure-ai-voicelive_metadata.json +++ b/sdk/voicelive/azure-ai-voicelive/src/main/resources/META-INF/azure-ai-voicelive_metadata.json @@ -1 +1 @@ -{"flavor":"azure","apiVersions":{"VoiceLive":"2026-06-01-preview"},"crossLanguagePackageId":"VoiceLive","crossLanguageVersion":"9b238185e57a","crossLanguageDefinitions":{"com.azure.ai.voicelive.models.AnimationOptions":"VoiceLive.Animation","com.azure.ai.voicelive.models.AnimationOutputType":"VoiceLive.AnimationOutputType","com.azure.ai.voicelive.models.AssistantMessageItem":"VoiceLive.AssistantMessageItem","com.azure.ai.voicelive.models.AudioEchoCancellation":"VoiceLive.AudioEchoCancellation","com.azure.ai.voicelive.models.AudioInputTranscriptionOptions":"VoiceLive.AudioInputTranscriptionOptions","com.azure.ai.voicelive.models.AudioInputTranscriptionOptionsModel":"VoiceLive.AudioInputTranscriptionOptions.model.anonymous","com.azure.ai.voicelive.models.AudioNoiseReduction":"VoiceLive.AudioNoiseReduction","com.azure.ai.voicelive.models.AudioNoiseReductionType":"VoiceLive.AudioNoiseReduction.type.anonymous","com.azure.ai.voicelive.models.AudioTimestampType":"VoiceLive.AudioTimestampType","com.azure.ai.voicelive.models.AvatarConfigTypes":"VoiceLive.AvatarConfigTypes","com.azure.ai.voicelive.models.AvatarOptions":"VoiceLive.AvatarConfig","com.azure.ai.voicelive.models.AvatarOutputProtocol":"VoiceLive.AvatarOutputProtocol","com.azure.ai.voicelive.models.AzureAvatarVoiceSyncVoice":"VoiceLive.AzureAvatarVoiceSyncVoice","com.azure.ai.voicelive.models.AzureCustomVoice":"VoiceLive.AzureCustomVoice","com.azure.ai.voicelive.models.AzurePersonalVoice":"VoiceLive.AzurePersonalVoice","com.azure.ai.voicelive.models.AzureRealtimeNativeVoice":"VoiceLive.AzureRealtimeNativeVoice","com.azure.ai.voicelive.models.AzureRealtimeNativeVoiceName":"VoiceLive.AzureRealtimeNativeVoiceName","com.azure.ai.voicelive.models.AzureSemanticEouDetection":"VoiceLive.AzureSemanticDetection","com.azure.ai.voicelive.models.AzureSemanticEouDetectionEn":"VoiceLive.AzureSemanticDetectionEn","com.azure.ai.voicelive.models.AzureSemanticEouDetectionMultilingual":"VoiceLive.AzureSemanticDetectionMultilingual","com.azure.ai.voicelive.models.AzureSemanticVadTurnDetection":"VoiceLive.AzureSemanticVad","com.azure.ai.voicelive.models.AzureSemanticVadTurnDetectionEn":"VoiceLive.AzureSemanticVadEn","com.azure.ai.voicelive.models.AzureSemanticVadTurnDetectionMultilingual":"VoiceLive.AzureSemanticVadMultilingual","com.azure.ai.voicelive.models.AzureStandardVoice":"VoiceLive.AzureStandardVoice","com.azure.ai.voicelive.models.AzureVoice":"VoiceLive.AzureVoice","com.azure.ai.voicelive.models.AzureVoiceType":"VoiceLive.AzureVoiceType","com.azure.ai.voicelive.models.CachedTokenDetails":"VoiceLive.CachedTokenDetails","com.azure.ai.voicelive.models.ClientEventConversationItemCreate":"VoiceLive.ClientEventConversationItemCreate","com.azure.ai.voicelive.models.ClientEventConversationItemDelete":"VoiceLive.ClientEventConversationItemDelete","com.azure.ai.voicelive.models.ClientEventConversationItemRetrieve":"VoiceLive.ClientEventConversationItemRetrieve","com.azure.ai.voicelive.models.ClientEventConversationItemTruncate":"VoiceLive.ClientEventConversationItemTruncate","com.azure.ai.voicelive.models.ClientEventInputAudioBufferAppend":"VoiceLive.ClientEventInputAudioBufferAppend","com.azure.ai.voicelive.models.ClientEventInputAudioBufferClear":"VoiceLive.ClientEventInputAudioBufferClear","com.azure.ai.voicelive.models.ClientEventInputAudioBufferCommit":"VoiceLive.ClientEventInputAudioBufferCommit","com.azure.ai.voicelive.models.ClientEventInputAudioClear":"VoiceLive.ClientEventInputAudioClear","com.azure.ai.voicelive.models.ClientEventInputAudioTurnAppend":"VoiceLive.ClientEventInputAudioTurnAppend","com.azure.ai.voicelive.models.ClientEventInputAudioTurnCancel":"VoiceLive.ClientEventInputAudioTurnCancel","com.azure.ai.voicelive.models.ClientEventInputAudioTurnEnd":"VoiceLive.ClientEventInputAudioTurnEnd","com.azure.ai.voicelive.models.ClientEventInputAudioTurnStart":"VoiceLive.ClientEventInputAudioTurnStart","com.azure.ai.voicelive.models.ClientEventInputTextDelta":"VoiceLive.ClientEventInputTextDelta","com.azure.ai.voicelive.models.ClientEventInputTextDone":"VoiceLive.ClientEventInputTextDone","com.azure.ai.voicelive.models.ClientEventOutputAudioBufferClear":"VoiceLive.ClientEventOutputAudioBufferClear","com.azure.ai.voicelive.models.ClientEventResponseCancel":"VoiceLive.ClientEventResponseCancel","com.azure.ai.voicelive.models.ClientEventResponseCreate":"VoiceLive.ClientEventResponseCreate","com.azure.ai.voicelive.models.ClientEventRtcCallSdpCreate":"VoiceLive.ClientEventRtcCallSdpCreate","com.azure.ai.voicelive.models.ClientEventSessionAvatarConnect":"VoiceLive.ClientEventSessionAvatarConnect","com.azure.ai.voicelive.models.ClientEventSessionUpdate":"VoiceLive.ClientEventSessionUpdate","com.azure.ai.voicelive.models.ClientEventType":"VoiceLive.ClientEventType","com.azure.ai.voicelive.models.ContentPartType":"VoiceLive.ContentPartType","com.azure.ai.voicelive.models.ConversationRequestItem":"VoiceLive.ConversationRequestItem","com.azure.ai.voicelive.models.EchoCancellationReferenceSource":"VoiceLive.EchoCancellationReferenceSource","com.azure.ai.voicelive.models.EouDetection":"VoiceLive.EouDetection","com.azure.ai.voicelive.models.EouDetectionModel":"VoiceLive.EouDetection.model.anonymous","com.azure.ai.voicelive.models.EouThresholdLevel":"VoiceLive.EouThresholdLevel","com.azure.ai.voicelive.models.FileSearchResult":"VoiceLive.FileSearchResult","com.azure.ai.voicelive.models.FunctionCallItem":"VoiceLive.FunctionCallItem","com.azure.ai.voicelive.models.FunctionCallOutputItem":"VoiceLive.FunctionCallOutputItem","com.azure.ai.voicelive.models.IceServer":"VoiceLive.IceServer","com.azure.ai.voicelive.models.InputAudioContentPart":"VoiceLive.InputAudioContentPart","com.azure.ai.voicelive.models.InputAudioFormat":"VoiceLive.InputAudioFormat","com.azure.ai.voicelive.models.InputTextContentPart":"VoiceLive.InputTextContentPart","com.azure.ai.voicelive.models.InputTokenDetails":"VoiceLive.InputTokenDetails","com.azure.ai.voicelive.models.InteractionModality":"VoiceLive.Modality","com.azure.ai.voicelive.models.InterimResponseConfigBase":"VoiceLive.InterimResponseConfigBase","com.azure.ai.voicelive.models.InterimResponseConfigType":"VoiceLive.InterimResponseConfigType","com.azure.ai.voicelive.models.InterimResponseTrigger":"VoiceLive.InterimResponseTrigger","com.azure.ai.voicelive.models.ItemParamStatus":"VoiceLive.ItemParamStatus","com.azure.ai.voicelive.models.ItemType":"VoiceLive.ItemType","com.azure.ai.voicelive.models.LlmInterimResponseConfig":"VoiceLive.LlmInterimResponseConfig","com.azure.ai.voicelive.models.LogProbProperties":"VoiceLive.LogProbProperties","com.azure.ai.voicelive.models.McpApprovalResponseRequestItem":"VoiceLive.MCPApprovalResponseRequestItem","com.azure.ai.voicelive.models.McpApprovalType":"VoiceLive.MCPApprovalType","com.azure.ai.voicelive.models.McpServer":"VoiceLive.MCPServer","com.azure.ai.voicelive.models.McpTool":"VoiceLive.MCPTool","com.azure.ai.voicelive.models.MessageContentPart":"VoiceLive.MessageContentPart","com.azure.ai.voicelive.models.MessageItem":"VoiceLive.MessageItem","com.azure.ai.voicelive.models.OpenAIVoice":"VoiceLive.OpenAIVoice","com.azure.ai.voicelive.models.OpenAIVoiceName":"VoiceLive.OAIVoice","com.azure.ai.voicelive.models.OutputAudioFormat":"VoiceLive.OutputAudioFormat","com.azure.ai.voicelive.models.OutputTextContentPart":"VoiceLive.OutputTextContentPart","com.azure.ai.voicelive.models.OutputTokenDetails":"VoiceLive.OutputTokenDetails","com.azure.ai.voicelive.models.PersonalVoiceModels":"VoiceLive.PersonalVoiceModels","com.azure.ai.voicelive.models.PhotoAvatarBaseModes":"VoiceLive.PhotoAvatarBaseModes","com.azure.ai.voicelive.models.ReasoningEffort":"VoiceLive.ReasoningEffort","com.azure.ai.voicelive.models.RequestAudioContentPart":"VoiceLive.RequestAudioContentPart","com.azure.ai.voicelive.models.RequestImageContentPart":"VoiceLive.RequestImageContentPart","com.azure.ai.voicelive.models.RequestImageContentPartDetail":"VoiceLive.RequestImageContentPartDetail","com.azure.ai.voicelive.models.RequestTextContentPart":"VoiceLive.RequestTextContentPart","com.azure.ai.voicelive.models.RespondingAgentOptions":"VoiceLive.AgentConfig","com.azure.ai.voicelive.models.ResponseAudioContentPart":"VoiceLive.ResponseAudioContentPart","com.azure.ai.voicelive.models.ResponseCancelledDetails":"VoiceLive.ResponseCancelledDetails","com.azure.ai.voicelive.models.ResponseCancelledDetailsReason":"VoiceLive.ResponseCancelledDetails.reason.anonymous","com.azure.ai.voicelive.models.ResponseCreateParams":"VoiceLive.ResponseCreateParams","com.azure.ai.voicelive.models.ResponseFailedDetails":"VoiceLive.ResponseFailedDetails","com.azure.ai.voicelive.models.ResponseFileSearchCallItem":"VoiceLive.ResponseFileSearchCallItem","com.azure.ai.voicelive.models.ResponseFileSearchCallItemStatus":"VoiceLive.ResponseFileSearchCallItem.status.anonymous","com.azure.ai.voicelive.models.ResponseFunctionCallItem":"VoiceLive.ResponseFunctionCallItem","com.azure.ai.voicelive.models.ResponseFunctionCallOutputItem":"VoiceLive.ResponseFunctionCallOutputItem","com.azure.ai.voicelive.models.ResponseIncompleteDetails":"VoiceLive.ResponseIncompleteDetails","com.azure.ai.voicelive.models.ResponseIncompleteDetailsReason":"VoiceLive.ResponseIncompleteDetails.reason.anonymous","com.azure.ai.voicelive.models.ResponseItemObject":null,"com.azure.ai.voicelive.models.ResponseMcpApprovalRequestItem":"VoiceLive.ResponseMCPApprovalRequestItem","com.azure.ai.voicelive.models.ResponseMcpApprovalResponseItem":"VoiceLive.ResponseMCPApprovalResponseItem","com.azure.ai.voicelive.models.ResponseMcpCallItem":"VoiceLive.ResponseMCPCallItem","com.azure.ai.voicelive.models.ResponseMcpListToolItem":"VoiceLive.ResponseMCPListToolItem","com.azure.ai.voicelive.models.ResponseMessageRole":"VoiceLive.MessageRole","com.azure.ai.voicelive.models.ResponseObject":null,"com.azure.ai.voicelive.models.ResponseStatusDetails":"VoiceLive.ResponseStatusDetails","com.azure.ai.voicelive.models.ResponseTextContentPart":"VoiceLive.ResponseTextContentPart","com.azure.ai.voicelive.models.ResponseTokenStatistics":"VoiceLive.TokenUsage","com.azure.ai.voicelive.models.ResponseWebSearchCallItem":"VoiceLive.ResponseWebSearchCallItem","com.azure.ai.voicelive.models.ResponseWebSearchCallItemStatus":"VoiceLive.ResponseWebSearchCallItem.status.anonymous","com.azure.ai.voicelive.models.RtcCallErrorDetails":"VoiceLive.RtcCallErrorDetails","com.azure.ai.voicelive.models.Scene":"VoiceLive.Scene","com.azure.ai.voicelive.models.ServerEventMcpListToolsCompleted":"VoiceLive.ServerEventMcpListToolsCompleted","com.azure.ai.voicelive.models.ServerEventMcpListToolsFailed":"VoiceLive.ServerEventMcpListToolsFailed","com.azure.ai.voicelive.models.ServerEventMcpListToolsInProgress":"VoiceLive.ServerEventMcpListToolsInProgress","com.azure.ai.voicelive.models.ServerEventOutputAudioBufferCleared":"VoiceLive.ServerEventOutputAudioBufferCleared","com.azure.ai.voicelive.models.ServerEventOutputAudioBufferStarted":"VoiceLive.ServerEventOutputAudioBufferStarted","com.azure.ai.voicelive.models.ServerEventOutputAudioBufferStopped":"VoiceLive.ServerEventOutputAudioBufferStopped","com.azure.ai.voicelive.models.ServerEventResponseAudioTranscriptAnnotationAdded":"VoiceLive.ServerEventResponseAudioTranscriptAnnotationAdded","com.azure.ai.voicelive.models.ServerEventResponseFileSearchCallCompleted":"VoiceLive.ServerEventResponseFileSearchCallCompleted","com.azure.ai.voicelive.models.ServerEventResponseFileSearchCallInProgress":"VoiceLive.ServerEventResponseFileSearchCallInProgress","com.azure.ai.voicelive.models.ServerEventResponseFileSearchCallSearching":"VoiceLive.ServerEventResponseFileSearchCallSearching","com.azure.ai.voicelive.models.ServerEventResponseInvocationDelta":"VoiceLive.ServerEventResponseInvocationDelta","com.azure.ai.voicelive.models.ServerEventResponseMcpCallArgumentsDelta":"VoiceLive.ServerEventResponseMcpCallArgumentsDelta","com.azure.ai.voicelive.models.ServerEventResponseMcpCallArgumentsDone":"VoiceLive.ServerEventResponseMcpCallArgumentsDone","com.azure.ai.voicelive.models.ServerEventResponseMcpCallCompleted":"VoiceLive.ServerEventResponseMcpCallCompleted","com.azure.ai.voicelive.models.ServerEventResponseMcpCallFailed":"VoiceLive.ServerEventResponseMcpCallFailed","com.azure.ai.voicelive.models.ServerEventResponseMcpCallInProgress":"VoiceLive.ServerEventResponseMcpCallInProgress","com.azure.ai.voicelive.models.ServerEventResponseVideoDelta":"VoiceLive.ServerEventResponseVideoDelta","com.azure.ai.voicelive.models.ServerEventResponseWebSearchCallCompleted":"VoiceLive.ServerEventResponseWebSearchCallCompleted","com.azure.ai.voicelive.models.ServerEventResponseWebSearchCallInProgress":"VoiceLive.ServerEventResponseWebSearchCallInProgress","com.azure.ai.voicelive.models.ServerEventResponseWebSearchCallSearching":"VoiceLive.ServerEventResponseWebSearchCallSearching","com.azure.ai.voicelive.models.ServerEventRtcCallError":"VoiceLive.ServerEventRtcCallError","com.azure.ai.voicelive.models.ServerEventRtcCallSdpCreated":"VoiceLive.ServerEventRtcCallSdpCreated","com.azure.ai.voicelive.models.ServerEventSessionAvatarSwitchToIdle":"VoiceLive.ServerEventSessionAvatarSwitchToIdle","com.azure.ai.voicelive.models.ServerEventSessionAvatarSwitchToSpeaking":"VoiceLive.ServerEventSessionAvatarSwitchToSpeaking","com.azure.ai.voicelive.models.ServerEventType":"VoiceLive.ServerEventType","com.azure.ai.voicelive.models.ServerEventWarning":"VoiceLive.ServerEventWarning","com.azure.ai.voicelive.models.ServerEventWarningDetails":"VoiceLive.ServerEventWarningDetails","com.azure.ai.voicelive.models.ServerVadTurnDetection":"VoiceLive.ServerVad","com.azure.ai.voicelive.models.SessionClientEvent":"VoiceLive.ClientEvent","com.azure.ai.voicelive.models.SessionIncludeOption":"VoiceLive.SessionIncludeOption","com.azure.ai.voicelive.models.SessionResponse":"VoiceLive.Response","com.azure.ai.voicelive.models.SessionResponseItem":"VoiceLive.ResponseItem","com.azure.ai.voicelive.models.SessionResponseItemStatus":"VoiceLive.ResponseItemStatus","com.azure.ai.voicelive.models.SessionResponseMessageItem":"VoiceLive.ResponseMessageItem","com.azure.ai.voicelive.models.SessionResponseStatus":"VoiceLive.ResponseStatus","com.azure.ai.voicelive.models.SessionServerEvent":"VoiceLive.ServerEvent","com.azure.ai.voicelive.models.SessionUpdateAvatarConnecting":"VoiceLive.ServerEventSessionAvatarConnecting","com.azure.ai.voicelive.models.SessionUpdateConversationItemCreated":"VoiceLive.ServerEventConversationItemCreated","com.azure.ai.voicelive.models.SessionUpdateConversationItemDeleted":"VoiceLive.ServerEventConversationItemDeleted","com.azure.ai.voicelive.models.SessionUpdateConversationItemInputAudioTranscriptionCompleted":"VoiceLive.ServerEventConversationItemInputAudioTranscriptionCompleted","com.azure.ai.voicelive.models.SessionUpdateConversationItemInputAudioTranscriptionDelta":"VoiceLive.ServerEventConversationItemInputAudioTranscriptionDelta","com.azure.ai.voicelive.models.SessionUpdateConversationItemInputAudioTranscriptionFailed":"VoiceLive.ServerEventConversationItemInputAudioTranscriptionFailed","com.azure.ai.voicelive.models.SessionUpdateConversationItemRetrieved":"VoiceLive.ServerEventConversationItemRetrieved","com.azure.ai.voicelive.models.SessionUpdateConversationItemTruncated":"VoiceLive.ServerEventConversationItemTruncated","com.azure.ai.voicelive.models.SessionUpdateError":"VoiceLive.ServerEventError","com.azure.ai.voicelive.models.SessionUpdateErrorDetails":"VoiceLive.ServerEventErrorDetails","com.azure.ai.voicelive.models.SessionUpdateInputAudioBufferCleared":"VoiceLive.ServerEventInputAudioBufferCleared","com.azure.ai.voicelive.models.SessionUpdateInputAudioBufferCommitted":"VoiceLive.ServerEventInputAudioBufferCommitted","com.azure.ai.voicelive.models.SessionUpdateInputAudioBufferSpeechStarted":"VoiceLive.ServerEventInputAudioBufferSpeechStarted","com.azure.ai.voicelive.models.SessionUpdateInputAudioBufferSpeechStopped":"VoiceLive.ServerEventInputAudioBufferSpeechStopped","com.azure.ai.voicelive.models.SessionUpdateResponseAnimationBlendshapeDelta":"VoiceLive.ServerEventResponseAnimationBlendshapeDelta","com.azure.ai.voicelive.models.SessionUpdateResponseAnimationBlendshapeDone":"VoiceLive.ServerEventResponseAnimationBlendshapeDone","com.azure.ai.voicelive.models.SessionUpdateResponseAnimationVisemeDelta":"VoiceLive.ServerEventResponseAnimationVisemeDelta","com.azure.ai.voicelive.models.SessionUpdateResponseAnimationVisemeDone":"VoiceLive.ServerEventResponseAnimationVisemeDone","com.azure.ai.voicelive.models.SessionUpdateResponseAudioDelta":"VoiceLive.ServerEventResponseAudioDelta","com.azure.ai.voicelive.models.SessionUpdateResponseAudioDone":"VoiceLive.ServerEventResponseAudioDone","com.azure.ai.voicelive.models.SessionUpdateResponseAudioTimestampDelta":"VoiceLive.ServerEventResponseAudioTimestampDelta","com.azure.ai.voicelive.models.SessionUpdateResponseAudioTimestampDone":"VoiceLive.ServerEventResponseAudioTimestampDone","com.azure.ai.voicelive.models.SessionUpdateResponseAudioTranscriptDelta":"VoiceLive.ServerEventResponseAudioTranscriptDelta","com.azure.ai.voicelive.models.SessionUpdateResponseAudioTranscriptDone":"VoiceLive.ServerEventResponseAudioTranscriptDone","com.azure.ai.voicelive.models.SessionUpdateResponseContentPartAdded":"VoiceLive.ServerEventResponseContentPartAdded","com.azure.ai.voicelive.models.SessionUpdateResponseContentPartDone":"VoiceLive.ServerEventResponseContentPartDone","com.azure.ai.voicelive.models.SessionUpdateResponseCreated":"VoiceLive.ServerEventResponseCreated","com.azure.ai.voicelive.models.SessionUpdateResponseDone":"VoiceLive.ServerEventResponseDone","com.azure.ai.voicelive.models.SessionUpdateResponseFunctionCallArgumentsDelta":"VoiceLive.ServerEventResponseFunctionCallArgumentsDelta","com.azure.ai.voicelive.models.SessionUpdateResponseFunctionCallArgumentsDone":"VoiceLive.ServerEventResponseFunctionCallArgumentsDone","com.azure.ai.voicelive.models.SessionUpdateResponseOutputItemAdded":"VoiceLive.ServerEventResponseOutputItemAdded","com.azure.ai.voicelive.models.SessionUpdateResponseOutputItemDone":"VoiceLive.ServerEventResponseOutputItemDone","com.azure.ai.voicelive.models.SessionUpdateResponseTextDelta":"VoiceLive.ServerEventResponseTextDelta","com.azure.ai.voicelive.models.SessionUpdateResponseTextDone":"VoiceLive.ServerEventResponseTextDone","com.azure.ai.voicelive.models.SessionUpdateSessionCreated":"VoiceLive.ServerEventSessionCreated","com.azure.ai.voicelive.models.SessionUpdateSessionUpdated":"VoiceLive.ServerEventSessionUpdated","com.azure.ai.voicelive.models.SmartEndOfTurnDetection":"VoiceLive.SmartEndOfTurnDetection","com.azure.ai.voicelive.models.StaticInterimResponseConfig":"VoiceLive.StaticInterimResponseConfig","com.azure.ai.voicelive.models.SystemMessageItem":"VoiceLive.SystemMessageItem","com.azure.ai.voicelive.models.ToolChoiceFunctionSelection":"VoiceLive.ToolChoiceFunctionObject","com.azure.ai.voicelive.models.ToolChoiceLiteral":"VoiceLive.ToolChoiceLiteral","com.azure.ai.voicelive.models.ToolChoiceSelection":"VoiceLive.ToolChoiceObject","com.azure.ai.voicelive.models.ToolType":"VoiceLive.ToolType","com.azure.ai.voicelive.models.TranscriptionPhrase":"VoiceLive.TranscriptionPhrase","com.azure.ai.voicelive.models.TranscriptionWord":"VoiceLive.TranscriptionWord","com.azure.ai.voicelive.models.TurnDetection":"VoiceLive.TurnDetection","com.azure.ai.voicelive.models.TurnDetectionType":"VoiceLive.TurnDetectionType","com.azure.ai.voicelive.models.UserMessageItem":"VoiceLive.UserMessageItem","com.azure.ai.voicelive.models.VideoBackground":"VoiceLive.Background","com.azure.ai.voicelive.models.VideoCrop":"VoiceLive.VideoCrop","com.azure.ai.voicelive.models.VideoParams":"VoiceLive.VideoParams","com.azure.ai.voicelive.models.VideoParamsCodec":null,"com.azure.ai.voicelive.models.VideoResolution":"VoiceLive.VideoResolution","com.azure.ai.voicelive.models.VoiceLiveContentPart":"VoiceLive.ContentPart","com.azure.ai.voicelive.models.VoiceLiveErrorDetails":"VoiceLive.VoiceLiveErrorDetails","com.azure.ai.voicelive.models.VoiceLiveFunctionDefinition":"VoiceLive.FunctionTool","com.azure.ai.voicelive.models.VoiceLiveSessionOptions":"VoiceLive.RequestSession","com.azure.ai.voicelive.models.VoiceLiveSessionResponse":"VoiceLive.ResponseSession","com.azure.ai.voicelive.models.VoiceLiveToolDefinition":"VoiceLive.Tool"},"generatedFiles":["src/main/java/com/azure/ai/voicelive/implementation/package-info.java","src/main/java/com/azure/ai/voicelive/models/AnimationOptions.java","src/main/java/com/azure/ai/voicelive/models/AnimationOutputType.java","src/main/java/com/azure/ai/voicelive/models/AssistantMessageItem.java","src/main/java/com/azure/ai/voicelive/models/AudioEchoCancellation.java","src/main/java/com/azure/ai/voicelive/models/AudioInputTranscriptionOptions.java","src/main/java/com/azure/ai/voicelive/models/AudioInputTranscriptionOptionsModel.java","src/main/java/com/azure/ai/voicelive/models/AudioNoiseReduction.java","src/main/java/com/azure/ai/voicelive/models/AudioNoiseReductionType.java","src/main/java/com/azure/ai/voicelive/models/AudioTimestampType.java","src/main/java/com/azure/ai/voicelive/models/AvatarConfigTypes.java","src/main/java/com/azure/ai/voicelive/models/AvatarOptions.java","src/main/java/com/azure/ai/voicelive/models/AvatarOutputProtocol.java","src/main/java/com/azure/ai/voicelive/models/AzureAvatarVoiceSyncVoice.java","src/main/java/com/azure/ai/voicelive/models/AzureCustomVoice.java","src/main/java/com/azure/ai/voicelive/models/AzurePersonalVoice.java","src/main/java/com/azure/ai/voicelive/models/AzureRealtimeNativeVoice.java","src/main/java/com/azure/ai/voicelive/models/AzureRealtimeNativeVoiceName.java","src/main/java/com/azure/ai/voicelive/models/AzureSemanticEouDetection.java","src/main/java/com/azure/ai/voicelive/models/AzureSemanticEouDetectionEn.java","src/main/java/com/azure/ai/voicelive/models/AzureSemanticEouDetectionMultilingual.java","src/main/java/com/azure/ai/voicelive/models/AzureSemanticVadTurnDetection.java","src/main/java/com/azure/ai/voicelive/models/AzureSemanticVadTurnDetectionEn.java","src/main/java/com/azure/ai/voicelive/models/AzureSemanticVadTurnDetectionMultilingual.java","src/main/java/com/azure/ai/voicelive/models/AzureStandardVoice.java","src/main/java/com/azure/ai/voicelive/models/AzureVoice.java","src/main/java/com/azure/ai/voicelive/models/AzureVoiceType.java","src/main/java/com/azure/ai/voicelive/models/CachedTokenDetails.java","src/main/java/com/azure/ai/voicelive/models/ClientEventConversationItemCreate.java","src/main/java/com/azure/ai/voicelive/models/ClientEventConversationItemDelete.java","src/main/java/com/azure/ai/voicelive/models/ClientEventConversationItemRetrieve.java","src/main/java/com/azure/ai/voicelive/models/ClientEventConversationItemTruncate.java","src/main/java/com/azure/ai/voicelive/models/ClientEventInputAudioBufferAppend.java","src/main/java/com/azure/ai/voicelive/models/ClientEventInputAudioBufferClear.java","src/main/java/com/azure/ai/voicelive/models/ClientEventInputAudioBufferCommit.java","src/main/java/com/azure/ai/voicelive/models/ClientEventInputAudioClear.java","src/main/java/com/azure/ai/voicelive/models/ClientEventInputAudioTurnAppend.java","src/main/java/com/azure/ai/voicelive/models/ClientEventInputAudioTurnCancel.java","src/main/java/com/azure/ai/voicelive/models/ClientEventInputAudioTurnEnd.java","src/main/java/com/azure/ai/voicelive/models/ClientEventInputAudioTurnStart.java","src/main/java/com/azure/ai/voicelive/models/ClientEventInputTextDelta.java","src/main/java/com/azure/ai/voicelive/models/ClientEventInputTextDone.java","src/main/java/com/azure/ai/voicelive/models/ClientEventOutputAudioBufferClear.java","src/main/java/com/azure/ai/voicelive/models/ClientEventResponseCancel.java","src/main/java/com/azure/ai/voicelive/models/ClientEventResponseCreate.java","src/main/java/com/azure/ai/voicelive/models/ClientEventRtcCallSdpCreate.java","src/main/java/com/azure/ai/voicelive/models/ClientEventSessionAvatarConnect.java","src/main/java/com/azure/ai/voicelive/models/ClientEventSessionUpdate.java","src/main/java/com/azure/ai/voicelive/models/ClientEventType.java","src/main/java/com/azure/ai/voicelive/models/ContentPartType.java","src/main/java/com/azure/ai/voicelive/models/ConversationRequestItem.java","src/main/java/com/azure/ai/voicelive/models/EchoCancellationReferenceSource.java","src/main/java/com/azure/ai/voicelive/models/EouDetection.java","src/main/java/com/azure/ai/voicelive/models/EouDetectionModel.java","src/main/java/com/azure/ai/voicelive/models/EouThresholdLevel.java","src/main/java/com/azure/ai/voicelive/models/FileSearchResult.java","src/main/java/com/azure/ai/voicelive/models/FunctionCallItem.java","src/main/java/com/azure/ai/voicelive/models/FunctionCallOutputItem.java","src/main/java/com/azure/ai/voicelive/models/IceServer.java","src/main/java/com/azure/ai/voicelive/models/InputAudioContentPart.java","src/main/java/com/azure/ai/voicelive/models/InputAudioFormat.java","src/main/java/com/azure/ai/voicelive/models/InputTextContentPart.java","src/main/java/com/azure/ai/voicelive/models/InputTokenDetails.java","src/main/java/com/azure/ai/voicelive/models/InteractionModality.java","src/main/java/com/azure/ai/voicelive/models/InterimResponseConfigBase.java","src/main/java/com/azure/ai/voicelive/models/InterimResponseConfigType.java","src/main/java/com/azure/ai/voicelive/models/InterimResponseTrigger.java","src/main/java/com/azure/ai/voicelive/models/ItemParamStatus.java","src/main/java/com/azure/ai/voicelive/models/ItemType.java","src/main/java/com/azure/ai/voicelive/models/LlmInterimResponseConfig.java","src/main/java/com/azure/ai/voicelive/models/LogProbProperties.java","src/main/java/com/azure/ai/voicelive/models/McpApprovalResponseRequestItem.java","src/main/java/com/azure/ai/voicelive/models/McpApprovalType.java","src/main/java/com/azure/ai/voicelive/models/McpServer.java","src/main/java/com/azure/ai/voicelive/models/McpTool.java","src/main/java/com/azure/ai/voicelive/models/MessageContentPart.java","src/main/java/com/azure/ai/voicelive/models/MessageItem.java","src/main/java/com/azure/ai/voicelive/models/OpenAIVoice.java","src/main/java/com/azure/ai/voicelive/models/OpenAIVoiceName.java","src/main/java/com/azure/ai/voicelive/models/OutputAudioFormat.java","src/main/java/com/azure/ai/voicelive/models/OutputTextContentPart.java","src/main/java/com/azure/ai/voicelive/models/OutputTokenDetails.java","src/main/java/com/azure/ai/voicelive/models/PersonalVoiceModels.java","src/main/java/com/azure/ai/voicelive/models/PhotoAvatarBaseModes.java","src/main/java/com/azure/ai/voicelive/models/ReasoningEffort.java","src/main/java/com/azure/ai/voicelive/models/RequestAudioContentPart.java","src/main/java/com/azure/ai/voicelive/models/RequestImageContentPart.java","src/main/java/com/azure/ai/voicelive/models/RequestImageContentPartDetail.java","src/main/java/com/azure/ai/voicelive/models/RequestTextContentPart.java","src/main/java/com/azure/ai/voicelive/models/RespondingAgentOptions.java","src/main/java/com/azure/ai/voicelive/models/ResponseAudioContentPart.java","src/main/java/com/azure/ai/voicelive/models/ResponseCancelledDetails.java","src/main/java/com/azure/ai/voicelive/models/ResponseCancelledDetailsReason.java","src/main/java/com/azure/ai/voicelive/models/ResponseCreateParams.java","src/main/java/com/azure/ai/voicelive/models/ResponseFailedDetails.java","src/main/java/com/azure/ai/voicelive/models/ResponseFileSearchCallItem.java","src/main/java/com/azure/ai/voicelive/models/ResponseFileSearchCallItemStatus.java","src/main/java/com/azure/ai/voicelive/models/ResponseFunctionCallItem.java","src/main/java/com/azure/ai/voicelive/models/ResponseFunctionCallOutputItem.java","src/main/java/com/azure/ai/voicelive/models/ResponseIncompleteDetails.java","src/main/java/com/azure/ai/voicelive/models/ResponseIncompleteDetailsReason.java","src/main/java/com/azure/ai/voicelive/models/ResponseItemObject.java","src/main/java/com/azure/ai/voicelive/models/ResponseMcpApprovalRequestItem.java","src/main/java/com/azure/ai/voicelive/models/ResponseMcpApprovalResponseItem.java","src/main/java/com/azure/ai/voicelive/models/ResponseMcpCallItem.java","src/main/java/com/azure/ai/voicelive/models/ResponseMcpListToolItem.java","src/main/java/com/azure/ai/voicelive/models/ResponseMessageRole.java","src/main/java/com/azure/ai/voicelive/models/ResponseObject.java","src/main/java/com/azure/ai/voicelive/models/ResponseStatusDetails.java","src/main/java/com/azure/ai/voicelive/models/ResponseTextContentPart.java","src/main/java/com/azure/ai/voicelive/models/ResponseTokenStatistics.java","src/main/java/com/azure/ai/voicelive/models/ResponseWebSearchCallItem.java","src/main/java/com/azure/ai/voicelive/models/ResponseWebSearchCallItemStatus.java","src/main/java/com/azure/ai/voicelive/models/RtcCallErrorDetails.java","src/main/java/com/azure/ai/voicelive/models/Scene.java","src/main/java/com/azure/ai/voicelive/models/ServerEventMcpListToolsCompleted.java","src/main/java/com/azure/ai/voicelive/models/ServerEventMcpListToolsFailed.java","src/main/java/com/azure/ai/voicelive/models/ServerEventMcpListToolsInProgress.java","src/main/java/com/azure/ai/voicelive/models/ServerEventOutputAudioBufferCleared.java","src/main/java/com/azure/ai/voicelive/models/ServerEventOutputAudioBufferStarted.java","src/main/java/com/azure/ai/voicelive/models/ServerEventOutputAudioBufferStopped.java","src/main/java/com/azure/ai/voicelive/models/ServerEventResponseAudioTranscriptAnnotationAdded.java","src/main/java/com/azure/ai/voicelive/models/ServerEventResponseFileSearchCallCompleted.java","src/main/java/com/azure/ai/voicelive/models/ServerEventResponseFileSearchCallInProgress.java","src/main/java/com/azure/ai/voicelive/models/ServerEventResponseFileSearchCallSearching.java","src/main/java/com/azure/ai/voicelive/models/ServerEventResponseInvocationDelta.java","src/main/java/com/azure/ai/voicelive/models/ServerEventResponseMcpCallArgumentsDelta.java","src/main/java/com/azure/ai/voicelive/models/ServerEventResponseMcpCallArgumentsDone.java","src/main/java/com/azure/ai/voicelive/models/ServerEventResponseMcpCallCompleted.java","src/main/java/com/azure/ai/voicelive/models/ServerEventResponseMcpCallFailed.java","src/main/java/com/azure/ai/voicelive/models/ServerEventResponseMcpCallInProgress.java","src/main/java/com/azure/ai/voicelive/models/ServerEventResponseVideoDelta.java","src/main/java/com/azure/ai/voicelive/models/ServerEventResponseWebSearchCallCompleted.java","src/main/java/com/azure/ai/voicelive/models/ServerEventResponseWebSearchCallInProgress.java","src/main/java/com/azure/ai/voicelive/models/ServerEventResponseWebSearchCallSearching.java","src/main/java/com/azure/ai/voicelive/models/ServerEventRtcCallError.java","src/main/java/com/azure/ai/voicelive/models/ServerEventRtcCallSdpCreated.java","src/main/java/com/azure/ai/voicelive/models/ServerEventSessionAvatarSwitchToIdle.java","src/main/java/com/azure/ai/voicelive/models/ServerEventSessionAvatarSwitchToSpeaking.java","src/main/java/com/azure/ai/voicelive/models/ServerEventType.java","src/main/java/com/azure/ai/voicelive/models/ServerEventWarning.java","src/main/java/com/azure/ai/voicelive/models/ServerEventWarningDetails.java","src/main/java/com/azure/ai/voicelive/models/ServerVadTurnDetection.java","src/main/java/com/azure/ai/voicelive/models/SessionClientEvent.java","src/main/java/com/azure/ai/voicelive/models/SessionIncludeOption.java","src/main/java/com/azure/ai/voicelive/models/SessionResponse.java","src/main/java/com/azure/ai/voicelive/models/SessionResponseItem.java","src/main/java/com/azure/ai/voicelive/models/SessionResponseItemStatus.java","src/main/java/com/azure/ai/voicelive/models/SessionResponseMessageItem.java","src/main/java/com/azure/ai/voicelive/models/SessionResponseStatus.java","src/main/java/com/azure/ai/voicelive/models/SessionServerEvent.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateAvatarConnecting.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateConversationItemCreated.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateConversationItemDeleted.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateConversationItemInputAudioTranscriptionCompleted.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateConversationItemInputAudioTranscriptionDelta.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateConversationItemInputAudioTranscriptionFailed.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateConversationItemRetrieved.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateConversationItemTruncated.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateError.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateErrorDetails.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateInputAudioBufferCleared.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateInputAudioBufferCommitted.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateInputAudioBufferSpeechStarted.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateInputAudioBufferSpeechStopped.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateResponseAnimationBlendshapeDelta.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateResponseAnimationBlendshapeDone.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateResponseAnimationVisemeDelta.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateResponseAnimationVisemeDone.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateResponseAudioDelta.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateResponseAudioDone.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateResponseAudioTimestampDelta.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateResponseAudioTimestampDone.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateResponseAudioTranscriptDelta.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateResponseAudioTranscriptDone.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateResponseContentPartAdded.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateResponseContentPartDone.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateResponseCreated.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateResponseDone.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateResponseFunctionCallArgumentsDelta.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateResponseFunctionCallArgumentsDone.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateResponseOutputItemAdded.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateResponseOutputItemDone.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateResponseTextDelta.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateResponseTextDone.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateSessionCreated.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateSessionUpdated.java","src/main/java/com/azure/ai/voicelive/models/SmartEndOfTurnDetection.java","src/main/java/com/azure/ai/voicelive/models/StaticInterimResponseConfig.java","src/main/java/com/azure/ai/voicelive/models/SystemMessageItem.java","src/main/java/com/azure/ai/voicelive/models/ToolChoiceFunctionSelection.java","src/main/java/com/azure/ai/voicelive/models/ToolChoiceLiteral.java","src/main/java/com/azure/ai/voicelive/models/ToolChoiceSelection.java","src/main/java/com/azure/ai/voicelive/models/ToolType.java","src/main/java/com/azure/ai/voicelive/models/TranscriptionPhrase.java","src/main/java/com/azure/ai/voicelive/models/TranscriptionWord.java","src/main/java/com/azure/ai/voicelive/models/TurnDetection.java","src/main/java/com/azure/ai/voicelive/models/TurnDetectionType.java","src/main/java/com/azure/ai/voicelive/models/UserMessageItem.java","src/main/java/com/azure/ai/voicelive/models/VideoBackground.java","src/main/java/com/azure/ai/voicelive/models/VideoCrop.java","src/main/java/com/azure/ai/voicelive/models/VideoParams.java","src/main/java/com/azure/ai/voicelive/models/VideoParamsCodec.java","src/main/java/com/azure/ai/voicelive/models/VideoResolution.java","src/main/java/com/azure/ai/voicelive/models/VoiceLiveContentPart.java","src/main/java/com/azure/ai/voicelive/models/VoiceLiveErrorDetails.java","src/main/java/com/azure/ai/voicelive/models/VoiceLiveFunctionDefinition.java","src/main/java/com/azure/ai/voicelive/models/VoiceLiveSessionOptions.java","src/main/java/com/azure/ai/voicelive/models/VoiceLiveSessionResponse.java","src/main/java/com/azure/ai/voicelive/models/VoiceLiveToolDefinition.java","src/main/java/com/azure/ai/voicelive/models/package-info.java","src/main/java/com/azure/ai/voicelive/package-info.java","src/main/java/module-info.java"]} \ No newline at end of file +{"flavor":"azure","apiVersions":{"VoiceLive":"2026-07-15"},"crossLanguagePackageId":"VoiceLive","crossLanguageVersion":"e710d3387810","crossLanguageDefinitions":{"com.azure.ai.voicelive.models.AnimationOptions":"VoiceLive.Animation","com.azure.ai.voicelive.models.AnimationOutputType":"VoiceLive.AnimationOutputType","com.azure.ai.voicelive.models.AssistantMessageItem":"VoiceLive.AssistantMessageItem","com.azure.ai.voicelive.models.AudioEchoCancellation":"VoiceLive.AudioEchoCancellation","com.azure.ai.voicelive.models.AudioInputTranscriptionOptions":"VoiceLive.AudioInputTranscriptionOptions","com.azure.ai.voicelive.models.AudioInputTranscriptionOptionsModel":"VoiceLive.AudioInputTranscriptionOptions.model.anonymous","com.azure.ai.voicelive.models.AudioNoiseReduction":"VoiceLive.AudioNoiseReduction","com.azure.ai.voicelive.models.AudioNoiseReductionType":"VoiceLive.AudioNoiseReduction.type.anonymous","com.azure.ai.voicelive.models.AudioTimestampType":"VoiceLive.AudioTimestampType","com.azure.ai.voicelive.models.AvatarConfigTypes":"VoiceLive.AvatarConfigTypes","com.azure.ai.voicelive.models.AvatarOptions":"VoiceLive.AvatarConfig","com.azure.ai.voicelive.models.AvatarOutputProtocol":"VoiceLive.AvatarOutputProtocol","com.azure.ai.voicelive.models.AzureAvatarVoiceSyncVoice":"VoiceLive.AzureAvatarVoiceSyncVoice","com.azure.ai.voicelive.models.AzureCustomVoice":"VoiceLive.AzureCustomVoice","com.azure.ai.voicelive.models.AzurePersonalVoice":"VoiceLive.AzurePersonalVoice","com.azure.ai.voicelive.models.AzureRealtimeNativeVoice":"VoiceLive.AzureRealtimeNativeVoice","com.azure.ai.voicelive.models.AzureRealtimeNativeVoiceName":"VoiceLive.AzureRealtimeNativeVoiceName","com.azure.ai.voicelive.models.AzureSemanticEouDetection":"VoiceLive.AzureSemanticDetection","com.azure.ai.voicelive.models.AzureSemanticEouDetectionEn":"VoiceLive.AzureSemanticDetectionEn","com.azure.ai.voicelive.models.AzureSemanticEouDetectionMultilingual":"VoiceLive.AzureSemanticDetectionMultilingual","com.azure.ai.voicelive.models.AzureSemanticVadTurnDetection":"VoiceLive.AzureSemanticVad","com.azure.ai.voicelive.models.AzureSemanticVadTurnDetectionEn":"VoiceLive.AzureSemanticVadEn","com.azure.ai.voicelive.models.AzureSemanticVadTurnDetectionMultilingual":"VoiceLive.AzureSemanticVadMultilingual","com.azure.ai.voicelive.models.AzureStandardVoice":"VoiceLive.AzureStandardVoice","com.azure.ai.voicelive.models.AzureVoice":"VoiceLive.AzureVoice","com.azure.ai.voicelive.models.AzureVoiceType":"VoiceLive.AzureVoiceType","com.azure.ai.voicelive.models.CachedTokenDetails":"VoiceLive.CachedTokenDetails","com.azure.ai.voicelive.models.ClientEventConversationItemCreate":"VoiceLive.ClientEventConversationItemCreate","com.azure.ai.voicelive.models.ClientEventConversationItemDelete":"VoiceLive.ClientEventConversationItemDelete","com.azure.ai.voicelive.models.ClientEventConversationItemRetrieve":"VoiceLive.ClientEventConversationItemRetrieve","com.azure.ai.voicelive.models.ClientEventConversationItemTruncate":"VoiceLive.ClientEventConversationItemTruncate","com.azure.ai.voicelive.models.ClientEventInputAudioBufferAppend":"VoiceLive.ClientEventInputAudioBufferAppend","com.azure.ai.voicelive.models.ClientEventInputAudioBufferClear":"VoiceLive.ClientEventInputAudioBufferClear","com.azure.ai.voicelive.models.ClientEventInputAudioBufferCommit":"VoiceLive.ClientEventInputAudioBufferCommit","com.azure.ai.voicelive.models.ClientEventInputAudioClear":"VoiceLive.ClientEventInputAudioClear","com.azure.ai.voicelive.models.ClientEventInputAudioTurnAppend":"VoiceLive.ClientEventInputAudioTurnAppend","com.azure.ai.voicelive.models.ClientEventInputAudioTurnCancel":"VoiceLive.ClientEventInputAudioTurnCancel","com.azure.ai.voicelive.models.ClientEventInputAudioTurnEnd":"VoiceLive.ClientEventInputAudioTurnEnd","com.azure.ai.voicelive.models.ClientEventInputAudioTurnStart":"VoiceLive.ClientEventInputAudioTurnStart","com.azure.ai.voicelive.models.ClientEventInputTextDelta":"VoiceLive.ClientEventInputTextDelta","com.azure.ai.voicelive.models.ClientEventInputTextDone":"VoiceLive.ClientEventInputTextDone","com.azure.ai.voicelive.models.ClientEventOutputAudioBufferClear":"VoiceLive.ClientEventOutputAudioBufferClear","com.azure.ai.voicelive.models.ClientEventResponseCancel":"VoiceLive.ClientEventResponseCancel","com.azure.ai.voicelive.models.ClientEventResponseCreate":"VoiceLive.ClientEventResponseCreate","com.azure.ai.voicelive.models.ClientEventSessionAvatarConnect":"VoiceLive.ClientEventSessionAvatarConnect","com.azure.ai.voicelive.models.ClientEventSessionUpdate":"VoiceLive.ClientEventSessionUpdate","com.azure.ai.voicelive.models.ClientEventType":"VoiceLive.ClientEventType","com.azure.ai.voicelive.models.ContentPartType":"VoiceLive.ContentPartType","com.azure.ai.voicelive.models.ConversationRequestItem":"VoiceLive.ConversationRequestItem","com.azure.ai.voicelive.models.EchoCancellationReferenceSource":"VoiceLive.EchoCancellationReferenceSource","com.azure.ai.voicelive.models.EouDetection":"VoiceLive.EouDetection","com.azure.ai.voicelive.models.EouDetectionModel":"VoiceLive.EouDetection.model.anonymous","com.azure.ai.voicelive.models.EouThresholdLevel":"VoiceLive.EouThresholdLevel","com.azure.ai.voicelive.models.FileSearchResult":"VoiceLive.FileSearchResult","com.azure.ai.voicelive.models.FunctionCallItem":"VoiceLive.FunctionCallItem","com.azure.ai.voicelive.models.FunctionCallOutputItem":"VoiceLive.FunctionCallOutputItem","com.azure.ai.voicelive.models.IceServer":"VoiceLive.IceServer","com.azure.ai.voicelive.models.InputAudioContentPart":"VoiceLive.InputAudioContentPart","com.azure.ai.voicelive.models.InputAudioFormat":"VoiceLive.InputAudioFormat","com.azure.ai.voicelive.models.InputTextContentPart":"VoiceLive.InputTextContentPart","com.azure.ai.voicelive.models.InputTokenDetails":"VoiceLive.InputTokenDetails","com.azure.ai.voicelive.models.InteractionModality":"VoiceLive.Modality","com.azure.ai.voicelive.models.InterimResponseConfigBase":"VoiceLive.InterimResponseConfigBase","com.azure.ai.voicelive.models.InterimResponseConfigType":"VoiceLive.InterimResponseConfigType","com.azure.ai.voicelive.models.InterimResponseTrigger":"VoiceLive.InterimResponseTrigger","com.azure.ai.voicelive.models.ItemParamStatus":"VoiceLive.ItemParamStatus","com.azure.ai.voicelive.models.ItemType":"VoiceLive.ItemType","com.azure.ai.voicelive.models.LlmInterimResponseConfig":"VoiceLive.LlmInterimResponseConfig","com.azure.ai.voicelive.models.LogProbProperties":"VoiceLive.LogProbProperties","com.azure.ai.voicelive.models.McpApprovalResponseRequestItem":"VoiceLive.MCPApprovalResponseRequestItem","com.azure.ai.voicelive.models.McpApprovalType":"VoiceLive.MCPApprovalType","com.azure.ai.voicelive.models.McpServer":"VoiceLive.MCPServer","com.azure.ai.voicelive.models.McpTool":"VoiceLive.MCPTool","com.azure.ai.voicelive.models.MessageContentPart":"VoiceLive.MessageContentPart","com.azure.ai.voicelive.models.MessageItem":"VoiceLive.MessageItem","com.azure.ai.voicelive.models.OpenAIVoice":"VoiceLive.OpenAIVoice","com.azure.ai.voicelive.models.OpenAIVoiceName":"VoiceLive.OAIVoice","com.azure.ai.voicelive.models.OutputAudioFormat":"VoiceLive.OutputAudioFormat","com.azure.ai.voicelive.models.OutputTextContentPart":"VoiceLive.OutputTextContentPart","com.azure.ai.voicelive.models.OutputTokenDetails":"VoiceLive.OutputTokenDetails","com.azure.ai.voicelive.models.PersonalVoiceModels":"VoiceLive.PersonalVoiceModels","com.azure.ai.voicelive.models.PhotoAvatarBaseModes":"VoiceLive.PhotoAvatarBaseModes","com.azure.ai.voicelive.models.ReasoningEffort":"VoiceLive.ReasoningEffort","com.azure.ai.voicelive.models.RequestAudioContentPart":"VoiceLive.RequestAudioContentPart","com.azure.ai.voicelive.models.RequestImageContentPart":"VoiceLive.RequestImageContentPart","com.azure.ai.voicelive.models.RequestImageContentPartDetail":"VoiceLive.RequestImageContentPartDetail","com.azure.ai.voicelive.models.RequestTextContentPart":"VoiceLive.RequestTextContentPart","com.azure.ai.voicelive.models.RespondingAgentOptions":"VoiceLive.AgentConfig","com.azure.ai.voicelive.models.ResponseAudioContentPart":"VoiceLive.ResponseAudioContentPart","com.azure.ai.voicelive.models.ResponseCancelledDetails":"VoiceLive.ResponseCancelledDetails","com.azure.ai.voicelive.models.ResponseCancelledDetailsReason":"VoiceLive.ResponseCancelledDetails.reason.anonymous","com.azure.ai.voicelive.models.ResponseCreateParams":"VoiceLive.ResponseCreateParams","com.azure.ai.voicelive.models.ResponseFailedDetails":"VoiceLive.ResponseFailedDetails","com.azure.ai.voicelive.models.ResponseFileSearchCallItem":"VoiceLive.ResponseFileSearchCallItem","com.azure.ai.voicelive.models.ResponseFileSearchCallItemStatus":"VoiceLive.ResponseFileSearchCallItem.status.anonymous","com.azure.ai.voicelive.models.ResponseFunctionCallItem":"VoiceLive.ResponseFunctionCallItem","com.azure.ai.voicelive.models.ResponseFunctionCallOutputItem":"VoiceLive.ResponseFunctionCallOutputItem","com.azure.ai.voicelive.models.ResponseIncompleteDetails":"VoiceLive.ResponseIncompleteDetails","com.azure.ai.voicelive.models.ResponseIncompleteDetailsReason":"VoiceLive.ResponseIncompleteDetails.reason.anonymous","com.azure.ai.voicelive.models.ResponseItemObject":null,"com.azure.ai.voicelive.models.ResponseMcpApprovalRequestItem":"VoiceLive.ResponseMCPApprovalRequestItem","com.azure.ai.voicelive.models.ResponseMcpApprovalResponseItem":"VoiceLive.ResponseMCPApprovalResponseItem","com.azure.ai.voicelive.models.ResponseMcpCallItem":"VoiceLive.ResponseMCPCallItem","com.azure.ai.voicelive.models.ResponseMcpListToolItem":"VoiceLive.ResponseMCPListToolItem","com.azure.ai.voicelive.models.ResponseMessageRole":"VoiceLive.MessageRole","com.azure.ai.voicelive.models.ResponseObject":null,"com.azure.ai.voicelive.models.ResponseStatusDetails":"VoiceLive.ResponseStatusDetails","com.azure.ai.voicelive.models.ResponseTextContentPart":"VoiceLive.ResponseTextContentPart","com.azure.ai.voicelive.models.ResponseTokenStatistics":"VoiceLive.TokenUsage","com.azure.ai.voicelive.models.ResponseWebSearchCallItem":"VoiceLive.ResponseWebSearchCallItem","com.azure.ai.voicelive.models.ResponseWebSearchCallItemStatus":"VoiceLive.ResponseWebSearchCallItem.status.anonymous","com.azure.ai.voicelive.models.Scene":"VoiceLive.Scene","com.azure.ai.voicelive.models.ServerEventMcpListToolsCompleted":"VoiceLive.ServerEventMcpListToolsCompleted","com.azure.ai.voicelive.models.ServerEventMcpListToolsFailed":"VoiceLive.ServerEventMcpListToolsFailed","com.azure.ai.voicelive.models.ServerEventMcpListToolsInProgress":"VoiceLive.ServerEventMcpListToolsInProgress","com.azure.ai.voicelive.models.ServerEventOutputAudioBufferCleared":"VoiceLive.ServerEventOutputAudioBufferCleared","com.azure.ai.voicelive.models.ServerEventResponseAudioTranscriptAnnotationAdded":"VoiceLive.ServerEventResponseAudioTranscriptAnnotationAdded","com.azure.ai.voicelive.models.ServerEventResponseFileSearchCallCompleted":"VoiceLive.ServerEventResponseFileSearchCallCompleted","com.azure.ai.voicelive.models.ServerEventResponseFileSearchCallInProgress":"VoiceLive.ServerEventResponseFileSearchCallInProgress","com.azure.ai.voicelive.models.ServerEventResponseFileSearchCallSearching":"VoiceLive.ServerEventResponseFileSearchCallSearching","com.azure.ai.voicelive.models.ServerEventResponseInvocationDelta":"VoiceLive.ServerEventResponseInvocationDelta","com.azure.ai.voicelive.models.ServerEventResponseMcpCallArgumentsDelta":"VoiceLive.ServerEventResponseMcpCallArgumentsDelta","com.azure.ai.voicelive.models.ServerEventResponseMcpCallArgumentsDone":"VoiceLive.ServerEventResponseMcpCallArgumentsDone","com.azure.ai.voicelive.models.ServerEventResponseMcpCallCompleted":"VoiceLive.ServerEventResponseMcpCallCompleted","com.azure.ai.voicelive.models.ServerEventResponseMcpCallFailed":"VoiceLive.ServerEventResponseMcpCallFailed","com.azure.ai.voicelive.models.ServerEventResponseMcpCallInProgress":"VoiceLive.ServerEventResponseMcpCallInProgress","com.azure.ai.voicelive.models.ServerEventResponseVideoDelta":"VoiceLive.ServerEventResponseVideoDelta","com.azure.ai.voicelive.models.ServerEventResponseWebSearchCallCompleted":"VoiceLive.ServerEventResponseWebSearchCallCompleted","com.azure.ai.voicelive.models.ServerEventResponseWebSearchCallInProgress":"VoiceLive.ServerEventResponseWebSearchCallInProgress","com.azure.ai.voicelive.models.ServerEventResponseWebSearchCallSearching":"VoiceLive.ServerEventResponseWebSearchCallSearching","com.azure.ai.voicelive.models.ServerEventSessionAvatarSwitchToIdle":"VoiceLive.ServerEventSessionAvatarSwitchToIdle","com.azure.ai.voicelive.models.ServerEventSessionAvatarSwitchToSpeaking":"VoiceLive.ServerEventSessionAvatarSwitchToSpeaking","com.azure.ai.voicelive.models.ServerEventType":"VoiceLive.ServerEventType","com.azure.ai.voicelive.models.ServerEventWarning":"VoiceLive.ServerEventWarning","com.azure.ai.voicelive.models.ServerEventWarningDetails":"VoiceLive.ServerEventWarningDetails","com.azure.ai.voicelive.models.ServerVadTurnDetection":"VoiceLive.ServerVad","com.azure.ai.voicelive.models.SessionClientEvent":"VoiceLive.ClientEvent","com.azure.ai.voicelive.models.SessionIncludeOption":"VoiceLive.SessionIncludeOption","com.azure.ai.voicelive.models.SessionResponse":"VoiceLive.Response","com.azure.ai.voicelive.models.SessionResponseItem":"VoiceLive.ResponseItem","com.azure.ai.voicelive.models.SessionResponseItemStatus":"VoiceLive.ResponseItemStatus","com.azure.ai.voicelive.models.SessionResponseMessageItem":"VoiceLive.ResponseMessageItem","com.azure.ai.voicelive.models.SessionResponseStatus":"VoiceLive.ResponseStatus","com.azure.ai.voicelive.models.SessionServerEvent":"VoiceLive.ServerEvent","com.azure.ai.voicelive.models.SessionUpdateAvatarConnecting":"VoiceLive.ServerEventSessionAvatarConnecting","com.azure.ai.voicelive.models.SessionUpdateConversationItemCreated":"VoiceLive.ServerEventConversationItemCreated","com.azure.ai.voicelive.models.SessionUpdateConversationItemDeleted":"VoiceLive.ServerEventConversationItemDeleted","com.azure.ai.voicelive.models.SessionUpdateConversationItemInputAudioTranscriptionCompleted":"VoiceLive.ServerEventConversationItemInputAudioTranscriptionCompleted","com.azure.ai.voicelive.models.SessionUpdateConversationItemInputAudioTranscriptionDelta":"VoiceLive.ServerEventConversationItemInputAudioTranscriptionDelta","com.azure.ai.voicelive.models.SessionUpdateConversationItemInputAudioTranscriptionFailed":"VoiceLive.ServerEventConversationItemInputAudioTranscriptionFailed","com.azure.ai.voicelive.models.SessionUpdateConversationItemRetrieved":"VoiceLive.ServerEventConversationItemRetrieved","com.azure.ai.voicelive.models.SessionUpdateConversationItemTruncated":"VoiceLive.ServerEventConversationItemTruncated","com.azure.ai.voicelive.models.SessionUpdateError":"VoiceLive.ServerEventError","com.azure.ai.voicelive.models.SessionUpdateErrorDetails":"VoiceLive.ServerEventErrorDetails","com.azure.ai.voicelive.models.SessionUpdateInputAudioBufferCleared":"VoiceLive.ServerEventInputAudioBufferCleared","com.azure.ai.voicelive.models.SessionUpdateInputAudioBufferCommitted":"VoiceLive.ServerEventInputAudioBufferCommitted","com.azure.ai.voicelive.models.SessionUpdateInputAudioBufferSpeechStarted":"VoiceLive.ServerEventInputAudioBufferSpeechStarted","com.azure.ai.voicelive.models.SessionUpdateInputAudioBufferSpeechStopped":"VoiceLive.ServerEventInputAudioBufferSpeechStopped","com.azure.ai.voicelive.models.SessionUpdateResponseAnimationBlendshapeDelta":"VoiceLive.ServerEventResponseAnimationBlendshapeDelta","com.azure.ai.voicelive.models.SessionUpdateResponseAnimationBlendshapeDone":"VoiceLive.ServerEventResponseAnimationBlendshapeDone","com.azure.ai.voicelive.models.SessionUpdateResponseAnimationVisemeDelta":"VoiceLive.ServerEventResponseAnimationVisemeDelta","com.azure.ai.voicelive.models.SessionUpdateResponseAnimationVisemeDone":"VoiceLive.ServerEventResponseAnimationVisemeDone","com.azure.ai.voicelive.models.SessionUpdateResponseAudioDelta":"VoiceLive.ServerEventResponseAudioDelta","com.azure.ai.voicelive.models.SessionUpdateResponseAudioDone":"VoiceLive.ServerEventResponseAudioDone","com.azure.ai.voicelive.models.SessionUpdateResponseAudioTimestampDelta":"VoiceLive.ServerEventResponseAudioTimestampDelta","com.azure.ai.voicelive.models.SessionUpdateResponseAudioTimestampDone":"VoiceLive.ServerEventResponseAudioTimestampDone","com.azure.ai.voicelive.models.SessionUpdateResponseAudioTranscriptDelta":"VoiceLive.ServerEventResponseAudioTranscriptDelta","com.azure.ai.voicelive.models.SessionUpdateResponseAudioTranscriptDone":"VoiceLive.ServerEventResponseAudioTranscriptDone","com.azure.ai.voicelive.models.SessionUpdateResponseContentPartAdded":"VoiceLive.ServerEventResponseContentPartAdded","com.azure.ai.voicelive.models.SessionUpdateResponseContentPartDone":"VoiceLive.ServerEventResponseContentPartDone","com.azure.ai.voicelive.models.SessionUpdateResponseCreated":"VoiceLive.ServerEventResponseCreated","com.azure.ai.voicelive.models.SessionUpdateResponseDone":"VoiceLive.ServerEventResponseDone","com.azure.ai.voicelive.models.SessionUpdateResponseFunctionCallArgumentsDelta":"VoiceLive.ServerEventResponseFunctionCallArgumentsDelta","com.azure.ai.voicelive.models.SessionUpdateResponseFunctionCallArgumentsDone":"VoiceLive.ServerEventResponseFunctionCallArgumentsDone","com.azure.ai.voicelive.models.SessionUpdateResponseOutputItemAdded":"VoiceLive.ServerEventResponseOutputItemAdded","com.azure.ai.voicelive.models.SessionUpdateResponseOutputItemDone":"VoiceLive.ServerEventResponseOutputItemDone","com.azure.ai.voicelive.models.SessionUpdateResponseTextDelta":"VoiceLive.ServerEventResponseTextDelta","com.azure.ai.voicelive.models.SessionUpdateResponseTextDone":"VoiceLive.ServerEventResponseTextDone","com.azure.ai.voicelive.models.SessionUpdateSessionCreated":"VoiceLive.ServerEventSessionCreated","com.azure.ai.voicelive.models.SessionUpdateSessionUpdated":"VoiceLive.ServerEventSessionUpdated","com.azure.ai.voicelive.models.StaticInterimResponseConfig":"VoiceLive.StaticInterimResponseConfig","com.azure.ai.voicelive.models.SystemMessageItem":"VoiceLive.SystemMessageItem","com.azure.ai.voicelive.models.ToolChoiceFunctionSelection":"VoiceLive.ToolChoiceFunctionObject","com.azure.ai.voicelive.models.ToolChoiceLiteral":"VoiceLive.ToolChoiceLiteral","com.azure.ai.voicelive.models.ToolChoiceSelection":"VoiceLive.ToolChoiceObject","com.azure.ai.voicelive.models.ToolType":"VoiceLive.ToolType","com.azure.ai.voicelive.models.TranscriptionPhrase":"VoiceLive.TranscriptionPhrase","com.azure.ai.voicelive.models.TranscriptionWord":"VoiceLive.TranscriptionWord","com.azure.ai.voicelive.models.TurnDetection":"VoiceLive.TurnDetection","com.azure.ai.voicelive.models.TurnDetectionType":"VoiceLive.TurnDetectionType","com.azure.ai.voicelive.models.UserMessageItem":"VoiceLive.UserMessageItem","com.azure.ai.voicelive.models.VideoBackground":"VoiceLive.Background","com.azure.ai.voicelive.models.VideoCrop":"VoiceLive.VideoCrop","com.azure.ai.voicelive.models.VideoParams":"VoiceLive.VideoParams","com.azure.ai.voicelive.models.VideoParamsCodec":null,"com.azure.ai.voicelive.models.VideoResolution":"VoiceLive.VideoResolution","com.azure.ai.voicelive.models.VoiceLiveContentPart":"VoiceLive.ContentPart","com.azure.ai.voicelive.models.VoiceLiveErrorDetails":"VoiceLive.VoiceLiveErrorDetails","com.azure.ai.voicelive.models.VoiceLiveFunctionDefinition":"VoiceLive.FunctionTool","com.azure.ai.voicelive.models.VoiceLiveSessionOptions":"VoiceLive.RequestSession","com.azure.ai.voicelive.models.VoiceLiveSessionResponse":"VoiceLive.ResponseSession","com.azure.ai.voicelive.models.VoiceLiveToolDefinition":"VoiceLive.Tool"},"generatedFiles":["src/main/java/com/azure/ai/voicelive/implementation/package-info.java","src/main/java/com/azure/ai/voicelive/models/AnimationOptions.java","src/main/java/com/azure/ai/voicelive/models/AnimationOutputType.java","src/main/java/com/azure/ai/voicelive/models/AssistantMessageItem.java","src/main/java/com/azure/ai/voicelive/models/AudioEchoCancellation.java","src/main/java/com/azure/ai/voicelive/models/AudioInputTranscriptionOptions.java","src/main/java/com/azure/ai/voicelive/models/AudioInputTranscriptionOptionsModel.java","src/main/java/com/azure/ai/voicelive/models/AudioNoiseReduction.java","src/main/java/com/azure/ai/voicelive/models/AudioNoiseReductionType.java","src/main/java/com/azure/ai/voicelive/models/AudioTimestampType.java","src/main/java/com/azure/ai/voicelive/models/AvatarConfigTypes.java","src/main/java/com/azure/ai/voicelive/models/AvatarOptions.java","src/main/java/com/azure/ai/voicelive/models/AvatarOutputProtocol.java","src/main/java/com/azure/ai/voicelive/models/AzureAvatarVoiceSyncVoice.java","src/main/java/com/azure/ai/voicelive/models/AzureCustomVoice.java","src/main/java/com/azure/ai/voicelive/models/AzurePersonalVoice.java","src/main/java/com/azure/ai/voicelive/models/AzureRealtimeNativeVoice.java","src/main/java/com/azure/ai/voicelive/models/AzureRealtimeNativeVoiceName.java","src/main/java/com/azure/ai/voicelive/models/AzureSemanticEouDetection.java","src/main/java/com/azure/ai/voicelive/models/AzureSemanticEouDetectionEn.java","src/main/java/com/azure/ai/voicelive/models/AzureSemanticEouDetectionMultilingual.java","src/main/java/com/azure/ai/voicelive/models/AzureSemanticVadTurnDetection.java","src/main/java/com/azure/ai/voicelive/models/AzureSemanticVadTurnDetectionEn.java","src/main/java/com/azure/ai/voicelive/models/AzureSemanticVadTurnDetectionMultilingual.java","src/main/java/com/azure/ai/voicelive/models/AzureStandardVoice.java","src/main/java/com/azure/ai/voicelive/models/AzureVoice.java","src/main/java/com/azure/ai/voicelive/models/AzureVoiceType.java","src/main/java/com/azure/ai/voicelive/models/CachedTokenDetails.java","src/main/java/com/azure/ai/voicelive/models/ClientEventConversationItemCreate.java","src/main/java/com/azure/ai/voicelive/models/ClientEventConversationItemDelete.java","src/main/java/com/azure/ai/voicelive/models/ClientEventConversationItemRetrieve.java","src/main/java/com/azure/ai/voicelive/models/ClientEventConversationItemTruncate.java","src/main/java/com/azure/ai/voicelive/models/ClientEventInputAudioBufferAppend.java","src/main/java/com/azure/ai/voicelive/models/ClientEventInputAudioBufferClear.java","src/main/java/com/azure/ai/voicelive/models/ClientEventInputAudioBufferCommit.java","src/main/java/com/azure/ai/voicelive/models/ClientEventInputAudioClear.java","src/main/java/com/azure/ai/voicelive/models/ClientEventInputAudioTurnAppend.java","src/main/java/com/azure/ai/voicelive/models/ClientEventInputAudioTurnCancel.java","src/main/java/com/azure/ai/voicelive/models/ClientEventInputAudioTurnEnd.java","src/main/java/com/azure/ai/voicelive/models/ClientEventInputAudioTurnStart.java","src/main/java/com/azure/ai/voicelive/models/ClientEventInputTextDelta.java","src/main/java/com/azure/ai/voicelive/models/ClientEventInputTextDone.java","src/main/java/com/azure/ai/voicelive/models/ClientEventOutputAudioBufferClear.java","src/main/java/com/azure/ai/voicelive/models/ClientEventResponseCancel.java","src/main/java/com/azure/ai/voicelive/models/ClientEventResponseCreate.java","src/main/java/com/azure/ai/voicelive/models/ClientEventSessionAvatarConnect.java","src/main/java/com/azure/ai/voicelive/models/ClientEventSessionUpdate.java","src/main/java/com/azure/ai/voicelive/models/ClientEventType.java","src/main/java/com/azure/ai/voicelive/models/ContentPartType.java","src/main/java/com/azure/ai/voicelive/models/ConversationRequestItem.java","src/main/java/com/azure/ai/voicelive/models/EchoCancellationReferenceSource.java","src/main/java/com/azure/ai/voicelive/models/EouDetection.java","src/main/java/com/azure/ai/voicelive/models/EouDetectionModel.java","src/main/java/com/azure/ai/voicelive/models/EouThresholdLevel.java","src/main/java/com/azure/ai/voicelive/models/FileSearchResult.java","src/main/java/com/azure/ai/voicelive/models/FunctionCallItem.java","src/main/java/com/azure/ai/voicelive/models/FunctionCallOutputItem.java","src/main/java/com/azure/ai/voicelive/models/IceServer.java","src/main/java/com/azure/ai/voicelive/models/InputAudioContentPart.java","src/main/java/com/azure/ai/voicelive/models/InputAudioFormat.java","src/main/java/com/azure/ai/voicelive/models/InputTextContentPart.java","src/main/java/com/azure/ai/voicelive/models/InputTokenDetails.java","src/main/java/com/azure/ai/voicelive/models/InteractionModality.java","src/main/java/com/azure/ai/voicelive/models/InterimResponseConfigBase.java","src/main/java/com/azure/ai/voicelive/models/InterimResponseConfigType.java","src/main/java/com/azure/ai/voicelive/models/InterimResponseTrigger.java","src/main/java/com/azure/ai/voicelive/models/ItemParamStatus.java","src/main/java/com/azure/ai/voicelive/models/ItemType.java","src/main/java/com/azure/ai/voicelive/models/LlmInterimResponseConfig.java","src/main/java/com/azure/ai/voicelive/models/LogProbProperties.java","src/main/java/com/azure/ai/voicelive/models/McpApprovalResponseRequestItem.java","src/main/java/com/azure/ai/voicelive/models/McpApprovalType.java","src/main/java/com/azure/ai/voicelive/models/McpServer.java","src/main/java/com/azure/ai/voicelive/models/McpTool.java","src/main/java/com/azure/ai/voicelive/models/MessageContentPart.java","src/main/java/com/azure/ai/voicelive/models/MessageItem.java","src/main/java/com/azure/ai/voicelive/models/OpenAIVoice.java","src/main/java/com/azure/ai/voicelive/models/OpenAIVoiceName.java","src/main/java/com/azure/ai/voicelive/models/OutputAudioFormat.java","src/main/java/com/azure/ai/voicelive/models/OutputTextContentPart.java","src/main/java/com/azure/ai/voicelive/models/OutputTokenDetails.java","src/main/java/com/azure/ai/voicelive/models/PersonalVoiceModels.java","src/main/java/com/azure/ai/voicelive/models/PhotoAvatarBaseModes.java","src/main/java/com/azure/ai/voicelive/models/ReasoningEffort.java","src/main/java/com/azure/ai/voicelive/models/RequestAudioContentPart.java","src/main/java/com/azure/ai/voicelive/models/RequestImageContentPart.java","src/main/java/com/azure/ai/voicelive/models/RequestImageContentPartDetail.java","src/main/java/com/azure/ai/voicelive/models/RequestTextContentPart.java","src/main/java/com/azure/ai/voicelive/models/RespondingAgentOptions.java","src/main/java/com/azure/ai/voicelive/models/ResponseAudioContentPart.java","src/main/java/com/azure/ai/voicelive/models/ResponseCancelledDetails.java","src/main/java/com/azure/ai/voicelive/models/ResponseCancelledDetailsReason.java","src/main/java/com/azure/ai/voicelive/models/ResponseCreateParams.java","src/main/java/com/azure/ai/voicelive/models/ResponseFailedDetails.java","src/main/java/com/azure/ai/voicelive/models/ResponseFileSearchCallItem.java","src/main/java/com/azure/ai/voicelive/models/ResponseFileSearchCallItemStatus.java","src/main/java/com/azure/ai/voicelive/models/ResponseFunctionCallItem.java","src/main/java/com/azure/ai/voicelive/models/ResponseFunctionCallOutputItem.java","src/main/java/com/azure/ai/voicelive/models/ResponseIncompleteDetails.java","src/main/java/com/azure/ai/voicelive/models/ResponseIncompleteDetailsReason.java","src/main/java/com/azure/ai/voicelive/models/ResponseItemObject.java","src/main/java/com/azure/ai/voicelive/models/ResponseMcpApprovalRequestItem.java","src/main/java/com/azure/ai/voicelive/models/ResponseMcpApprovalResponseItem.java","src/main/java/com/azure/ai/voicelive/models/ResponseMcpCallItem.java","src/main/java/com/azure/ai/voicelive/models/ResponseMcpListToolItem.java","src/main/java/com/azure/ai/voicelive/models/ResponseMessageRole.java","src/main/java/com/azure/ai/voicelive/models/ResponseObject.java","src/main/java/com/azure/ai/voicelive/models/ResponseStatusDetails.java","src/main/java/com/azure/ai/voicelive/models/ResponseTextContentPart.java","src/main/java/com/azure/ai/voicelive/models/ResponseTokenStatistics.java","src/main/java/com/azure/ai/voicelive/models/ResponseWebSearchCallItem.java","src/main/java/com/azure/ai/voicelive/models/ResponseWebSearchCallItemStatus.java","src/main/java/com/azure/ai/voicelive/models/Scene.java","src/main/java/com/azure/ai/voicelive/models/ServerEventMcpListToolsCompleted.java","src/main/java/com/azure/ai/voicelive/models/ServerEventMcpListToolsFailed.java","src/main/java/com/azure/ai/voicelive/models/ServerEventMcpListToolsInProgress.java","src/main/java/com/azure/ai/voicelive/models/ServerEventOutputAudioBufferCleared.java","src/main/java/com/azure/ai/voicelive/models/ServerEventResponseAudioTranscriptAnnotationAdded.java","src/main/java/com/azure/ai/voicelive/models/ServerEventResponseFileSearchCallCompleted.java","src/main/java/com/azure/ai/voicelive/models/ServerEventResponseFileSearchCallInProgress.java","src/main/java/com/azure/ai/voicelive/models/ServerEventResponseFileSearchCallSearching.java","src/main/java/com/azure/ai/voicelive/models/ServerEventResponseInvocationDelta.java","src/main/java/com/azure/ai/voicelive/models/ServerEventResponseMcpCallArgumentsDelta.java","src/main/java/com/azure/ai/voicelive/models/ServerEventResponseMcpCallArgumentsDone.java","src/main/java/com/azure/ai/voicelive/models/ServerEventResponseMcpCallCompleted.java","src/main/java/com/azure/ai/voicelive/models/ServerEventResponseMcpCallFailed.java","src/main/java/com/azure/ai/voicelive/models/ServerEventResponseMcpCallInProgress.java","src/main/java/com/azure/ai/voicelive/models/ServerEventResponseVideoDelta.java","src/main/java/com/azure/ai/voicelive/models/ServerEventResponseWebSearchCallCompleted.java","src/main/java/com/azure/ai/voicelive/models/ServerEventResponseWebSearchCallInProgress.java","src/main/java/com/azure/ai/voicelive/models/ServerEventResponseWebSearchCallSearching.java","src/main/java/com/azure/ai/voicelive/models/ServerEventSessionAvatarSwitchToIdle.java","src/main/java/com/azure/ai/voicelive/models/ServerEventSessionAvatarSwitchToSpeaking.java","src/main/java/com/azure/ai/voicelive/models/ServerEventType.java","src/main/java/com/azure/ai/voicelive/models/ServerEventWarning.java","src/main/java/com/azure/ai/voicelive/models/ServerEventWarningDetails.java","src/main/java/com/azure/ai/voicelive/models/ServerVadTurnDetection.java","src/main/java/com/azure/ai/voicelive/models/SessionClientEvent.java","src/main/java/com/azure/ai/voicelive/models/SessionIncludeOption.java","src/main/java/com/azure/ai/voicelive/models/SessionResponse.java","src/main/java/com/azure/ai/voicelive/models/SessionResponseItem.java","src/main/java/com/azure/ai/voicelive/models/SessionResponseItemStatus.java","src/main/java/com/azure/ai/voicelive/models/SessionResponseMessageItem.java","src/main/java/com/azure/ai/voicelive/models/SessionResponseStatus.java","src/main/java/com/azure/ai/voicelive/models/SessionServerEvent.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateAvatarConnecting.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateConversationItemCreated.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateConversationItemDeleted.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateConversationItemInputAudioTranscriptionCompleted.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateConversationItemInputAudioTranscriptionDelta.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateConversationItemInputAudioTranscriptionFailed.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateConversationItemRetrieved.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateConversationItemTruncated.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateError.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateErrorDetails.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateInputAudioBufferCleared.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateInputAudioBufferCommitted.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateInputAudioBufferSpeechStarted.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateInputAudioBufferSpeechStopped.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateResponseAnimationBlendshapeDelta.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateResponseAnimationBlendshapeDone.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateResponseAnimationVisemeDelta.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateResponseAnimationVisemeDone.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateResponseAudioDelta.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateResponseAudioDone.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateResponseAudioTimestampDelta.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateResponseAudioTimestampDone.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateResponseAudioTranscriptDelta.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateResponseAudioTranscriptDone.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateResponseContentPartAdded.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateResponseContentPartDone.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateResponseCreated.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateResponseDone.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateResponseFunctionCallArgumentsDelta.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateResponseFunctionCallArgumentsDone.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateResponseOutputItemAdded.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateResponseOutputItemDone.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateResponseTextDelta.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateResponseTextDone.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateSessionCreated.java","src/main/java/com/azure/ai/voicelive/models/SessionUpdateSessionUpdated.java","src/main/java/com/azure/ai/voicelive/models/StaticInterimResponseConfig.java","src/main/java/com/azure/ai/voicelive/models/SystemMessageItem.java","src/main/java/com/azure/ai/voicelive/models/ToolChoiceFunctionSelection.java","src/main/java/com/azure/ai/voicelive/models/ToolChoiceLiteral.java","src/main/java/com/azure/ai/voicelive/models/ToolChoiceSelection.java","src/main/java/com/azure/ai/voicelive/models/ToolType.java","src/main/java/com/azure/ai/voicelive/models/TranscriptionPhrase.java","src/main/java/com/azure/ai/voicelive/models/TranscriptionWord.java","src/main/java/com/azure/ai/voicelive/models/TurnDetection.java","src/main/java/com/azure/ai/voicelive/models/TurnDetectionType.java","src/main/java/com/azure/ai/voicelive/models/UserMessageItem.java","src/main/java/com/azure/ai/voicelive/models/VideoBackground.java","src/main/java/com/azure/ai/voicelive/models/VideoCrop.java","src/main/java/com/azure/ai/voicelive/models/VideoParams.java","src/main/java/com/azure/ai/voicelive/models/VideoParamsCodec.java","src/main/java/com/azure/ai/voicelive/models/VideoResolution.java","src/main/java/com/azure/ai/voicelive/models/VoiceLiveContentPart.java","src/main/java/com/azure/ai/voicelive/models/VoiceLiveErrorDetails.java","src/main/java/com/azure/ai/voicelive/models/VoiceLiveFunctionDefinition.java","src/main/java/com/azure/ai/voicelive/models/VoiceLiveSessionOptions.java","src/main/java/com/azure/ai/voicelive/models/VoiceLiveSessionResponse.java","src/main/java/com/azure/ai/voicelive/models/VoiceLiveToolDefinition.java","src/main/java/com/azure/ai/voicelive/models/package-info.java","src/main/java/com/azure/ai/voicelive/package-info.java","src/main/java/module-info.java"]} \ No newline at end of file diff --git a/sdk/voicelive/azure-ai-voicelive/src/samples/java/com/azure/ai/voicelive/AgentV2Sample.java b/sdk/voicelive/azure-ai-voicelive/src/samples/java/com/azure/ai/voicelive/AgentV2Sample.java index 80db8de02a96..807a2bea659a 100644 --- a/sdk/voicelive/azure-ai-voicelive/src/samples/java/com/azure/ai/voicelive/AgentV2Sample.java +++ b/sdk/voicelive/azure-ai-voicelive/src/samples/java/com/azure/ai/voicelive/AgentV2Sample.java @@ -235,7 +235,7 @@ void start() { // Create the VoiceLive client using DefaultAzureCredential (Entra ID). VoiceLiveAsyncClient client = new VoiceLiveClientBuilder() .endpoint(endpoint) - .serviceVersion(VoiceLiveServiceVersion.V2026_04_10) + .serviceVersion(VoiceLiveServiceVersion.V2026_07_15) .credential(new DefaultAzureCredentialBuilder().build()) .buildAsyncClient(); diff --git a/sdk/voicelive/azure-ai-voicelive/src/samples/java/com/azure/ai/voicelive/McpSample.java b/sdk/voicelive/azure-ai-voicelive/src/samples/java/com/azure/ai/voicelive/McpSample.java index d628045c5b51..948060de45d8 100644 --- a/sdk/voicelive/azure-ai-voicelive/src/samples/java/com/azure/ai/voicelive/McpSample.java +++ b/sdk/voicelive/azure-ai-voicelive/src/samples/java/com/azure/ai/voicelive/McpSample.java @@ -145,7 +145,7 @@ private static void runMcpSample(String endpoint) { // Create the VoiceLive client using DefaultAzureCredential (Entra ID). VoiceLiveAsyncClient client = new VoiceLiveClientBuilder() .endpoint(endpoint) - .serviceVersion(VoiceLiveServiceVersion.V2026_04_10) + .serviceVersion(VoiceLiveServiceVersion.V2026_07_15) .credential(new DefaultAzureCredentialBuilder().build()) .buildAsyncClient(); diff --git a/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/implementation/VoiceLiveTracerTest.java b/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/implementation/VoiceLiveTracerTest.java index 20d510aa904a..113a974995ff 100644 --- a/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/implementation/VoiceLiveTracerTest.java +++ b/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/implementation/VoiceLiveTracerTest.java @@ -53,7 +53,7 @@ void setUp() throws Exception { tracer = tracerProvider.get("azure-ai-voicelive", "1.0.0-beta.6"); Meter meter = meterProvider.get("azure-ai-voicelive"); URI endpoint = new URI("wss://test.cognitiveservices.azure.com/voice-live/realtime"); - voiceLiveTracer = new VoiceLiveTracer(tracer, meter, endpoint, "gpt-4o-realtime-preview", null); + voiceLiveTracer = new VoiceLiveTracer(tracer, meter, endpoint, "gpt-realtime", null); } @AfterEach @@ -70,7 +70,7 @@ void testConnectSpanCreated() { List spans = spanExporter.getFinishedSpanItems(); assertEquals(1, spans.size()); SpanData span = spans.get(0); - assertEquals("connect gpt-4o-realtime-preview", span.getName()); + assertEquals("connect gpt-realtime", span.getName()); assertEquals(SpanKind.CLIENT, span.getKind()); assertEquals(VoiceLiveTracer.GEN_AI_SYSTEM_VALUE, span.getAttributes().get(VoiceLiveTracer.GEN_AI_SYSTEM)); assertEquals(VoiceLiveTracer.OPERATION_CONNECT, @@ -78,7 +78,7 @@ void testConnectSpanCreated() { assertEquals(VoiceLiveTracer.AZ_NAMESPACE_VALUE, span.getAttributes().get(VoiceLiveTracer.AZ_NAMESPACE)); assertEquals(VoiceLiveTracer.GEN_AI_PROVIDER_NAME_VALUE, span.getAttributes().get(VoiceLiveTracer.GEN_AI_PROVIDER_NAME)); - assertEquals("gpt-4o-realtime-preview", span.getAttributes().get(VoiceLiveTracer.GEN_AI_REQUEST_MODEL)); + assertEquals("gpt-realtime", span.getAttributes().get(VoiceLiveTracer.GEN_AI_REQUEST_MODEL)); assertEquals("test.cognitiveservices.azure.com", span.getAttributes().get(VoiceLiveTracer.SERVER_ADDRESS)); assertEquals(443L, span.getAttributes().get(VoiceLiveTracer.SERVER_PORT).longValue()); } diff --git a/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/live/VoiceLiveTestBase.java b/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/live/VoiceLiveTestBase.java index 0b24e25e00ea..edc7dc53e5a7 100644 --- a/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/live/VoiceLiveTestBase.java +++ b/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/live/VoiceLiveTestBase.java @@ -66,7 +66,7 @@ public abstract class VoiceLiveTestBase extends TestProxyTestBase { protected static final double DEFAULT_SILENCE_DURATION = 2.0; // API versions exercised by parameterized live tests. - protected static final String[] API_VERSIONS = { "2025-10-01", "2026-04-10" }; + protected static final String[] API_VERSIONS = { "2025-10-01", "2026-07-15" }; protected String getEndpoint() { String endpoint = Configuration.getGlobalConfiguration().get("AI_SERVICES_ENDPOINT"); diff --git a/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/live/VoiceLiveToolCallTests.java b/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/live/VoiceLiveToolCallTests.java index b1f749fa5d4a..d69768315381 100644 --- a/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/live/VoiceLiveToolCallTests.java +++ b/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/live/VoiceLiveToolCallTests.java @@ -46,7 +46,7 @@ public class VoiceLiveToolCallTests extends VoiceLiveTestBase { // ===== test_realtime_service_tool_call ===== - // Python: models=[gpt-realtime, gpt-4o], api_versions=[2025-10-01, 2026-04-10] + // Python: models=[gpt-realtime, gpt-4o], api_versions=[2025-10-01, 2026-07-15] // Uses _get_speech_recognition_setting(model), audio=4-1.wav, tool=assess_pronunciation // Voice: AzureStandardVoice("en-US-AriaNeural") @@ -162,7 +162,7 @@ private void doTestRealtimeServiceToolCall(String model, String apiVersion) // ===== test_realtime_service_tool_choice ===== // Python: models=[gpt-realtime, gpt-4o, gpt-5-chat], skip if "realtime" in model // -> effective models: [gpt-4o, gpt-5-chat] - // api_versions=[2025-10-01, 2026-04-10] + // api_versions=[2025-10-01, 2026-07-15] // Uses azure-speech + ServerVad, audio=ask_weather.wav // Tools: get_weather, get_time. ToolChoice: get_time // Assert: function_done.name == "get_time", arguments contains Beijing @@ -255,7 +255,7 @@ public void testRealtimeServiceToolChoice(String model, String apiVersion) // ===== test_realtime_service_tool_call_parameter ===== // Python: models=[gpt-realtime, gpt-4.1, gpt-5, gpt-5.1, gpt-5.2, phi4-mm-realtime], // skip if "realtime" in model -> effective models: [gpt-4.1, gpt-5] - // api_versions=[2025-10-01, 2026-04-10] + // api_versions=[2025-10-01, 2026-07-15] // Uses azure-speech + ServerVad, audio=ask_weather.wav // Tool: get_weather. Full tool call flow: get function call -> send tool output -> get transcript // Assert: transcript contains "sunny" or chinese equivalent, and "25" @@ -393,7 +393,7 @@ public void testRealtimeServiceToolCallParameter(String model, String apiVersion } // ===== test_realtime_service_live_session_update ===== - // Python: model=[gpt-realtime], api_versions=[2025-10-01, 2026-04-10] + // Python: model=[gpt-realtime], api_versions=[2025-10-01, 2026-07-15] // Two-phase test: // Phase 1: Session without tools -> send audio -> expect no function call in response // Phase 2: New session with tools -> send audio -> expect function call diff --git a/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/live/VoiceLiveTranscriptionTests.java b/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/live/VoiceLiveTranscriptionTests.java index 4906d0746c8d..78a1e0c6c84f 100644 --- a/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/live/VoiceLiveTranscriptionTests.java +++ b/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/live/VoiceLiveTranscriptionTests.java @@ -35,7 +35,7 @@ public class VoiceLiveTranscriptionTests extends VoiceLiveTestBase { static Stream whisperTranscriptionParams() { - // gpt-realtime uses WHISPER_1, which the 2026-04-10 service does not emit + // gpt-realtime uses WHISPER_1, which the 2026-07-15 service does not emit // transcription.completed events for; restrict it to the GA version. gpt-4.1 // uses AZURE_SPEECH, which works on both API versions. return Stream.concat(Stream.of(Arguments.of("gpt-realtime", API_VERSIONS[0])), @@ -113,7 +113,7 @@ public void testInputAudioTranscriptionWithWhisper(String model, String apiVersi static Stream gpt4oTranscribeParams() { // gpt-4o-transcribe and gpt-4o-mini-transcribe do not emit transcription.completed - // events on the 2026-04-10 service; restrict to the GA version. + // events on the 2026-07-15 service; restrict to the GA version. return crossProduct(new String[] { "gpt-4o-transcribe", "gpt-4o-mini-transcribe" }, new String[] { API_VERSIONS[0] }); } diff --git a/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/live/VoiceLiveTurnDetectionTests.java b/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/live/VoiceLiveTurnDetectionTests.java index 1bbd843447c2..464c3be810b6 100644 --- a/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/live/VoiceLiveTurnDetectionTests.java +++ b/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/live/VoiceLiveTurnDetectionTests.java @@ -39,7 +39,7 @@ public class VoiceLiveTurnDetectionTests extends VoiceLiveTestBase { // ===== test_realtime_service_with_turn_detection_long_tts_vad_duration ===== - // Python: models=[gpt-realtime, gpt-4o], api_versions=[2025-10-01, 2026-04-10] + // Python: models=[gpt-realtime, gpt-4o], api_versions=[2025-10-01, 2026-07-15] // turn_detection: {"type": "azure_semantic_vad", "speech_duration_assistant_speaking_ms": 800} // Note: speechDurationAssistantSpeakingMs not available in Java SDK; // using speechDurationMs(800) as the closest available parameter. @@ -130,7 +130,7 @@ private void doTestLongTtsVadDuration(String model, String apiVersion) throws In } // ===== test_realtime_service_with_turn_detection_multilingual ===== - // Python: models × semanticVadParams, api_versions=[2025-10-01, 2026-04-10] + // Python: models × semanticVadParams, api_versions=[2025-10-01, 2026-07-15] // Uses AzureSemanticVadMultilingual(**semantic_vad_params) static Stream multilingualParams() { @@ -231,7 +231,7 @@ private void doTestMultilingual(String description, String model, TurnDetection // ===== test_realtime_service_with_eou ===== // Python: model=gpt-4o, turn_detection_cls × end_of_detection combinations // 6 combos: ServerVad/AzureSemanticVad/AzureSemanticVadMultilingual × AzureSemanticDetection/AzureSemanticDetectionEn - // api_versions=[2025-10-01, 2026-04-10] + // api_versions=[2025-10-01, 2026-07-15] static Stream eouParams() { return withApiVersions(Stream.of( diff --git a/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/unit/VoiceLiveAsyncClientStartSessionTest.java b/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/unit/VoiceLiveAsyncClientStartSessionTest.java index 323d24802a40..7981764a25dc 100644 --- a/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/unit/VoiceLiveAsyncClientStartSessionTest.java +++ b/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/unit/VoiceLiveAsyncClientStartSessionTest.java @@ -39,7 +39,7 @@ void setUp() { @Test void testStartSessionWithValidOptions() { // Arrange - VoiceLiveSessionOptions sessionOptions = new VoiceLiveSessionOptions().setModel("gpt-4o-realtime-preview"); + VoiceLiveSessionOptions sessionOptions = new VoiceLiveSessionOptions().setModel("gpt-realtime"); // Act & Assert // Note: This test might need to be adjusted based on actual implementation @@ -67,7 +67,7 @@ void testStartSessionWithoutModel() { @Test void testStartSessionWithModelString() { // Arrange - String model = "gpt-4o-realtime-preview"; + String model = "gpt-realtime"; // Act & Assert assertDoesNotThrow(() -> { @@ -83,7 +83,7 @@ void testStartSessionWithNullModel() { @Test void testStartSessionWithModelAndRequestOptions() { - String model = "gpt-4o-realtime-preview"; + String model = "gpt-realtime"; VoiceLiveRequestOptions requestOptions = new VoiceLiveRequestOptions(); assertDoesNotThrow(() -> { @@ -117,12 +117,12 @@ void testOptimizedConnectMethods() { // Test startSession with model string assertDoesNotThrow(() -> { - Mono result = client.startSession("gpt-4o-realtime-preview", null); + Mono result = client.startSession("gpt-realtime", null); assertNotNull(result); }); // Test startSession with session options - VoiceLiveSessionOptions sessionOptions = new VoiceLiveSessionOptions().setModel("gpt-4o-realtime-preview"); + VoiceLiveSessionOptions sessionOptions = new VoiceLiveSessionOptions().setModel("gpt-realtime"); assertDoesNotThrow(() -> { Mono result = client.startSession(sessionOptions.getModel(), null); assertNotNull(result); @@ -135,7 +135,7 @@ void testOptimizedConnectMethods() { @Test void testReturnTypeOptimization() { // Test that connect methods return the session for direct use - String model = "gpt-4o-realtime-preview"; + String model = "gpt-realtime"; assertDoesNotThrow(() -> { Mono sessionMono = client.startSession(model, null); diff --git a/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/unit/VoiceLiveClientBuilderTest.java b/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/unit/VoiceLiveClientBuilderTest.java index cef0e86464a7..5886dfce2c33 100644 --- a/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/unit/VoiceLiveClientBuilderTest.java +++ b/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/unit/VoiceLiveClientBuilderTest.java @@ -176,7 +176,7 @@ void testBuilderWithServiceVersion() { assertDoesNotThrow(() -> { VoiceLiveAsyncClient client = clientBuilder.endpoint(endpoint) .credential(mockKeyCredential) - .serviceVersion(VoiceLiveServiceVersion.V2026_04_10) + .serviceVersion(VoiceLiveServiceVersion.V2026_07_15) .buildAsyncClient(); assertNotNull(client); @@ -192,7 +192,7 @@ void testBuilderChaining() { assertDoesNotThrow(() -> { VoiceLiveAsyncClient client = clientBuilder.endpoint(endpoint) .credential(mockKeyCredential) - .serviceVersion(VoiceLiveServiceVersion.V2026_04_10) + .serviceVersion(VoiceLiveServiceVersion.V2026_07_15) .buildAsyncClient(); assertNotNull(client); @@ -204,7 +204,7 @@ void testBuilderReturnsBuilder() { // Test that all methods return the builder for chaining assertSame(clientBuilder, clientBuilder.endpoint("https://test.cognitiveservices.azure.com")); assertSame(clientBuilder, clientBuilder.credential(mockKeyCredential)); - assertSame(clientBuilder, clientBuilder.serviceVersion(VoiceLiveServiceVersion.V2026_04_10)); + assertSame(clientBuilder, clientBuilder.serviceVersion(VoiceLiveServiceVersion.V2026_07_15)); } @Test diff --git a/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/unit/VoiceLiveRequestOptionsClientTest.java b/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/unit/VoiceLiveRequestOptionsClientTest.java index 259037787cbc..63fe579ef934 100644 --- a/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/unit/VoiceLiveRequestOptionsClientTest.java +++ b/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/unit/VoiceLiveRequestOptionsClientTest.java @@ -66,15 +66,14 @@ void testConvertToWebSocketEndpointWithRequestOptions() throws Exception { VoiceLiveAsyncClient client = newClient(testEndpoint); // Act - URI result - = convert(client, testEndpoint, "gpt-4o-realtime-preview", requestOptions.getCustomQueryParameters()); + URI result = convert(client, testEndpoint, "gpt-realtime", requestOptions.getCustomQueryParameters()); // Assert assertNotNull(result); assertEquals("wss", result.getScheme()); assertNotNull(result.getQuery()); assertTrue(result.getQuery().contains("api-version=" + apiVersion)); - assertTrue(result.getQuery().contains("model=gpt-4o-realtime-preview")); + assertTrue(result.getQuery().contains("model=gpt-realtime")); assertTrue(result.getQuery().contains("deployment-id=test-deployment")); assertTrue(result.getQuery().contains("custom-param=custom-value")); } @@ -111,8 +110,7 @@ void testRequestOptionsQueryParameterPrecedence() throws Exception { VoiceLiveAsyncClient client = newClient(endpointWithQuery); // Act - URI result - = convert(client, endpointWithQuery, "gpt-4o-realtime-preview", requestOptions.getCustomQueryParameters()); + URI result = convert(client, endpointWithQuery, "gpt-realtime", requestOptions.getCustomQueryParameters()); // Assert - SDK's api-version should take precedence assertNotNull(result); diff --git a/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/unit/VoiceLiveSessionOptionsTest.java b/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/unit/VoiceLiveSessionOptionsTest.java index fc4c99778e68..b61f3d80b98e 100644 --- a/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/unit/VoiceLiveSessionOptionsTest.java +++ b/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/unit/VoiceLiveSessionOptionsTest.java @@ -33,7 +33,7 @@ class VoiceLiveSessionOptionsTest { private VoiceLiveSessionOptions sessionOptions; - private static final String TEST_MODEL = "gpt-4o-realtime-preview"; + private static final String TEST_MODEL = "gpt-realtime"; @BeforeEach void setUp() { diff --git a/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/unit/models/AvatarAndAudioBufferEventsTest.java b/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/unit/models/AvatarAndAudioBufferEventsTest.java index bac8922c36fe..c1c18c07f548 100644 --- a/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/unit/models/AvatarAndAudioBufferEventsTest.java +++ b/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/unit/models/AvatarAndAudioBufferEventsTest.java @@ -6,8 +6,6 @@ import com.azure.ai.voicelive.models.ClientEventOutputAudioBufferClear; import com.azure.ai.voicelive.models.ClientEventType; import com.azure.ai.voicelive.models.ServerEventOutputAudioBufferCleared; -import com.azure.ai.voicelive.models.ServerEventOutputAudioBufferStarted; -import com.azure.ai.voicelive.models.ServerEventOutputAudioBufferStopped; import com.azure.ai.voicelive.models.ServerEventResponseVideoDelta; import com.azure.ai.voicelive.models.ServerEventSessionAvatarSwitchToIdle; import com.azure.ai.voicelive.models.ServerEventSessionAvatarSwitchToSpeaking; @@ -173,35 +171,4 @@ void testClientEventOutputAudioBufferClearPolymorphicViaClientEvent() { assertEquals(ClientEventType.OUTPUT_AUDIO_BUFFER_CLEAR, deserialized.getType()); assertEquals("clear-3", deserialized.getEventId()); } - - @Test - void testOutputAudioBufferLifecycleTypesRegistered() { - assertEquals("output_audio_buffer.started", ServerEventType.OUTPUT_AUDIO_BUFFER_STARTED.toString()); - assertEquals("output_audio_buffer.stopped", ServerEventType.OUTPUT_AUDIO_BUFFER_STOPPED.toString()); - } - - @Test - void testServerEventOutputAudioBufferStartedPolymorphic() { - String json = "{\"type\":\"output_audio_buffer.started\",\"event_id\":\"a1\",\"response_id\":\"resp-7\"}"; - - SessionServerEvent event = BinaryData.fromString(json).toObject(SessionServerEvent.class); - - assertTrue(event instanceof ServerEventOutputAudioBufferStarted); - ServerEventOutputAudioBufferStarted started = (ServerEventOutputAudioBufferStarted) event; - assertEquals(ServerEventType.OUTPUT_AUDIO_BUFFER_STARTED, started.getType()); - assertEquals("a1", started.getEventId()); - assertEquals("resp-7", started.getResponseId()); - } - - @Test - void testServerEventOutputAudioBufferStoppedPolymorphic() { - String json = "{\"type\":\"output_audio_buffer.stopped\",\"event_id\":\"a2\",\"response_id\":\"resp-8\"}"; - - SessionServerEvent event = BinaryData.fromString(json).toObject(SessionServerEvent.class); - - assertTrue(event instanceof ServerEventOutputAudioBufferStopped); - ServerEventOutputAudioBufferStopped stopped = (ServerEventOutputAudioBufferStopped) event; - assertEquals(ServerEventType.OUTPUT_AUDIO_BUFFER_STOPPED, stopped.getType()); - assertEquals("resp-8", stopped.getResponseId()); - } } diff --git a/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/unit/models/RtcCallSdpEventsTest.java b/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/unit/models/RtcCallSdpEventsTest.java deleted file mode 100644 index ace635d55568..000000000000 --- a/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/unit/models/RtcCallSdpEventsTest.java +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -package com.azure.ai.voicelive.unit.models; - -import com.azure.ai.voicelive.models.ClientEventRtcCallSdpCreate; -import com.azure.ai.voicelive.models.ClientEventType; -import com.azure.ai.voicelive.models.RtcCallErrorDetails; -import com.azure.ai.voicelive.models.ServerEventRtcCallError; -import com.azure.ai.voicelive.models.ServerEventRtcCallSdpCreated; -import com.azure.ai.voicelive.models.ServerEventType; -import com.azure.ai.voicelive.models.SessionClientEvent; -import com.azure.ai.voicelive.models.SessionServerEvent; -import com.azure.ai.voicelive.models.VoiceLiveSessionOptions; -import com.azure.core.util.BinaryData; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; - -/** - * Unit tests for the WebRTC SDP negotiation client/server events and the related - * {@link RtcCallErrorDetails} payload. - */ -class RtcCallSdpEventsTest { - - @Test - void testRtcCallEventTypesRegistered() { - assertEquals("rtc.call.sdp.create", ClientEventType.RTC_CALL_SDP_CREATE.toString()); - assertEquals("rtc.call.sdp.created", ServerEventType.RTC_CALL_SDP_CREATED.toString()); - assertEquals("rtc.call.error", ServerEventType.RTC_CALL_ERROR.toString()); - } - - @Test - void testClientEventRtcCallSdpCreateRoundTrip() { - ClientEventRtcCallSdpCreate event = new ClientEventRtcCallSdpCreate("v=0\r\no=- 1 1 IN IP4 0.0.0.0\r\n") - .setSession(new VoiceLiveSessionOptions().setModel("gpt-4o-realtime-preview")); - event.setEventId("c1"); - - ClientEventRtcCallSdpCreate deserialized - = BinaryData.fromObject(event).toObject(ClientEventRtcCallSdpCreate.class); - - assertEquals(ClientEventType.RTC_CALL_SDP_CREATE, deserialized.getType()); - assertEquals("c1", deserialized.getEventId()); - assertEquals(event.getSdpOffer(), deserialized.getSdpOffer()); - assertNotNull(deserialized.getSession()); - assertEquals("gpt-4o-realtime-preview", deserialized.getSession().getModel()); - } - - @Test - void testClientEventRtcCallSdpCreatePolymorphicViaSessionClientEvent() { - String json = "{\"type\":\"rtc.call.sdp.create\",\"event_id\":\"c2\",\"sdp_offer\":\"v=0\"}"; - - SessionClientEvent event = BinaryData.fromString(json).toObject(SessionClientEvent.class); - - assertTrue(event instanceof ClientEventRtcCallSdpCreate, - "Expected ClientEventRtcCallSdpCreate, got " + event.getClass()); - assertEquals("v=0", ((ClientEventRtcCallSdpCreate) event).getSdpOffer()); - } - - @Test - void testServerEventRtcCallSdpCreatedDeserialization() { - String json = "{\"type\":\"rtc.call.sdp.created\",\"event_id\":\"s1\"," - + "\"rtc_call_id\":\"call-123\",\"sdp_answer\":\"v=0\\r\\no=- 2 2 IN IP4 0.0.0.0\\r\\n\"}"; - - SessionServerEvent event = BinaryData.fromString(json).toObject(SessionServerEvent.class); - - assertTrue(event instanceof ServerEventRtcCallSdpCreated); - ServerEventRtcCallSdpCreated sdpCreated = (ServerEventRtcCallSdpCreated) event; - assertEquals(ServerEventType.RTC_CALL_SDP_CREATED, sdpCreated.getType()); - assertEquals("s1", sdpCreated.getEventId()); - assertEquals("call-123", sdpCreated.getRtcCallId()); - assertTrue(sdpCreated.getSdpAnswer().startsWith("v=0")); - } - - @Test - void testServerEventRtcCallErrorDeserialization() { - String json = "{\"type\":\"rtc.call.error\",\"event_id\":\"s2\"," - + "\"operation\":\"rtc.call.sdp.create\",\"rtc_call_id\":\"call-9\"," - + "\"error\":{\"type\":\"invalid_request_error\",\"code\":\"bad_sdp\",\"message\":\"Malformed SDP\"}}"; - - SessionServerEvent event = BinaryData.fromString(json).toObject(SessionServerEvent.class); - - assertTrue(event instanceof ServerEventRtcCallError); - ServerEventRtcCallError err = (ServerEventRtcCallError) event; - assertEquals(ServerEventType.RTC_CALL_ERROR, err.getType()); - assertEquals("rtc.call.sdp.create", err.getOperation()); - assertEquals("call-9", err.getRtcCallId()); - - RtcCallErrorDetails details = err.getError(); - assertNotNull(details); - assertEquals("invalid_request_error", details.getType()); - assertEquals("bad_sdp", details.getCode()); - assertEquals("Malformed SDP", details.getMessage()); - } -} diff --git a/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/unit/models/SmartEndOfTurnDetectionTest.java b/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/unit/models/SmartEndOfTurnDetectionTest.java deleted file mode 100644 index f7d584aa3c37..000000000000 --- a/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/unit/models/SmartEndOfTurnDetectionTest.java +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -package com.azure.ai.voicelive.unit.models; - -import com.azure.ai.voicelive.models.EouDetection; -import com.azure.ai.voicelive.models.EouDetectionModel; -import com.azure.ai.voicelive.models.EouThresholdLevel; -import com.azure.ai.voicelive.models.SmartEndOfTurnDetection; -import com.azure.core.util.BinaryData; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -/** - * Unit tests for {@link SmartEndOfTurnDetection} and the {@link EouDetectionModel#SMART_END_OF_TURN_DETECTION} - * polymorphic discriminator on {@link EouDetection}. - */ -class SmartEndOfTurnDetectionTest { - - @Test - void testSmartEndOfTurnDetectionRoundTrip() { - SmartEndOfTurnDetection eou - = new SmartEndOfTurnDetection().setThresholdLevel(EouThresholdLevel.HIGH).setTimeoutMs(1500); - - SmartEndOfTurnDetection deserialized = BinaryData.fromObject(eou).toObject(SmartEndOfTurnDetection.class); - - assertEquals(EouDetectionModel.SMART_END_OF_TURN_DETECTION, deserialized.getModel()); - assertEquals(EouThresholdLevel.HIGH, deserialized.getThresholdLevel()); - assertEquals(1500, deserialized.getTimeoutMs()); - } - - @Test - void testSmartEndOfTurnDetectionPolymorphic() { - String json = "{\"model\":\"smart_end_of_turn_detection\",\"threshold_level\":\"medium\",\"timeout_ms\":800}"; - - EouDetection eou = BinaryData.fromString(json).toObject(EouDetection.class); - - assertTrue(eou instanceof SmartEndOfTurnDetection, "Expected SmartEndOfTurnDetection, got " + eou.getClass()); - SmartEndOfTurnDetection smart = (SmartEndOfTurnDetection) eou; - assertEquals(EouThresholdLevel.MEDIUM, smart.getThresholdLevel()); - assertEquals(800, smart.getTimeoutMs()); - } -} diff --git a/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/unit/models/TranscriptionAndIncludeOptionsTest.java b/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/unit/models/TranscriptionAndIncludeOptionsTest.java index acf08b99ab40..7f18f8925af5 100644 --- a/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/unit/models/TranscriptionAndIncludeOptionsTest.java +++ b/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/unit/models/TranscriptionAndIncludeOptionsTest.java @@ -260,7 +260,7 @@ void testSessionOptionsIncludeAndMetadataJsonRoundTrip() { Map metadata = new HashMap<>(); metadata.put("key", "value"); - VoiceLiveSessionOptions options = new VoiceLiveSessionOptions().setModel("gpt-4o-realtime-preview") + VoiceLiveSessionOptions options = new VoiceLiveSessionOptions().setModel("gpt-realtime") .setInclude(Arrays.asList(SessionIncludeOption.ITEM_INPUT_AUDIO_TRANSCRIPTION_PHRASES)) .setMetadata(metadata); diff --git a/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/unit/models/VoiceLiveSessionExpirationTest.java b/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/unit/models/VoiceLiveSessionExpirationTest.java new file mode 100644 index 000000000000..b98a2b21be72 --- /dev/null +++ b/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/unit/models/VoiceLiveSessionExpirationTest.java @@ -0,0 +1,82 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.ai.voicelive.unit.models; + +import com.azure.ai.voicelive.models.VoiceLiveSessionResponse; +import com.azure.core.util.BinaryData; +import org.junit.jupiter.api.Test; + +import java.time.OffsetDateTime; +import java.time.ZoneOffset; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertSame; + +/** + * Unit tests for the session expiration feature on {@link VoiceLiveSessionResponse} + * ({@code getExpiresAt()} / {@code setExpiresAt(OffsetDateTime)}). + */ +class VoiceLiveSessionExpirationTest { + + @Test + void testSetAndGetExpiresAt() { + // Arrange + OffsetDateTime expiresAt = OffsetDateTime.of(2026, 7, 15, 12, 0, 0, 0, ZoneOffset.UTC); + VoiceLiveSessionResponse response = new VoiceLiveSessionResponse(); + + // Act + VoiceLiveSessionResponse result = response.setExpiresAt(expiresAt); + + // Assert - fluent setter returns the same instance and value round-trips + assertSame(response, result); + assertEquals(expiresAt, response.getExpiresAt()); + } + + @Test + void testExpiresAtNullByDefault() { + assertNull(new VoiceLiveSessionResponse().getExpiresAt()); + } + + @Test + void testSetExpiresAtNullClearsValue() { + // Arrange + VoiceLiveSessionResponse response + = new VoiceLiveSessionResponse().setExpiresAt(OffsetDateTime.now(ZoneOffset.UTC)); + + // Act + response.setExpiresAt(null); + + // Assert + assertNull(response.getExpiresAt()); + } + + @Test + void testExpiresAtJsonRoundTrip() { + // Arrange + OffsetDateTime expiresAt = OffsetDateTime.of(2026, 7, 15, 12, 0, 0, 0, ZoneOffset.UTC); + VoiceLiveSessionResponse response = new VoiceLiveSessionResponse().setExpiresAt(expiresAt); + + // Act + VoiceLiveSessionResponse deserialized + = BinaryData.fromObject(response).toObject(VoiceLiveSessionResponse.class); + + // Assert + assertEquals(expiresAt, deserialized.getExpiresAt()); + } + + @Test + void testExpiresAtDeserializedFromEpochSeconds() { + // Arrange - the wire format for expires_at is epoch seconds + long epochSeconds = 1_784_000_000L; + String json = "{\"id\":\"sess-expiry\",\"expires_at\":" + epochSeconds + "}"; + + // Act + VoiceLiveSessionResponse response = BinaryData.fromString(json).toObject(VoiceLiveSessionResponse.class); + + // Assert + assertEquals(OffsetDateTime.ofInstant(java.time.Instant.ofEpochSecond(epochSeconds), ZoneOffset.UTC), + response.getExpiresAt()); + } +} diff --git a/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/unit/models/VoiceLiveSessionOptionsNewFeaturesTest.java b/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/unit/models/VoiceLiveSessionOptionsNewFeaturesTest.java index 4cc1baaecedc..767ab604e656 100644 --- a/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/unit/models/VoiceLiveSessionOptionsNewFeaturesTest.java +++ b/sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/unit/models/VoiceLiveSessionOptionsNewFeaturesTest.java @@ -70,8 +70,8 @@ void testSetAndGetInterimResponse() { @Test void testReasoningEffortJsonSerialization() { // Arrange - VoiceLiveSessionOptions options = new VoiceLiveSessionOptions().setModel("gpt-4o-realtime-preview") - .setReasoningEffort(ReasoningEffort.HIGH); + VoiceLiveSessionOptions options + = new VoiceLiveSessionOptions().setModel("gpt-realtime").setReasoningEffort(ReasoningEffort.HIGH); // Act BinaryData serialized = BinaryData.fromObject(options); @@ -91,7 +91,7 @@ void testInterimResponseJsonSerialization() { .setTriggers(Arrays.asList(InterimResponseTrigger.TOOL)) .setLatencyThresholdMs(1500); - VoiceLiveSessionOptions options = new VoiceLiveSessionOptions().setModel("gpt-4o-realtime-preview") + VoiceLiveSessionOptions options = new VoiceLiveSessionOptions().setModel("gpt-realtime") .setInterimResponse(BinaryData.fromObject(interimConfig)); // Act @@ -111,14 +111,14 @@ void testMethodChainingWithNewFeatures() { .setTriggers(Arrays.asList(InterimResponseTrigger.LATENCY, InterimResponseTrigger.TOOL)); // Act - VoiceLiveSessionOptions options = new VoiceLiveSessionOptions().setModel("gpt-4o-realtime-preview") + VoiceLiveSessionOptions options = new VoiceLiveSessionOptions().setModel("gpt-realtime") .setInstructions("Test instructions") .setReasoningEffort(ReasoningEffort.LOW) .setInterimResponse(BinaryData.fromObject(interimConfig)) .setTemperature(0.8); // Assert - assertEquals("gpt-4o-realtime-preview", options.getModel()); + assertEquals("gpt-realtime", options.getModel()); assertEquals("Test instructions", options.getInstructions()); assertEquals(ReasoningEffort.LOW, options.getReasoningEffort()); assertNotNull(options.getInterimResponse()); @@ -157,7 +157,7 @@ void testVoiceLiveSessionResponseInterimResponse() { @Test void testVoiceLiveSessionOptionsParallelToolCallsRoundTrip() { VoiceLiveSessionOptions options - = new VoiceLiveSessionOptions().setModel("gpt-4o-realtime-preview").setParallelToolCalls(true); + = new VoiceLiveSessionOptions().setModel("gpt-realtime").setParallelToolCalls(true); VoiceLiveSessionOptions deserialized = BinaryData.fromObject(options).toObject(VoiceLiveSessionOptions.class); @@ -166,7 +166,7 @@ void testVoiceLiveSessionOptionsParallelToolCallsRoundTrip() { @Test void testVoiceLiveSessionResponseParallelToolCallsDeserialization() { - String json = "{\"id\":\"sess-1\",\"model\":\"gpt-4o-realtime-preview\",\"parallel_tool_calls\":false}"; + String json = "{\"id\":\"sess-1\",\"model\":\"gpt-realtime\",\"parallel_tool_calls\":false}"; VoiceLiveSessionResponse response = BinaryData.fromString(json).toObject(VoiceLiveSessionResponse.class); diff --git a/sdk/voicelive/azure-ai-voicelive/tsp-location.yaml b/sdk/voicelive/azure-ai-voicelive/tsp-location.yaml index 3d9b406e7c87..91dd50a111d8 100644 --- a/sdk/voicelive/azure-ai-voicelive/tsp-location.yaml +++ b/sdk/voicelive/azure-ai-voicelive/tsp-location.yaml @@ -1,4 +1,4 @@ directory: specification/ai/data-plane/VoiceLive -commit: d9c59b511bcc6c7df5be44a2284f4bf342147615 +commit: 965041b72edd6a89003243f98e36c74ffbfc33c9 repo: Azure/azure-rest-api-specs additionalDirectories: From a6e4f9bbc2212e46a933f5f59220477355b24ff1 Mon Sep 17 00:00:00 2001 From: "azure-sdk-automation[bot]" <191533747+azure-sdk-automation[bot]@users.noreply.github.com> Date: Tue, 14 Jul 2026 13:33:18 -0700 Subject: [PATCH 2/6] Sync .github/skills directory with azure-sdk-tools for PR 16300 (#49807) * Update pipeline troubleshooting skill and vally fixtures * Split pipeline troubleshooting into analysis + fixer skills, added Vally eval suite. * Fixed project name resolution for untrusted DevOps pipelines. Removed unnecessary evaluation files and fixtures for pipeline analysis and fixing. Updated and added skills files for pipeline analysis and fixing. * Fixes to PipelineIdentifierHelper Updated skills/tools descriptions. Deleted redundant eval in prompt-to-tool-pipeline.eval.yaml * Changed skills formatting and updated Vally README to have absolute paths. * Updated to align with review comments. * Updated failure patterns to use "az account show" * Prettier formatting. --------- Co-authored-by: ReilleyMilne Co-authored-by: ReilleyMilne <91291100+ReilleyMilne@users.noreply.github.com> --- .../azsdk-common-pipeline-analysis/SKILL.md | 50 ++++++++++ .../evals/trigger.eval.yaml | 91 +++++++++++++++++++ .../references/failure-patterns.md | 60 ++++++++++++ .../references/output-format.md | 26 ++++++ .../azsdk-common-pipeline-fixer/SKILL.md | 51 +++++++++++ .../evals/trigger.eval.yaml | 89 ++++++++++++++++++ .../SKILL.md | 54 ----------- .../evals/eval.yaml | 89 ------------------ .../evals/trigger.eval.yaml | 83 ----------------- .../references/failure-patterns.md | 45 --------- 10 files changed, 367 insertions(+), 271 deletions(-) create mode 100644 .github/skills/azsdk-common-pipeline-analysis/SKILL.md create mode 100644 .github/skills/azsdk-common-pipeline-analysis/evals/trigger.eval.yaml create mode 100644 .github/skills/azsdk-common-pipeline-analysis/references/failure-patterns.md create mode 100644 .github/skills/azsdk-common-pipeline-analysis/references/output-format.md create mode 100644 .github/skills/azsdk-common-pipeline-fixer/SKILL.md create mode 100644 .github/skills/azsdk-common-pipeline-fixer/evals/trigger.eval.yaml delete mode 100644 .github/skills/azsdk-common-pipeline-troubleshooting/SKILL.md delete mode 100644 .github/skills/azsdk-common-pipeline-troubleshooting/evals/eval.yaml delete mode 100644 .github/skills/azsdk-common-pipeline-troubleshooting/evals/trigger.eval.yaml delete mode 100644 .github/skills/azsdk-common-pipeline-troubleshooting/references/failure-patterns.md diff --git a/.github/skills/azsdk-common-pipeline-analysis/SKILL.md b/.github/skills/azsdk-common-pipeline-analysis/SKILL.md new file mode 100644 index 000000000000..c38fc27be50f --- /dev/null +++ b/.github/skills/azsdk-common-pipeline-analysis/SKILL.md @@ -0,0 +1,50 @@ +--- +name: azsdk-common-pipeline-analysis +license: MIT +metadata: + version: "1.0.0" + distribution: shared +description: 'Analyze Azure SDK CI/CD pipeline failures into a structured diagnosis, and define the required output format. Load this skill before calling azsdk_analyze_pipeline, which returns raw failure data that this skill interprets and formats. USE FOR: "pipeline failed", "build failure", "CI check failing", "tests failing in CI", "analyze pipeline", "debug SDK pipeline". DO NOT USE FOR: local build issues without pipeline context, API design review, SDK publishing, applying code fixes (instead use azsdk-common-pipeline-fixer). INVOKES: azure-sdk-mcp:azsdk_analyze_pipeline, azure-sdk-mcp:azsdk_get_pipeline_llm_artifacts, azure-sdk-mcp:azsdk_get_pr_checks, azure-sdk-mcp:azsdk_get_pipeline_status.' +compatibility: "azure-sdk-mcp server, Azure DevOps pipeline build ID or GitHub PR link" +--- + +# Pipeline Analysis + +This skill analyzes Azure SDK CI/CD pipeline failures and provides a structured diagnosis including root cause, affected files, and concrete instructions for how to fix each issue. It does NOT apply fixes - it tells you exactly what's wrong and how to resolve it. + +## Rules + +- Load this skill **before** running `azsdk_analyze_pipeline` — the tool returns raw failure data that this skill interprets and formats per [output format](references/output-format.md). +- Requires the `azure-sdk-mcp` server; without it, inspect logs in the Azure DevOps UI. +- Analysis-only: never edit files or apply fixes — use `azsdk-common-pipeline-fixer` for changes. +- Run `azsdk_analyze_pipeline` first, then categorize each failure and cite specific files/lines. +- For infrastructure failures (network timeouts, agent crashes, throttling), recommend retry, not code changes. + +## MCP Tools + +| Tool | Purpose | +| ------------------------------------------------ | ---------------------------------------------- | +| `azure-sdk-mcp:azsdk_analyze_pipeline` | Analyze pipeline failure (logs + test results) | +| `azure-sdk-mcp:azsdk_get_pipeline_llm_artifacts` | Download test result artifacts from pipeline | +| `azure-sdk-mcp:azsdk_get_pr_checks` | Get pipeline/check results linked to a PR | +| `azure-sdk-mcp:azsdk_get_pipeline_status` | Get pipeline run status | + +## Steps + +1. **Identify** - Get the build ID, pipeline URL, or PR link (use the PR link when triggered from a PR comment). +2. **Analyze** - Run `azsdk_analyze_pipeline`. It returns `failed_tasks` (log errors from failed steps) and `failed_test_titles` (failed tests grouped by file). +3. **Categorize** each failure: test, build/compilation, validation/lint, or infrastructure. +4. **Diagnose** - Give each failure's root cause and affected file(s)/line(s), and note if several share one root cause. See [failure patterns](references/failure-patterns.md). +5. **Report** - Use the [output format](references/output-format.md): root cause, affected files, per-failure fix + verify command, and fixable vs infrastructure. Recommend `azsdk-common-pipeline-fixer` to apply fixes. + +## Examples + +- "My pipeline build 6447834 failed, what went wrong?" +- PR comment: `@copilot Analyze the failed pipeline on this PR` +- "Why is my CI red? Build ID is 6455939" + +## Troubleshooting + +- If `azsdk_analyze_pipeline` returns no data, verify the build ID is correct and the run has completed. +- If `failed_test_titles` is empty, rely on `failed_tasks` log analysis (test-artifact upload may not be configured). +- For a private/internal pipeline, the user may need to `az login`. See [failure patterns](references/failure-patterns.md). diff --git a/.github/skills/azsdk-common-pipeline-analysis/evals/trigger.eval.yaml b/.github/skills/azsdk-common-pipeline-analysis/evals/trigger.eval.yaml new file mode 100644 index 000000000000..f43b7c37b081 --- /dev/null +++ b/.github/skills/azsdk-common-pipeline-analysis/evals/trigger.eval.yaml @@ -0,0 +1,91 @@ +name: azsdk-common-pipeline-analysis-trigger-eval +description: Trigger and anti-trigger tests for the azsdk-common-pipeline-analysis skill +type: capability + +environment: azsdk-mcp-mock + +tags: + area: azsdk-common-pipeline-analysis + type: ci-gate + +config: + runs: 1 + timeout: "90s" + model: claude-opus-4.6 + executor: copilot-sdk + +scoring: + threshold: 0.8 + +stimuli: + # Should trigger + - name: trigger-my-ci-pipeline-is-failing + prompt: "my Azure SDK CI pipeline build 6447834 is failing, can you help troubleshoot what went wrong?" + graders: + - type: skill-invocation + config: + required: ["azsdk-common-pipeline-analysis"] + - name: trigger-debug-pipeline-build-error + prompt: "debug the build error in my SDK generation pipeline, build 6447834" + graders: + - type: skill-invocation + config: + required: ["azsdk-common-pipeline-analysis"] + - name: trigger-pipeline-analysis-help + prompt: "I'm stuck on a failing Azure SDK pipeline — can you help me troubleshoot it?" + graders: + - type: skill-invocation + config: + required: ["azsdk-common-pipeline-analysis"] + - name: trigger-analyze-failing-sdk-pipeline + prompt: "analyze my failing Azure SDK generation pipeline https://dev.azure.com/azure-sdk/internal/_build/results?buildId=6447834 and tell me what went wrong" + graders: + - type: skill-invocation + config: + required: ["azsdk-common-pipeline-analysis"] + - name: trigger-ci-build-broke-after-my-change + prompt: "the SDK CI build broke after my change, help me troubleshoot the pipeline" + graders: + - type: skill-invocation + config: + required: ["azsdk-common-pipeline-analysis"] + + # Should NOT trigger + # "apply the fix / auto-fix" prompts belong to azsdk-common-pipeline-fixer, not + # this analysis-only skill (see each skill's DO NOT USE FOR boundary). + - name: anti-trigger-auto-fix-and-commit + prompt: "auto-fix the failing tests in my pipeline and commit the changes to my PR" + graders: + - type: skill-invocation + config: + disallowed: ["azsdk-common-pipeline-analysis"] + - name: anti-trigger-write-a-typespec-definition + prompt: "write a TypeSpec definition" + graders: + - type: skill-invocation + config: + disallowed: ["azsdk-common-pipeline-analysis"] + - name: anti-trigger-create-a-new-skill + prompt: "create a new skill" + graders: + - type: skill-invocation + config: + disallowed: ["azsdk-common-pipeline-analysis"] + - name: anti-trigger-optimize-markdown-tokens + prompt: "optimize markdown tokens" + graders: + - type: skill-invocation + config: + disallowed: ["azsdk-common-pipeline-analysis"] + - name: anti-trigger-how-do-i-release-an-sdk-package + prompt: "how do I release an SDK package" + graders: + - type: skill-invocation + config: + disallowed: ["azsdk-common-pipeline-analysis"] + - name: anti-trigger-resolve-apiview-feedback + prompt: "resolve APIView feedback" + graders: + - type: skill-invocation + config: + disallowed: ["azsdk-common-pipeline-analysis"] diff --git a/.github/skills/azsdk-common-pipeline-analysis/references/failure-patterns.md b/.github/skills/azsdk-common-pipeline-analysis/references/failure-patterns.md new file mode 100644 index 000000000000..5e6c4008bde0 --- /dev/null +++ b/.github/skills/azsdk-common-pipeline-analysis/references/failure-patterns.md @@ -0,0 +1,60 @@ +# Pipeline Failure Patterns and Resolution + +## Test Failures + +| Pattern | Likely Cause | Fix | +| ---------------------------------------- | -------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| AssertionError (expected vs actual) | Logic bug or unintended behavior change | Fix the code logic or update expected value if change was intentional | +| Recording file path does not exist | Missing test recording for a new/modified test | Best effort: use the `az` CLI to check auth (try `az account show`); if authenticated, run tests in record mode; else skip and report re-recording is required | +| Playback failure / ResourceNotFoundError | Recorded responses don't match current API calls | Best effort: use the `az` CLI to check auth (try `az account show`); if authenticated, re-record the session; else skip and report re-recording is required | +| HttpResponseError (5xx) in live tests | Service-side issue during live test run | Infrastructure - retry the pipeline | +| Timeout / test hung | Async issue, deadlock, or slow external dependency | Add timeout, fix async logic, or mock the slow dependency | +| FileNotFoundError / missing fixture | Test data not committed or path changed | Add the fixture file or fix the path reference | + +## Build/Compilation Failures + +| Pattern | Likely Cause | Fix | +| ------------------------------------- | -------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | +| Type mismatch (mypy, pyright, tsc) | Code passes wrong type to a function/constructor | Fix the type at the cited file:line | +| Missing import / unresolved reference | New dependency not imported, or missing from the project | Add the import; if the package isn't a declared dependency, add it to the project manifest (e.g. pyproject.toml, .csproj, package.json) | +| Incompatible type in generics | Generic type parameter doesn't satisfy constraint | Fix the type parameter or constraint | +| Syntax error | Malformed code | Fix the syntax at the cited line | +| Missing types/models (TypeSpec) | TypeSpec compilation issue | Fix TypeSpec definition, regenerate | + +## Validation/Lint Failures + +| Pattern | Likely Cause | Fix | +| ------------------------------ | ------------------------------------ | -------------------------------------------------- | +| Changelog validation error | Missing or malformed changelog entry | Update CHANGELOG.md content | +| Breaking change detected | API surface changed incompatibly | Revert the breaking change or add suppression | +| Lint/format violation | Code doesn't match style rules | Run the formatter (black, prettier, dotnet format) | +| API compatibility check failed | Public API signature changed | Update API review or revert | + +## Infrastructure Failures (Recommend Retry) + +| Pattern | Likely Cause | Action | +| ----------------------------------- | --------------------------------------- | -------------- | +| Name or service not known (DNS) | Transient network issue | Retry pipeline | +| HTTP 429 / rate limited | Throttling from package registry or API | Wait and retry | +| Agent disconnected / process killed | CI agent resource exhaustion | Retry pipeline | +| Timeout downloading packages | Network congestion or registry slowness | Retry pipeline | +| Certificate / SSL error | Transient PKI issue | Retry pipeline | + +## Cascading Failure Detection + +When many tests fail simultaneously, look for: + +- A single build/setup step that failed (all downstream tests fail with import errors) +- A shared test fixture or setup method that throws +- A missing environment variable or config file +- A dependency that failed to install + +**Rule of thumb:** If >10 tests fail with similar error patterns, identify the common root cause rather than fixing each individually. + +## TypeSpec/SDK Generation Failures + +| Pattern | Likely Cause | Fix | +| -------------------------------- | ----------------------------------- | ------------------------------------- | +| Missing client.tsp changes | TypeSpec customization needed | Use `azsdk_customized_code_update` | +| tspconfig.yaml emitter error | Incorrect emitter configuration | Fix tspconfig.yaml | +| Breaking change in generated API | TypeSpec change affects SDK surface | Add `@clientName` decorator or revert | diff --git a/.github/skills/azsdk-common-pipeline-analysis/references/output-format.md b/.github/skills/azsdk-common-pipeline-analysis/references/output-format.md new file mode 100644 index 000000000000..1864d2b852dd --- /dev/null +++ b/.github/skills/azsdk-common-pipeline-analysis/references/output-format.md @@ -0,0 +1,26 @@ +# Pipeline Analysis Output Format + +Write the diagnosis as markdown so it reads cleanly in a GitHub PR comment or an +Azure DevOps pipeline summary. Order it: root cause first, then each failure, +then a short fix summary. + +Include these parts: + +1. **Header** — build ID or PR link, package path, and overall status. +2. **Root cause** — one or two plain sentences naming the underlying problem. If + failures are unrelated, list each root cause separately. +3. **Failures** — for every failure: its category (test / build / validation / + infrastructure), the exact `file:line` from the analysis output, the error + text, and the specific fix. +4. **Verify** — the local command that reproduces each fixable failure + (e.g. `python -m mypy --isolate `, `dotnet test --filter `). +5. **Summary** — counts of fixable-in-code, infrastructure (retry), and + needs-human-input failures. Recommend `azsdk-common-pipeline-fixer` only when + something is code-fixable. + +## Rules + +- Always cite the real `file:line` from the analysis output; never paraphrase it. +- Group cascading failures under their shared root cause instead of listing each. +- Mark infrastructure failures (network, throttling, agent crash) as retry, not code. +- See [failure patterns](failure-patterns.md) for category-to-fix mappings. diff --git a/.github/skills/azsdk-common-pipeline-fixer/SKILL.md b/.github/skills/azsdk-common-pipeline-fixer/SKILL.md new file mode 100644 index 000000000000..743b8f180faf --- /dev/null +++ b/.github/skills/azsdk-common-pipeline-fixer/SKILL.md @@ -0,0 +1,51 @@ +--- +name: azsdk-common-pipeline-fixer +license: MIT +metadata: + version: "1.0.0" + distribution: shared +description: 'Automatically fix Azure SDK CI/CD pipeline failures by applying code changes and verifying locally. USE FOR: "fix pipeline failure", "fix CI", "fix failing tests", "auto-fix and commit the fix", "fix build error", "fix mypy/pylint/type-check/lint errors", "auto-fix pipeline", "resolve pipeline failure". DO NOT USE FOR: pipeline analysis (instead use azsdk-common-pipeline-analysis), API design review, SDK publishing. INVOKES: azure-sdk-mcp:azsdk_package_build_code, azure-sdk-mcp:azsdk_package_run_check, azure-sdk-mcp:azsdk_package_run_tests, azure-sdk-mcp:azsdk_verify_setup.' +compatibility: "azure-sdk-mcp server, local azure-sdk-for-{language} clone, language build tools" +--- + +# Pipeline Fixer + +This skill automatically fixes Azure SDK CI/CD pipeline failures. It analyzes the failure, identifies the root cause, applies code changes, and verifies the fix locally using build, check, and test tools before committing. + +## Rules + +- Requires the `azure-sdk-mcp` server and a local clone of the SDK language repo. +- Work on the PR branch — the failing code is there, not main. +- Analyze first, then apply the minimal code change for the root cause. +- Verify ONLY via the azsdk MCP package tools (build → check → tests); never raw shell build/test commands. +- Never fix infrastructure failures (timeouts, crashes, throttling) — recommend retry. Iterate up to 3 times, then report. + +## MCP Tools + +| Tool | Purpose | +| ---------------------------------------- | ------------------------------------- | +| `azure-sdk-mcp:azsdk_verify_setup` | Verify local environment is ready | +| `azure-sdk-mcp:azsdk_package_build_code` | Build the package locally | +| `azure-sdk-mcp:azsdk_package_run_check` | Run validation/lint/typecheck locally | +| `azure-sdk-mcp:azsdk_package_run_tests` | Run tests locally | + +**Prerequisites:** azure-sdk-mcp server required. Local clone of the affected SDK language repo. Language build tools installed. + +## Steps + +1. **Find analysis** - Reuse an existing analysis from the PR comments; if none, view the `azsdk-common-pipeline-analysis` skill. +2. **Classify** - Fixable (test, type, lint, import, assertion errors) vs retry (infrastructure) vs escalate (breaking API, credentials). +3. **Locate** - Identify the affected package, its path, and the files/lines to change. +4. **Fix** - Read the failing code at the cited lines and apply the minimal fix. +5. **Verify** - Run `azsdk_package_build_code` → `azsdk_package_run_check` → `azsdk_package_run_tests` on the package; all must pass. If the environment isn't ready, run `azsdk_verify_setup`. Never substitute raw shell build/test commands. +6. **Iterate & commit** - On failure, revise and re-verify (max 3 attempts). Once all pass, commit with a descriptive message. + +## Examples + +- "Fix the pipeline failure for build 6447834" +- "My Python SDK CI is failing with a type error, fix it" +- "Auto-fix the failing tests in my PR" + +## Troubleshooting + +- If the verify tools fail because the environment isn't ready, run `azsdk_verify_setup`, report its error, and stop — don't fall back to raw shell build/test commands. diff --git a/.github/skills/azsdk-common-pipeline-fixer/evals/trigger.eval.yaml b/.github/skills/azsdk-common-pipeline-fixer/evals/trigger.eval.yaml new file mode 100644 index 000000000000..16dad26093c7 --- /dev/null +++ b/.github/skills/azsdk-common-pipeline-fixer/evals/trigger.eval.yaml @@ -0,0 +1,89 @@ +name: azsdk-common-pipeline-fixer-trigger-eval +description: Trigger and anti-trigger tests for the azsdk-common-pipeline-fixer skill +type: capability + +environment: azsdk-mcp-mock + +tags: + area: azsdk-common-pipeline-fixer + type: ci-gate + +config: + runs: 1 + # Stimuli with a resolvable build reference (URL or build ID) make the agent + # run the full analyze→fix→verify workflow (~90-180s under claude-opus-4.6), + # so the per-stimulus cap matches the Vally scenario evals (5m). Non-build-ref + # routing prompts still complete in ~10-20s. + timeout: "5m" + model: claude-opus-4.6 + executor: copilot-sdk + +scoring: + threshold: 0.8 + +stimuli: + # Should trigger + - name: trigger-fix-pipeline-failure + prompt: "fix the pipeline failure for build 6447834" + graders: + - type: skill-invocation + config: + required: ["azsdk-common-pipeline-fixer"] + - name: trigger-auto-fix-failing-tests + prompt: "My Azure SDK PR has failing tests in CI: https://dev.azure.com/azure-sdk/internal/_build/results?buildId=6447834. Can you fix them?" + graders: + - type: skill-invocation + config: + required: ["azsdk-common-pipeline-fixer"] + - name: trigger-resolve-pipeline-failure + prompt: "resolve my Azure SDK pipeline failure" + graders: + - type: skill-invocation + config: + required: ["azsdk-common-pipeline-fixer"] + - name: trigger-fix-build-error + prompt: "fix the build error in my Azure SDK CI" + graders: + - type: skill-invocation + config: + required: ["azsdk-common-pipeline-fixer"] + - name: trigger-fix-mypy-type-error + prompt: "My Python SDK CI is failing with a mypy type error: https://dev.azure.com/azure-sdk/internal/_build/results?buildId=6447834. Can you fix it?" + graders: + - type: skill-invocation + config: + required: ["azsdk-common-pipeline-fixer"] + + # Should NOT trigger + # Analysis-only prompts belong to azsdk-common-pipeline-analysis; this + # skill applies + verifies fixes and must stay out of pure-diagnosis requests. + - name: anti-trigger-analyze-only + prompt: "what went wrong in my pipeline build 12345? just tell me, don't fix anything" + graders: + - type: skill-invocation + config: + disallowed: ["azsdk-common-pipeline-fixer"] + - name: anti-trigger-why-is-ci-red + prompt: "why is my CI red? just diagnose the root cause, do not change any code" + graders: + - type: skill-invocation + config: + disallowed: ["azsdk-common-pipeline-fixer"] + - name: anti-trigger-write-a-typespec-definition + prompt: "write a TypeSpec definition" + graders: + - type: skill-invocation + config: + disallowed: ["azsdk-common-pipeline-fixer"] + - name: anti-trigger-release-sdk-package + prompt: "how do I release an SDK package" + graders: + - type: skill-invocation + config: + disallowed: ["azsdk-common-pipeline-fixer"] + - name: anti-trigger-create-a-new-skill + prompt: "create a new skill" + graders: + - type: skill-invocation + config: + disallowed: ["azsdk-common-pipeline-fixer"] diff --git a/.github/skills/azsdk-common-pipeline-troubleshooting/SKILL.md b/.github/skills/azsdk-common-pipeline-troubleshooting/SKILL.md deleted file mode 100644 index 81b896f6b5e6..000000000000 --- a/.github/skills/azsdk-common-pipeline-troubleshooting/SKILL.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -name: azsdk-common-pipeline-troubleshooting -license: MIT -metadata: - version: "1.0.0" - distribution: shared -description: 'Diagnose and resolve failures in Azure SDK CI and generation pipelines. **UTILITY SKILL**. USE FOR: "pipeline failed", "build failure", "CI check failing", "SDK generation error", "reproduce pipeline locally", "debug SDK pipeline". DO NOT USE FOR: local build issues without pipeline context, API design review, SDK publishing. INVOKES: azure-sdk-mcp:azsdk_analyze_pipeline, azure-sdk-mcp:azsdk_verify_setup, azure-sdk-mcp:azsdk_package_build_code, azure-sdk-mcp:azsdk_package_run_check, azure-sdk-mcp:azsdk_package_pack.' -compatibility: "azure-sdk-mcp server, Azure DevOps pipeline build ID" ---- - -# Pipeline Troubleshooting - -This skill diagnoses and resolves failures in Azure SDK CI and generation pipelines by analyzing pipeline runs, reproducing issues locally, and applying targeted fixes for build, validation, or TypeSpec problems before verifying the rerun. - -## Triggers - -USE FOR: pipeline failed, build failure, CI check failing, SDK generation error, reproduce pipeline locally, debug SDK pipeline -WHEN: "pipeline failed", "build failure", "CI check failing", "SDK generation error", "reproduce pipeline locally", "debug SDK pipeline" -DO NOT USE FOR: local build issues without pipeline context, API design review, SDK publishing - -## Rules - -- Requires the `azure-sdk-mcp` server; without MCP, inspect logs in the Azure DevOps UI. -- Start with the pipeline build ID and run pipeline analysis before attempting local reproduction. -- Verify the local environment before running build or check commands to reproduce the failure. - -## MCP Tools - -| Tool | Purpose | -| ---------------------------------------- | ------------------------ | -| `azure-sdk-mcp:azsdk_analyze_pipeline` | Analyze pipeline failure | -| `azure-sdk-mcp:azsdk_verify_setup` | Verify local environment | -| `azure-sdk-mcp:azsdk_package_build_code` | Reproduce build locally | -| `azure-sdk-mcp:azsdk_package_run_check` | Run validation checks | -| `azure-sdk-mcp:azsdk_package_pack` | Create SDK packages | - -**Prerequisites:** azure-sdk-mcp server required. Without MCP, view pipeline logs in Azure DevOps UI. - -## Steps - -1. **Identify** — Get build ID, run `azure-sdk-mcp:azsdk_analyze_pipeline`. Categorize failure. -2. **Analyze** — See [failure patterns](references/failure-patterns.md) for common causes. -3. **Reproduce** — Verify setup, then run `azure-sdk-mcp:azsdk_package_build_code` or `azure-sdk-mcp:azsdk_package_run_check`. -4. **Fix** — Apply fixes for code or TypeSpec issues. -5. **Verify** — Confirm fix locally, push, monitor re-run. - -## Examples - -- "My pipeline build 12345 failed, help debug it" -- "Reproduce CI failure locally" - -## Troubleshooting - -If `azure-sdk-mcp:azsdk_analyze_pipeline` returns no data, verify build ID and MCP. Without MCP, check pipeline logs in Azure DevOps UI. diff --git a/.github/skills/azsdk-common-pipeline-troubleshooting/evals/eval.yaml b/.github/skills/azsdk-common-pipeline-troubleshooting/evals/eval.yaml deleted file mode 100644 index 194de6b1e144..000000000000 --- a/.github/skills/azsdk-common-pipeline-troubleshooting/evals/eval.yaml +++ /dev/null @@ -1,89 +0,0 @@ -name: azsdk-common-pipeline-troubleshooting-eval -description: Evaluation suite for the azsdk-common-pipeline-troubleshooting skill -type: capability - -environment: azsdk-mcp-mock - -tags: - area: azsdk-common-pipeline-troubleshooting - type: ci-gate - -config: - runs: 1 - timeout: "90s" - model: claude-opus-4.6 - executor: copilot-sdk - -scoring: - threshold: 0.8 - -stimuli: - - name: pipeline-basic-001 - prompt: "My SDK generation pipeline failed for the Python language. The pipeline URL is https://dev.azure.com/azure-sdk/internal/_build/results?buildId=12345. Can you help me figure out what went wrong?" - graders: - - type: output-contains - config: - substring: "pipeline" - - type: output-contains - config: - substring: "Python" - - type: tool-calls - config: - required: - - name: azure-sdk-mcp-azsdk_analyze_pipeline - - - name: pipeline-edge-001 - prompt: "My SDK generation pipeline failed for both Python and Java but succeeded for .NET and JavaScript. How do I fix the failing languages?" - graders: - - type: output-contains - config: - substring: "Python" - - type: output-contains - config: - substring: "Java" - - type: output-not-contains - config: - substring: "cannot help" - - - name: pipeline-repro-001 - prompt: "The CI pipeline for my Go SDK PR is failing with a compilation error. I want to reproduce this locally to debug it." - graders: - - type: output-contains - config: - substring: "local" - - type: output-contains - config: - substring: "Go" - - type: output-contains - config: - substring: "build" - - - name: pipeline-negative-001 - prompt: "How do I define a new REST operation in my TypeSpec project?" - graders: - - type: tool-calls - config: - disallowed: - - name: azure-sdk-mcp-azsdk_analyze_pipeline - - type: output-not-contains - config: - substring: "pipeline failure" - - - name: basic-trigger - prompt: "My Azure SDK CI pipeline is failing. Can you help me debug it?" - graders: - - type: output-contains - config: - substring: "pipeline" - constraints: - expect_skills: ["azsdk-common-pipeline-troubleshooting"] - - - name: anti-trigger - prompt: "How do I write a TypeSpec definition for a new Azure service?" - graders: - - type: output-not-contains - config: - substring: "pipeline" - - type: output-not-contains - config: - substring: "CI failure" diff --git a/.github/skills/azsdk-common-pipeline-troubleshooting/evals/trigger.eval.yaml b/.github/skills/azsdk-common-pipeline-troubleshooting/evals/trigger.eval.yaml deleted file mode 100644 index 994334745a84..000000000000 --- a/.github/skills/azsdk-common-pipeline-troubleshooting/evals/trigger.eval.yaml +++ /dev/null @@ -1,83 +0,0 @@ -name: azsdk-common-pipeline-troubleshooting-trigger-eval -description: Trigger and anti-trigger tests for the azsdk-common-pipeline-troubleshooting skill -type: capability - -environment: azsdk-mcp-mock - -tags: - area: azsdk-common-pipeline-troubleshooting - type: ci-gate - -config: - runs: 1 - timeout: "90s" - model: claude-opus-4.6 - executor: copilot-sdk - -scoring: - threshold: 0.8 - -stimuli: - # Should trigger - - name: trigger-my-ci-pipeline-is-failing - prompt: "my Azure SDK CI pipeline is failing, can you help troubleshoot?" - graders: - - type: skill-invocation - config: - required: ["azsdk-common-pipeline-troubleshooting"] - - name: trigger-debug-pipeline-build-error - prompt: "debug my SDK generation pipeline build error" - graders: - - type: skill-invocation - config: - required: ["azsdk-common-pipeline-troubleshooting"] - - name: trigger-pipeline-troubleshooting-help - prompt: "pipeline troubleshooting help" - graders: - - type: skill-invocation - config: - required: ["azsdk-common-pipeline-troubleshooting"] - - name: trigger-fix-failing-sdk-pipeline - prompt: "fix my failing Azure SDK generation pipeline" - graders: - - type: skill-invocation - config: - required: ["azsdk-common-pipeline-troubleshooting"] - - name: trigger-ci-build-broke-after-my-change - prompt: "the SDK CI build broke after my change, help me troubleshoot the pipeline" - graders: - - type: skill-invocation - config: - required: ["azsdk-common-pipeline-troubleshooting"] - - # Should NOT trigger - - name: anti-trigger-write-a-typespec-definition - prompt: "write a TypeSpec definition" - graders: - - type: skill-invocation - config: - disallowed: ["azsdk-common-pipeline-troubleshooting"] - - name: anti-trigger-create-a-new-skill - prompt: "create a new skill" - graders: - - type: skill-invocation - config: - disallowed: ["azsdk-common-pipeline-troubleshooting"] - - name: anti-trigger-optimize-markdown-tokens - prompt: "optimize markdown tokens" - graders: - - type: skill-invocation - config: - disallowed: ["azsdk-common-pipeline-troubleshooting"] - - name: anti-trigger-how-do-i-release-an-sdk-package - prompt: "how do I release an SDK package" - graders: - - type: skill-invocation - config: - disallowed: ["azsdk-common-pipeline-troubleshooting"] - - name: anti-trigger-resolve-apiview-feedback - prompt: "resolve APIView feedback" - graders: - - type: skill-invocation - config: - disallowed: ["azsdk-common-pipeline-troubleshooting"] diff --git a/.github/skills/azsdk-common-pipeline-troubleshooting/references/failure-patterns.md b/.github/skills/azsdk-common-pipeline-troubleshooting/references/failure-patterns.md deleted file mode 100644 index 36b7c16602c0..000000000000 --- a/.github/skills/azsdk-common-pipeline-troubleshooting/references/failure-patterns.md +++ /dev/null @@ -1,45 +0,0 @@ -# Pipeline Failure Patterns and Resolution - -## Build Failures - -- Check for TypeSpec customization needs (missing client.tsp changes) -- Verify tspconfig.yaml emitter configuration is correct -- Check for breaking changes in the generated API surface - -## Test Failures - -- Check if tests need playback recording updates -- Verify test fixtures are present and valid - -## Validation Failures - -- Run `azsdk_package_run_check` locally to reproduce -- Check changelog format and content -- Verify API compatibility (no unintended breaking changes) - -## Common Failure Patterns - -| Pattern | Likely Cause | Fix | -| ----------------------------- | ------------------------------ | ---------------------------------- | -| Missing types/models | TypeSpec compilation issue | Fix TypeSpec, regenerate | -| Breaking change detected | API surface changed | Add `@clientName` or revert change | -| Test playback failure | Recorded responses outdated | Re-record test sessions | -| Changelog validation error | Missing or malformed changelog | Update changelog content | -| Dependency resolution failure | Package version conflict | Check dependency versions | - -## Fix Application - -**If TypeSpec change is needed:** - -- Use TypeSpec customization to apply changes -- Regenerate SDK after TypeSpec fixes - -**If code fix is needed:** - -- Apply fix directly in SDK repo -- Re-run build and validation locally - -**If pipeline/infrastructure issue:** - -- Suggest re-running the pipeline -- Report infrastructure issues to engineering systems team From 084088dcbee567dc5e55ac7e28ac054a076d2f0c Mon Sep 17 00:00:00 2001 From: "azure-sdk-automation[bot]" <191533747+azure-sdk-automation[bot]@users.noreply.github.com> Date: Tue, 14 Jul 2026 20:57:35 +0000 Subject: [PATCH 3/6] Added presteps support to auto-release template (#49818) Co-authored-by: Ray Chen --- .../stages/archetype-auto-release-prepare.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/eng/common/pipelines/templates/stages/archetype-auto-release-prepare.yml b/eng/common/pipelines/templates/stages/archetype-auto-release-prepare.yml index 8e34b5844643..5b8d6b9e592a 100644 --- a/eng/common/pipelines/templates/stages/archetype-auto-release-prepare.yml +++ b/eng/common/pipelines/templates/stages/archetype-auto-release-prepare.yml @@ -9,6 +9,12 @@ parameters: - name: Condition type: string default: succeeded() + # Language-specific steps that run (in the resolve job) before the package-detection script. + # Repos whose Get-AllPackageInfoFromRepo needs tooling set up first (e.g. Python installing + # azure-sdk-tools from an authenticated feed) pass those steps here. Default is none. + - name: PreSteps + type: stepList + default: [] stages: # Post-merge auto-release preparation, shared across language repos (this file lives in the synced @@ -44,6 +50,10 @@ stages: - template: /eng/common/pipelines/templates/steps/login-to-github.yml + # Optional language-specific environment setup (e.g. Python: UsePythonVersion + feed auth so + # the in-script azure-sdk-tools install resolves from an authenticated, reachable feed). + - ${{ parameters.PreSteps }} + - task: PowerShell@2 name: resolve displayName: Determine releasable packages From 591bdb019af4e011ec3b6efd48fb50b229ca951b Mon Sep 17 00:00:00 2001 From: "azure-sdk-automation[bot]" <191533747+azure-sdk-automation[bot]@users.noreply.github.com> Date: Tue, 14 Jul 2026 14:15:03 -0700 Subject: [PATCH 4/6] Sync eng/common directory with azure-sdk-tools for PR 16330 (#49811) * Convert eval CI glue scripts from .js to .ts (Node type stripping) Rename the 7 source + 4 test modules under eng/common/scripts/eval to .ts and rewrite relative import specifiers to .ts (Node native type erasure, no build step). Pipeline node invocations and the npm test script gain --experimental-strip-types --disable-warning=ExperimentalWarning so they run on Node 22.6-22.17 (local) and unflagged on 22.18+ (CI). engines bumped to >=22.6. Addresses Mike Harder feedback to prefer .ts with type erasure over .js. * Reuse azure-rest-api-specs exec primitives in eval git sync Vendor .github/shared/src/exec.js from azure-rest-api-specs (@ef7dd74) as lib/exec.ts (TS port, erasable syntax) under eng/common so it syncs into the language repos. Rewire sync-eval-git-repo invokeGit onto the async execFile helper (no-shell child_process.execFile, git stderr surfaced only on failure); syncRepo and init-eval-git-fixtures main become async accordingly. README documents the vendored file and provenance. Addresses Mike Harder feedback to reuse the shared exec primitives; see #16296. * Polish: keep vendored exec.ts faithful to upstream; note shard spawnSync rationale * Drop --disable-warning=ExperimentalWarning; keep only --experimental-strip-types --------- Co-authored-by: helen229 --- .../pipelines/templates/jobs/eval-shard.yml | 2 +- .../templates/jobs/eval-summarize.yml | 2 +- .../templates/jobs/generate-eval-matrix.yml | 2 +- .../pipelines/templates/steps/eval-invoke.yml | 4 +- eng/common/scripts/eval/.gitignore | 2 +- eng/common/scripts/eval/README.md | 19 ++- ...-eval-summary.js => build-eval-summary.ts} | 2 +- ...{collect-stimuli.js => collect-stimuli.ts} | 2 +- ...-fixtures.js => init-eval-git-fixtures.ts} | 16 +- ...oke-eval-shard.js => invoke-eval-shard.ts} | 5 +- eng/common/scripts/eval/lib/exec.ts | 139 ++++++++++++++++++ .../scripts/eval/lib/{glob.js => glob.ts} | 0 .../eval/lib/{verdict.js => verdict.ts} | 2 +- eng/common/scripts/eval/package.json | 4 +- ...eval-git-repo.js => sync-eval-git-repo.ts} | 57 +++---- ...ary.test.js => build-eval-summary.test.ts} | 4 +- ...timuli.test.js => collect-stimuli.test.ts} | 4 +- ...test.js => init-eval-git-fixtures.test.ts} | 4 +- .../test/{verdict.test.js => verdict.test.ts} | 4 +- 19 files changed, 217 insertions(+), 57 deletions(-) rename eng/common/scripts/eval/{build-eval-summary.js => build-eval-summary.ts} (99%) rename eng/common/scripts/eval/{collect-stimuli.js => collect-stimuli.ts} (99%) rename eng/common/scripts/eval/{init-eval-git-fixtures.js => init-eval-git-fixtures.ts} (95%) rename eng/common/scripts/eval/{invoke-eval-shard.js => invoke-eval-shard.ts} (93%) create mode 100644 eng/common/scripts/eval/lib/exec.ts rename eng/common/scripts/eval/lib/{glob.js => glob.ts} (100%) rename eng/common/scripts/eval/lib/{verdict.js => verdict.ts} (98%) rename eng/common/scripts/eval/{sync-eval-git-repo.js => sync-eval-git-repo.ts} (71%) rename eng/common/scripts/eval/test/{build-eval-summary.test.js => build-eval-summary.test.ts} (98%) rename eng/common/scripts/eval/test/{collect-stimuli.test.js => collect-stimuli.test.ts} (98%) rename eng/common/scripts/eval/test/{init-eval-git-fixtures.test.js => init-eval-git-fixtures.test.ts} (98%) rename eng/common/scripts/eval/test/{verdict.test.js => verdict.test.ts} (97%) diff --git a/eng/common/pipelines/templates/jobs/eval-shard.yml b/eng/common/pipelines/templates/jobs/eval-shard.yml index 409b3bb53919..0b31fdb93c3e 100644 --- a/eng/common/pipelines/templates/jobs/eval-shard.yml +++ b/eng/common/pipelines/templates/jobs/eval-shard.yml @@ -101,7 +101,7 @@ jobs: patterns+=(--pattern "$tok") done set +f - node "$(Build.SourcesDirectory)/eng/common/scripts/eval/init-eval-git-fixtures.js" \ + node --experimental-strip-types "$(Build.SourcesDirectory)/eng/common/scripts/eval/init-eval-git-fixtures.ts" \ --eval-root "$(Build.SourcesDirectory)/${{ parameters.vallyRoot }}" \ "${patterns[@]}" displayName: 'Prime eval git fixtures' diff --git a/eng/common/pipelines/templates/jobs/eval-summarize.yml b/eng/common/pipelines/templates/jobs/eval-summarize.yml index 99c8fd39515e..8d9f49d6c8c8 100644 --- a/eng/common/pipelines/templates/jobs/eval-summarize.yml +++ b/eng/common/pipelines/templates/jobs/eval-summarize.yml @@ -29,7 +29,7 @@ jobs: # Renders the rollup to the run's Summary tab (##vso[task.uploadsummary]). - script: | - node "$(Build.SourcesDirectory)/eng/common/scripts/eval/build-eval-summary.js" \ + node --experimental-strip-types "$(Build.SourcesDirectory)/eng/common/scripts/eval/build-eval-summary.ts" \ --results-root "$(Pipeline.Workspace)/eval-results" \ --output-path "$(Build.ArtifactStagingDirectory)/eval-summary.md" displayName: 'Render Markdown rollup' diff --git a/eng/common/pipelines/templates/jobs/generate-eval-matrix.yml b/eng/common/pipelines/templates/jobs/generate-eval-matrix.yml index 5d3ca5511ba3..688a1018bfb7 100644 --- a/eng/common/pipelines/templates/jobs/generate-eval-matrix.yml +++ b/eng/common/pipelines/templates/jobs/generate-eval-matrix.yml @@ -37,7 +37,7 @@ jobs: set +f fi base="$(Build.SourcesDirectory)/${{ parameters.vallyRoot }}" - node "$(Build.SourcesDirectory)/eng/common/scripts/eval/collect-stimuli.js" \ + node --experimental-strip-types "$(Build.SourcesDirectory)/eng/common/scripts/eval/collect-stimuli.ts" \ --eval-root "$base" \ --path-base "$base" \ "${patterns[@]}" \ diff --git a/eng/common/pipelines/templates/steps/eval-invoke.yml b/eng/common/pipelines/templates/steps/eval-invoke.yml index 25ebff0fffe7..50c833a30812 100644 --- a/eng/common/pipelines/templates/steps/eval-invoke.yml +++ b/eng/common/pipelines/templates/steps/eval-invoke.yml @@ -27,7 +27,7 @@ steps: scriptLocation: inlineScript workingDirectory: ${{ parameters.vallyRoot }} inlineScript: | - node "$(Build.SourcesDirectory)/eng/common/scripts/eval/invoke-eval-shard.js" \ + node --experimental-strip-types "$(Build.SourcesDirectory)/eng/common/scripts/eval/invoke-eval-shard.ts" \ --eval-args "$(evalArgs)" \ --shard-name "$(shardName)" \ --output-dir "$(Build.SourcesDirectory)/artifacts/vally-results/$(shardName)" \ @@ -37,7 +37,7 @@ steps: - ${{ else }}: - script: | - node "$(Build.SourcesDirectory)/eng/common/scripts/eval/invoke-eval-shard.js" \ + node --experimental-strip-types "$(Build.SourcesDirectory)/eng/common/scripts/eval/invoke-eval-shard.ts" \ --eval-args "$(evalArgs)" \ --shard-name "$(shardName)" \ --output-dir "$(Build.SourcesDirectory)/artifacts/vally-results/$(shardName)" \ diff --git a/eng/common/scripts/eval/.gitignore b/eng/common/scripts/eval/.gitignore index e35daad3f926..a45aeeaa2241 100644 --- a/eng/common/scripts/eval/.gitignore +++ b/eng/common/scripts/eval/.gitignore @@ -1,4 +1,4 @@ -# The Vally eval harness ships hand-written ES modules under lib/ (glob.js, verdict.js). +# The Vally eval harness ships hand-written ES modules under lib/ (glob.ts, verdict.ts). # Most repos ignore a top-level `lib/` (Python build output); re-include ours here so the # harness stays tracked wherever eng/common is synced (else node fails ERR_MODULE_NOT_FOUND). # Living in eng/common means this fix travels with the sync to every language SDK repo, so no diff --git a/eng/common/scripts/eval/README.md b/eng/common/scripts/eval/README.md index c3de6d3ec2a9..b66dd60fad3c 100644 --- a/eng/common/scripts/eval/README.md +++ b/eng/common/scripts/eval/README.md @@ -1,6 +1,6 @@ # eval-scripts (CI glue + pinned Vally CLI) -This folder holds the JavaScript glue the Vally eval CI runs (matrix sharding, the shard +This folder holds the TypeScript glue the Vally eval CI runs (matrix sharding, the shard runner, the JUnit summary) **and** pins the [`@microsoft/vally-cli`](https://www.npmjs.com/package/@microsoft/vally-cli) version those shards install. The CLI and its full transitive dependency tree are locked by the committed `package-lock.json` instead of resolved fresh from semver ranges on every run. @@ -10,6 +10,23 @@ templates. - The only dependency should be `@microsoft/vally-cli`, pinned to the version CI should evaluate with. - `package-lock.json` must be committed so `npm ci` is deterministic. +## TypeScript (no build step) + +The `*.ts` sources run directly through Node's native type stripping (erasable syntax only — +no `enum`/`namespace`/parameter properties, no emit). CI pins Node `22.x`, which strips types +unflagged on `>=22.18`; the pipeline `node` invocations and the `npm test` script pass +`--experimental-strip-types` so the same sources also run on older local Node (`>=22.6`), which +prints a harmless `ExperimentalWarning`. Relative imports use explicit `.ts` specifiers, as Node requires. + +## Vendored files + +- `lib/exec.ts` was **copied from azure-rest-api-specs** (`.github/shared/src/exec.js` + @ `ef7dd74c13aa9ca12b67b33b9dc4b5d1419a46f0`) and ported to TypeScript. It lives here under + `eng/common` (rather than the specs repo's `.github/shared` path) so it travels with the + eng/common sync into the language repos. Re-vendor from upstream rather than editing locally; + see [azure-sdk-tools#16296](https://github.com/Azure/azure-sdk-tools/issues/16296) for the plan + to share these primitives instead of copying. + ## Updating the Vally CLI version 1. Bump `@microsoft/vally-cli` in `package.json`. diff --git a/eng/common/scripts/eval/build-eval-summary.js b/eng/common/scripts/eval/build-eval-summary.ts similarity index 99% rename from eng/common/scripts/eval/build-eval-summary.js rename to eng/common/scripts/eval/build-eval-summary.ts index 69b41488afbe..c270821e6375 100644 --- a/eng/common/scripts/eval/build-eval-summary.js +++ b/eng/common/scripts/eval/build-eval-summary.ts @@ -5,7 +5,7 @@ import fs from "node:fs"; import path from "node:path"; import { pathToFileURL } from "node:url"; -import { globFiles } from "./lib/glob.js"; +import { globFiles } from "./lib/glob.ts"; // Maps a JUnit file path back to its shard and job attempt. Result artifacts download into // folders named `eval-result--` (the attempt suffix keeps "Rerun failed diff --git a/eng/common/scripts/eval/collect-stimuli.js b/eng/common/scripts/eval/collect-stimuli.ts similarity index 99% rename from eng/common/scripts/eval/collect-stimuli.js rename to eng/common/scripts/eval/collect-stimuli.ts index b571e4874ee7..260e4006fd41 100644 --- a/eng/common/scripts/eval/collect-stimuli.js +++ b/eng/common/scripts/eval/collect-stimuli.ts @@ -6,7 +6,7 @@ import fs from "node:fs"; import path from "node:path"; import { pathToFileURL } from "node:url"; -import { globFiles } from "./lib/glob.js"; +import { globFiles } from "./lib/glob.ts"; // Fallback patterns when run with no --pattern. Mirrors archetype-eval.yml's evalGlobs default. const DEFAULT_PATTERNS = [ diff --git a/eng/common/scripts/eval/init-eval-git-fixtures.js b/eng/common/scripts/eval/init-eval-git-fixtures.ts similarity index 95% rename from eng/common/scripts/eval/init-eval-git-fixtures.js rename to eng/common/scripts/eval/init-eval-git-fixtures.ts index 208ba0fdbd95..8921b1004c59 100644 --- a/eng/common/scripts/eval/init-eval-git-fixtures.js +++ b/eng/common/scripts/eval/init-eval-git-fixtures.ts @@ -5,8 +5,8 @@ import fs from "node:fs"; import path from "node:path"; import { pathToFileURL } from "node:url"; -import { globFiles } from "./lib/glob.js"; -import { syncRepo } from "./sync-eval-git-repo.js"; +import { globFiles } from "./lib/glob.ts"; +import { syncRepo } from "./sync-eval-git-repo.ts"; export const DEFAULT_PATTERNS = [ "evals/tools/*.eval.yaml", @@ -113,7 +113,7 @@ function parseArgs(argv) { return options; } -function main(argv) { +async function main(argv) { const options = parseArgs(argv); const root = path.resolve(options.evalRoot); @@ -139,7 +139,7 @@ function main(argv) { const sparseCheckoutPaths = known ? known.sparse : []; const cacheRoot = path.dirname(fixture.cachePath); console.log(`[prime-fixtures] Priming ${fixture.repoName} @ ${fixture.ref} from ${repoUrl}`); - syncRepo({ + await syncRepo({ cacheRoot, repoUrl, repoName: fixture.repoName, @@ -154,10 +154,8 @@ function main(argv) { } if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) { - try { - main(process.argv.slice(2)); - } catch (error) { - console.error(error.message); + main(process.argv.slice(2)).catch((error) => { + console.error(error instanceof Error ? error.message : error); process.exit(1); - } + }); } diff --git a/eng/common/scripts/eval/invoke-eval-shard.js b/eng/common/scripts/eval/invoke-eval-shard.ts similarity index 93% rename from eng/common/scripts/eval/invoke-eval-shard.js rename to eng/common/scripts/eval/invoke-eval-shard.ts index c59a642fa295..135a71d5a98e 100644 --- a/eng/common/scripts/eval/invoke-eval-shard.js +++ b/eng/common/scripts/eval/invoke-eval-shard.ts @@ -4,7 +4,7 @@ import { spawnSync } from "node:child_process"; import path from "node:path"; import { fileURLToPath, pathToFileURL } from "node:url"; -import { getVallyShardVerdict } from "./lib/verdict.js"; +import { getVallyShardVerdict } from "./lib/verdict.ts"; // The pinned Vally CLI is installed next to this script (package.json + node_modules live here), // so the npm --prefix is just this file's own directory. @@ -30,6 +30,9 @@ export function runShard({ evalArgs, shardName, outputDir, threshold = 0.8 }) { ); // Do NOT abort on a non-zero exit — the verdict below is authoritative. + // Uses spawnSync (not the vendored execFile helper) on purpose: the shard needs vally's output + // streamed live to the log (stdio: "inherit") and must keep going on a non-zero exit, whereas + // the exec helper captures output and rejects on failure. const proc = spawnSync( "npm", [ diff --git a/eng/common/scripts/eval/lib/exec.ts b/eng/common/scripts/eval/lib/exec.ts new file mode 100644 index 000000000000..3bddedcf06a4 --- /dev/null +++ b/eng/common/scripts/eval/lib/exec.ts @@ -0,0 +1,139 @@ +// Secure process/exec primitives (execFile wrapper with logging + a larger default maxBuffer). +// +// PROVENANCE: Copied from azure-rest-api-specs .github/shared/src/exec.js +// @ ef7dd74c13aa9ca12b67b33b9dc4b5d1419a46f0 and ported to TypeScript (erasable syntax only, +// run via Node native type stripping). See azure-sdk-tools#16296 for the plan to share these +// primitives properly instead of copying. Kept under eng/common/scripts/eval/lib so it travels +// with the eng/common sync into the language repos (unlike .github/shared, which does not sync); +// this is why the folder path differs from the specs repo. + +import child_process from "node:child_process"; +import { dirname, join } from "node:path"; +import { promisify } from "node:util"; + +const execFileImpl = promisify(child_process.execFile); + +// Minimal logger contract used by the exec helpers (subset of the specs repo ILogger). +export interface ILogger { + info(message: string): void; + debug(message: string): void; +} + +export interface ExecOptions { + /** Current working directory. Default: process.cwd(). */ + cwd?: string; + logger?: ILogger; + /** Max bytes allowed on stdout or stderr. Default: 16 * 1024 * 1024. */ + maxBuffer?: number; +} + +export interface NpmPrefixOptions { + /** Prefix to pass to npm via "--prefix". */ + prefix?: string; +} + +export type ExecNpmOptions = ExecOptions & NpmPrefixOptions; + +export interface ExecResult { + stdout: string; + stderr: string; +} + +export type ExecError = Error & { stdout?: string; stderr?: string; code?: number }; + +/** + * Checks whether an unknown error object is an ExecError. + */ +export function isExecError(error: unknown): error is ExecError { + if (!(error instanceof Error)) return false; + + const e = error as ExecError; + return typeof e.stdout === "string" || typeof e.stderr === "string"; +} + +/** + * Wraps `child_process.execFile()`, adding logging and a larger default maxBuffer. + * + * @throws {ExecError} + */ +export async function execFile( + file: string, + args?: string[], + options: ExecOptions = {}, +): Promise { + const { + cwd, + logger, + // Node default is 1024 * 1024, which is too small for some git commands returning many + // entities or large file content. To support "git show", should be larger than the largest + // swagger file in the repo (2.5 MB as of 2/28/2025). + maxBuffer = 16 * 1024 * 1024, + } = options; + + logger?.info(`execFile("${file}", ${JSON.stringify(args)})`); + + try { + // execFile(file, args) is more secure than exec(cmd), since the latter is vulnerable to + // shell injection. + const result = await execFileImpl(file, args, { + cwd, + maxBuffer, + }); + + logger?.debug(`stdout: '${result.stdout}'`); + logger?.debug(`stderr: '${result.stderr}'`); + + return result; + } catch (error) { + /* v8 ignore next */ + logger?.debug(`error: '${JSON.stringify(error)}'`); + + throw error; + } +} + +/** + * Calls `execFile()` with appropriate arguments to run `npm` on all platforms. + * + * @throws {ExecError} + */ +export async function execNpm(args: string[], options: ExecNpmOptions = {}): Promise { + const { prefix } = options; + + // Exclude platform-specific code from coverage + /* v8 ignore start */ + const { file, defaultArgs } = + process.platform === "win32" + ? { + // Only way I could find to run "npm" on Windows, without using the shell (e.g. + // "cmd /c npm ...") + // + // "node.exe", ["--", "npm-cli.js", ...args] + // + // The "--" MUST come BEFORE "npm-cli.js", to ensure args are sent to the script + // unchanged. If the "--" comes after "npm-cli.js", the args sent to the script will be + // ["--", ...args], which is NOT equivalent, and can break if args itself contains + // another "--". + + // example: "C:\Program Files\nodejs\node.exe" + file: process.execPath, + + // example: "C:\Program Files\nodejs\node_modules\npm\bin\npm-cli.js" + defaultArgs: ["--", join(dirname(process.execPath), "node_modules", "npm", "bin", "npm-cli.js")], + } + : { file: "npm", defaultArgs: [] as string[] }; + /* v8 ignore stop */ + + const prefixArgs = prefix ? ["--prefix", prefix] : []; + + return await execFile(file, [...defaultArgs, ...prefixArgs, ...args], options); +} + +/** + * Calls `execNpm()` with arguments ["exec", "--no", "--"] prepended. + * + * @throws {ExecError} + */ +export async function execNpmExec(args: string[], options: ExecNpmOptions = {}): Promise { + return await execNpm(["exec", "--no", "--", ...args], options); +} diff --git a/eng/common/scripts/eval/lib/glob.js b/eng/common/scripts/eval/lib/glob.ts similarity index 100% rename from eng/common/scripts/eval/lib/glob.js rename to eng/common/scripts/eval/lib/glob.ts diff --git a/eng/common/scripts/eval/lib/verdict.js b/eng/common/scripts/eval/lib/verdict.ts similarity index 98% rename from eng/common/scripts/eval/lib/verdict.js rename to eng/common/scripts/eval/lib/verdict.ts index a496fae4dbca..330c59be75c0 100644 --- a/eng/common/scripts/eval/lib/verdict.js +++ b/eng/common/scripts/eval/lib/verdict.ts @@ -5,7 +5,7 @@ import fs from "node:fs"; import path from "node:path"; -import { globFiles } from "./glob.js"; +import { globFiles } from "./glob.ts"; // Formats a 0..1 ratio as a fixed-1-decimal percentage string (e.g. 97.1). function pct(ratio) { diff --git a/eng/common/scripts/eval/package.json b/eng/common/scripts/eval/package.json index 3f852ffac19d..531ef3dfe51e 100644 --- a/eng/common/scripts/eval/package.json +++ b/eng/common/scripts/eval/package.json @@ -5,10 +5,10 @@ "description": "Vally eval CI glue scripts (matrix sharding, shard runner, JUnit summary) plus the pinned @microsoft/vally-cli the shards install from the committed lockfile. Synced via eng/common; not published.", "type": "module", "engines": { - "node": ">=18" + "node": ">=22.6" }, "scripts": { - "test": "node --test" + "test": "node --experimental-strip-types --test" }, "devDependencies": { "@microsoft/vally-cli": "0.6.0" diff --git a/eng/common/scripts/eval/sync-eval-git-repo.js b/eng/common/scripts/eval/sync-eval-git-repo.ts similarity index 71% rename from eng/common/scripts/eval/sync-eval-git-repo.js rename to eng/common/scripts/eval/sync-eval-git-repo.ts index 6cb835161150..98929f010992 100644 --- a/eng/common/scripts/eval/sync-eval-git-repo.js +++ b/eng/common/scripts/eval/sync-eval-git-repo.ts @@ -3,20 +3,22 @@ // fetch + checkout. Primes the cache Vally's `environment.git` fixtures point at; FETCH_HEAD // is landed on a local branch named so `git worktree add --detach ` resolves. -import { spawnSync } from "node:child_process"; import fs from "node:fs"; import path from "node:path"; import { pathToFileURL } from "node:url"; +import { execFile, isExecError } from "./lib/exec.ts"; -// Throws on non-zero git exit so a failed clone stops immediately. -// NOTE: azure-rest-api-specs ships shared exec primitives (.github/shared/src/exec.js), but -// they aren't importable here — eng/common has no cross-repo dependency on that package and -// those helpers carry specs-repo-specific assumptions. This intentionally stays a tiny local -// wrapper; revisit if a shared eng/common exec utility is ever introduced. -function invokeGit(args) { - const proc = spawnSync("git", args, { stdio: ["ignore", "ignore", "inherit"] }); - if (proc.status !== 0) { - throw new Error(`git ${args.join(" ")} failed (exit ${proc.status})`); +// Throws on non-zero git exit so a failed clone stops immediately. Delegates to the shared +// execFile helper (copied from azure-rest-api-specs; see lib/exec.ts), which runs git without a +// shell (no injection) and captures output; git's stderr is surfaced only when the command fails. +async function invokeGit(args: string[]): Promise { + try { + await execFile("git", args); + } catch (error) { + if (isExecError(error) && error.stderr) { + process.stderr.write(error.stderr); + } + throw new Error(`git ${args.join(" ")} failed`); } } @@ -30,9 +32,9 @@ function invokeGit(args) { * @param {string} [options.ref] Branch/ref to check out. * @param {string[]} [options.sparseCheckoutPaths] Cone-sparse paths (pass [] for full tree). * @param {number} [options.maxAgeHours] Skip the refresh fetch if cached within this window. - * @returns {string} The cache path. + * @returns {Promise} The cache path. */ -export function syncRepo({ +export async function syncRepo({ cacheRoot, repoUrl = "https://github.com/Azure/azure-rest-api-specs.git", repoName = "azure-rest-api-specs", @@ -50,16 +52,16 @@ export function syncRepo({ console.log(`[sync-eval-git-repo] Cloning ${repoName} (${ref}) into cache: ${cache}`); fs.mkdirSync(cache, { recursive: true }); // init + fetch (not clone --depth 1) so any branch/tag/SHA is pinned on a cold cache. - invokeGit(["-C", cache, "init", "--quiet"]); - invokeGit(["-C", cache, "remote", "add", "origin", repoUrl]); + await invokeGit(["-C", cache, "init", "--quiet"]); + await invokeGit(["-C", cache, "remote", "add", "origin", repoUrl]); if (sparseCheckoutPaths.length > 0) { - invokeGit(["-C", cache, "sparse-checkout", "init", "--cone"]); - invokeGit(["-C", cache, "sparse-checkout", "set", ...sparseCheckoutPaths]); + await invokeGit(["-C", cache, "sparse-checkout", "init", "--cone"]); + await invokeGit(["-C", cache, "sparse-checkout", "set", ...sparseCheckoutPaths]); } - invokeGit(["-C", cache, "fetch", "--depth", "1", "--filter=blob:none", "origin", ref]); + await invokeGit(["-C", cache, "fetch", "--depth", "1", "--filter=blob:none", "origin", ref]); // Land FETCH_HEAD on a real local branch named (not detached) so Vally's worktree // fixtures can resolve `git worktree add --detach `. - invokeGit(["-C", cache, "checkout", "-B", ref, "FETCH_HEAD"]); + await invokeGit(["-C", cache, "checkout", "-B", ref, "FETCH_HEAD"]); fs.writeFileSync(stamp, new Date().toISOString()); } else { let stale = true; @@ -69,10 +71,10 @@ export function syncRepo({ } if (stale) { console.log(`[sync-eval-git-repo] Refreshing cache (>${maxAgeHours}h old): ${cache}`); - invokeGit(["-C", cache, "fetch", "--depth", "1", "origin", ref]); + await invokeGit(["-C", cache, "fetch", "--depth", "1", "origin", ref]); // Re-point the local branch at FETCH_HEAD (also repairs a previously detached cache) // so the worktree fixtures keep resolving. - invokeGit(["-C", cache, "checkout", "-B", ref, "FETCH_HEAD"]); + await invokeGit(["-C", cache, "checkout", "-B", ref, "FETCH_HEAD"]); fs.writeFileSync(stamp, new Date().toISOString()); } else { console.log(`[sync-eval-git-repo] Cache is fresh (<${maxAgeHours}h): ${cache}`); @@ -121,11 +123,12 @@ function parseArgs(argv) { } if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) { - try { - const cache = syncRepo(parseArgs(process.argv.slice(2))); - console.log(cache); // echo the cache path so a wrapper can capture it - } catch (error) { - console.error(error.message); - process.exit(1); - } + syncRepo(parseArgs(process.argv.slice(2))) + .then((cache) => { + console.log(cache); // echo the cache path so a wrapper can capture it + }) + .catch((error) => { + console.error(error instanceof Error ? error.message : error); + process.exit(1); + }); } diff --git a/eng/common/scripts/eval/test/build-eval-summary.test.js b/eng/common/scripts/eval/test/build-eval-summary.test.ts similarity index 98% rename from eng/common/scripts/eval/test/build-eval-summary.test.js rename to eng/common/scripts/eval/test/build-eval-summary.test.ts index bda95cd790a4..e1e77dacebc0 100644 --- a/eng/common/scripts/eval/test/build-eval-summary.test.js +++ b/eng/common/scripts/eval/test/build-eval-summary.test.ts @@ -1,4 +1,4 @@ -// node:test unit tests for build-eval-summary.js (port of Build-EvalSummary.Tests.ps1). +// node:test unit tests for build-eval-summary.ts (port of Build-EvalSummary.Tests.ps1). // Run from eng/common/scripts/eval: npm test import assert from "node:assert/strict"; @@ -7,7 +7,7 @@ import os from "node:os"; import path from "node:path"; import { after, before, beforeEach, describe, it } from "node:test"; -import { getEvalSummary, formatEvalSummaryMarkdown } from "../build-eval-summary.js"; +import { getEvalSummary, formatEvalSummaryMarkdown } from "../build-eval-summary.ts"; // Convenience: build the summary and also write the markdown, returning both. function summarize(resultsRoot, outFile) { diff --git a/eng/common/scripts/eval/test/collect-stimuli.test.js b/eng/common/scripts/eval/test/collect-stimuli.test.ts similarity index 98% rename from eng/common/scripts/eval/test/collect-stimuli.test.js rename to eng/common/scripts/eval/test/collect-stimuli.test.ts index ad122b460486..ca0e6ead5036 100644 --- a/eng/common/scripts/eval/test/collect-stimuli.test.js +++ b/eng/common/scripts/eval/test/collect-stimuli.test.ts @@ -1,4 +1,4 @@ -// node:test unit tests for collect-stimuli.js (port of Split-EvalSuite.Tests.ps1). +// node:test unit tests for collect-stimuli.ts (port of Split-EvalSuite.Tests.ps1). // Run from eng/common/scripts/eval: npm test // // Sharding is always by `area` tag: one shard per area, each carrying every eval of that @@ -10,7 +10,7 @@ import os from "node:os"; import path from "node:path"; import { after, before, describe, it } from "node:test"; -import { buildMatrix } from "../collect-stimuli.js"; +import { buildMatrix } from "../collect-stimuli.ts"; // Helper: write a file, creating parent directories as needed. function writeFile(filePath, content) { diff --git a/eng/common/scripts/eval/test/init-eval-git-fixtures.test.js b/eng/common/scripts/eval/test/init-eval-git-fixtures.test.ts similarity index 98% rename from eng/common/scripts/eval/test/init-eval-git-fixtures.test.js rename to eng/common/scripts/eval/test/init-eval-git-fixtures.test.ts index 9f78750970b4..5da2de81e93b 100644 --- a/eng/common/scripts/eval/test/init-eval-git-fixtures.test.js +++ b/eng/common/scripts/eval/test/init-eval-git-fixtures.test.ts @@ -1,4 +1,4 @@ -// Tests for init-eval-git-fixtures.js — discovery only (the dry-run path that clones nothing). +// Tests for init-eval-git-fixtures.ts — discovery only (the dry-run path that clones nothing). import assert from "node:assert/strict"; import fs from "node:fs"; @@ -7,7 +7,7 @@ import path from "node:path"; import { fileURLToPath } from "node:url"; import { after, before, describe, it } from "node:test"; -import { dedupeFixtures, getEvalGitFixtures } from "../init-eval-git-fixtures.js"; +import { dedupeFixtures, getEvalGitFixtures } from "../init-eval-git-fixtures.ts"; const here = path.dirname(fileURLToPath(import.meta.url)); diff --git a/eng/common/scripts/eval/test/verdict.test.js b/eng/common/scripts/eval/test/verdict.test.ts similarity index 97% rename from eng/common/scripts/eval/test/verdict.test.js rename to eng/common/scripts/eval/test/verdict.test.ts index 8e8f6acc8e14..fe4978ea5bc4 100644 --- a/eng/common/scripts/eval/test/verdict.test.js +++ b/eng/common/scripts/eval/test/verdict.test.ts @@ -1,4 +1,4 @@ -// node:test unit tests for lib/verdict.js (port of Invoke-EvalShard.Tests.ps1, which +// node:test unit tests for lib/verdict.ts (port of Invoke-EvalShard.Tests.ps1, which // exercised the verdict helpers). Run from eng/common/scripts/eval: npm test import assert from "node:assert/strict"; @@ -7,7 +7,7 @@ import os from "node:os"; import path from "node:path"; import { after, before, describe, it } from "node:test"; -import { getVallyShardVerdict } from "../lib/verdict.js"; +import { getVallyShardVerdict } from "../lib/verdict.ts"; describe("getVallyShardVerdict", () => { let root; From 2b6f6d1d90bfd0be015a19cdc37a729e8122c892 Mon Sep 17 00:00:00 2001 From: "azure-sdk-automation[bot]" <191533747+azure-sdk-automation[bot]@users.noreply.github.com> Date: Tue, 14 Jul 2026 21:36:20 +0000 Subject: [PATCH 5/6] Updated to align with review comments. (#49808) Co-authored-by: ReilleyMilne --- .../instructions/azsdk-tools/typespec-to-sdk.instructions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/common/instructions/azsdk-tools/typespec-to-sdk.instructions.md b/eng/common/instructions/azsdk-tools/typespec-to-sdk.instructions.md index 4d0e4bb2e39e..c4dbf7813b76 100644 --- a/eng/common/instructions/azsdk-tools/typespec-to-sdk.instructions.md +++ b/eng/common/instructions/azsdk-tools/typespec-to-sdk.instructions.md @@ -52,7 +52,7 @@ Follow the steps in #file:.github/skills/azsdk-common-generate-sdk-locally/SKILL For data plane: `Python`, `.NET`, `JavaScript`, `Java` - Each SDK generation tool call should show a label to indicate the language being generated. 2. Monitor pipeline status after 15 minutes and provide updates. If pipeline is in progress, inform user that it may take additional time and check the status later. -3. Display generated SDK PR links when available. If pipeline fails, inform user with error details and suggest to check pipeline logs for more information. Use the `azsdk-common-pipeline-troubleshooting` skill to diagnose and resolve pipeline failures. +3. Display generated SDK PR links when available. If pipeline fails, inform user with error details and suggest to check pipeline logs for more information. Use the `azsdk-common-pipeline-analysis` skill to diagnose and resolve pipeline failures. 4. If SDK pull request is available for all languages, ask user to review generated SDK pull request and mark them as ready for review when they are ready to get them reviewed and merged. If APIView feedback is received, use the `azsdk-common-apiview-feedback-resolution` skill to analyze and resolve review comments. 5. Inform the user that they can checkout generated SDK pull request locally and add more tests, samples or code customizations if needed using local SDK generation tools. 6. If SDK pull request was created for test purposes, inform user to close the test SDK pull request. From f77047b9d01dee1ee791e2e50671f7664c480878 Mon Sep 17 00:00:00 2001 From: "azure-sdk-automation[bot]" <191533747+azure-sdk-automation[bot]@users.noreply.github.com> Date: Tue, 14 Jul 2026 18:10:57 -0400 Subject: [PATCH 6/6] Update release pending status and pipeline URL in release plan (#49817) Update release pending status and pipeline URL in release plan --- .../stages/archetype-auto-release-prepare.yml | 4 ++ .../scripts/Mark-ReleasePlanCompletion.ps1 | 19 +++++++- .../scripts/Resolve-AutoReleasePackages.ps1 | 44 ++++++++++++++++++- 3 files changed, 65 insertions(+), 2 deletions(-) diff --git a/eng/common/pipelines/templates/stages/archetype-auto-release-prepare.yml b/eng/common/pipelines/templates/stages/archetype-auto-release-prepare.yml index 5b8d6b9e592a..038f1d5e5c9c 100644 --- a/eng/common/pipelines/templates/stages/archetype-auto-release-prepare.yml +++ b/eng/common/pipelines/templates/stages/archetype-auto-release-prepare.yml @@ -54,6 +54,8 @@ stages: # the in-script azure-sdk-tools install resolves from an authenticated, reachable feed). - ${{ parameters.PreSteps }} + - template: /eng/common/pipelines/templates/steps/install-azsdk-cli.yml + - task: PowerShell@2 name: resolve displayName: Determine releasable packages @@ -68,3 +70,5 @@ stages: arguments: > -CommitSha "$(Build.SourceVersion)" -RepoId "$(Build.Repository.Name)" + -PipelineUrl "$(System.CollectionUri)$(System.TeamProject)/_build/results?buildId=$(Build.BuildId)" + -AzsdkExePath "$(AZSDK)" diff --git a/eng/common/scripts/Mark-ReleasePlanCompletion.ps1 b/eng/common/scripts/Mark-ReleasePlanCompletion.ps1 index 1ff17d633b2f..7d5a5ed122f1 100644 --- a/eng/common/scripts/Mark-ReleasePlanCompletion.ps1 +++ b/eng/common/scripts/Mark-ReleasePlanCompletion.ps1 @@ -49,7 +49,24 @@ function Process-Package([string]$packageInfoPath) Write-Host "Marking release completion for package, name: $PackageName" $PackageVersion = $pkgInfo.Version - $releaseArgs = @("release-plan", "update-release-status", "--package-name", $PackageName, "--language", $LanguageDisplayName, "--status", "Released") + $version = [AzureEngSemanticVersion]::ParseVersionString($PackageVersion) + if (!$version) + { + Write-Host "Failed to parse version string '$($PackageVersion)' for package '$PackageName'. Skipping the release plan status update." + return + } + + $sdkReleaseType = "" + if ($version.IsPrerelease) + { + $sdkReleaseType = "beta" + } + else + { + $sdkReleaseType = "stable" + } + + $releaseArgs = @("release-plan", "update-release-status", "--package-name", $PackageName, "--language", $LanguageDisplayName, "--status", "Released", "--sdk-release-type", $sdkReleaseType) if ($PackageVersion) { $releaseArgs += @("--package-version", $PackageVersion) diff --git a/eng/common/scripts/Resolve-AutoReleasePackages.ps1 b/eng/common/scripts/Resolve-AutoReleasePackages.ps1 index 0c9823dfc9ce..2be70bcd53a4 100644 --- a/eng/common/scripts/Resolve-AutoReleasePackages.ps1 +++ b/eng/common/scripts/Resolve-AutoReleasePackages.ps1 @@ -47,6 +47,12 @@ The GitHub PR label that opts a merged PR into auto-release. Defaults to 'auto-r .PARAMETER BaseBranch The base branch a PR must have been merged into to qualify. Defaults to 'main'. +.PARAMETER PipelineUrl +The URL of the pipeline run, used for logging or linking back to the pipeline. Defaults to empty. + +.PARAMETER AzsdkExePath +The path to the azsdk executable used for release operations. Defaults to the AZSDK environment variable. + .OUTPUTS Azure DevOps output variables (reference cross-stage via dependencies..outputs['..']): - HasAutoReleaseArtifacts : 'true' if at least one declared package is releasable @@ -63,7 +69,9 @@ param( [string] $Artifacts = $env:AUTORELEASE_ARTIFACTS, [string] $AuthToken = $env:GH_TOKEN, [string] $AutoReleaseLabel = 'auto-release', - [string] $BaseBranch = 'main' + [string] $BaseBranch = 'main', + [string] $PipelineUrl = '', + [string] $AzsdkExePath = $env:AZSDK ) $ErrorActionPreference = 'Stop' @@ -186,6 +194,40 @@ function Invoke-AutoReleaseResolution { Write-Host " [$name] changed by PR $prLink -> releasable." Set-PipelineVariable -Name "ReleaseArtifact_$safeName" -Value 'true' -IsOutput $matchedArtifacts += $artifact + + # Update release pending status and release pipeline URL in the release plan for this package. + # release status is updated as "Released" when the package has been successfully released; here we are marking it as "Approval Pending" to indicate that the release is awaiting approval. + try + { + if($AzsdkExePath) + { + $sdkPullRequestUrl = $pr.html_url + $cliArgs = @("release-plan", "update-release-status", "--package-name", $name, "--language", $LanguageDisplayName, "--status", "Approval Pending", "--sdk-pull-request", $sdkPullRequestUrl) + if ($PipelineUrl) + { + $cliArgs += @("--release-pipeline", $PipelineUrl) + } + else + { + LogWarning "Pipeline URL is not set; Not setting release pipeline link for package '$name' in release plan." + } + + & $AzsdkExePath @cliArgs + if ($LASTEXITCODE -ne 0) + { + ## Not all releases have a release plan. So we should not fail the script even if a release plan is missing. + Write-Host "Failed to update release pending status for package '$name' using azsdk. Exit code: $LASTEXITCODE" + } + } + else + { + Write-Host "AzsdkExePath is not set; skipping release plan update for package '$name'." + } + } + catch + { + Write-Host "Failed to update release pending status in release plan for package '$name'. $($_.Exception.Message)" + } } else { Write-Host " [$name] not changed by PR $prLink."