Skip to content

Commit c2bad81

Browse files
authored
Rhurey/remove sync (Azure#52946)
* Remove sync API's and make AgentOptions internal * Parsing errors are errors * Update changelog * Update test * Latest TS Update * Change casing of file * Update for moved spec files
1 parent 9ab9e1e commit c2bad81

37 files changed

+165
-815
lines changed

sdk/ai/Azure.AI.VoiceLive/CHANGELOG.md

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,33 @@
11
# Release History
22

3-
## 1.0.0-beta.4 (Unreleased)
4-
5-
### Features Added
3+
## 1.0.0-beta.4 (2025-09-30)
64

75
### Breaking Changes
86

9-
### Bugs Fixed
10-
11-
### Other Changes
7+
- Removed all synchronous methods from `VoiceLiveClient` and `VoiceLiveSession` classes.
8+
- `VoiceLiveClient.StartSession()` - use `StartSessionAsync()` instead
9+
- `VoiceLiveSession.AddItem()` - use `AddItemAsync()` instead
10+
- `VoiceLiveSession.AppendAudioToTurn()` - use `AppendAudioToTurnAsync()` instead
11+
- `VoiceLiveSession.CancelAudioTurn()` - use `CancelAudioTurnAsync()` instead
12+
- `VoiceLiveSession.CancelResponse()` - use `CancelResponseAsync()` instead
13+
- `VoiceLiveSession.ClearInputAudio()` - use `ClearInputAudioAsync()` instead
14+
- `VoiceLiveSession.ClearStreamingAudio()` - use `ClearStreamingAudioAsync()` instead
15+
- `VoiceLiveSession.Close()` - use `CloseAsync()` instead
16+
- `VoiceLiveSession.CommitInputAudio()` - use `CommitInputAudioAsync()` instead
17+
- `VoiceLiveSession.ConfigureSession()` - use `ConfigureSessionAsync()` instead
18+
- `VoiceLiveSession.Connect()` - use `ConnectAsync()` instead
19+
- `VoiceLiveSession.ConnectAvatar()` - use `ConnectAvatarAsync()` instead
20+
- `VoiceLiveSession.DeleteItem()` - use `DeleteItemAsync()` instead
21+
- `VoiceLiveSession.EndAudioTurn()` - use `EndAudioTurnAsync()` instead
22+
- `VoiceLiveSession.GetUpdates()` - use `GetUpdatesAsync()` instead
23+
- `VoiceLiveSession.ReceiveUpdates()` - use `ReceiveUpdatesAsync()` instead
24+
- `VoiceLiveSession.RequestItemRetrieval()` - use `RequestItemRetrievalAsync()` instead
25+
- `VoiceLiveSession.SendCommand()` - use `SendCommandAsync()` instead
26+
- `VoiceLiveSession.SendInputAudio()` - use `SendInputAudioAsync()` instead
27+
- `VoiceLiveSession.StartAudioTurn()` - use `StartAudioTurnAsync()` instead
28+
- `VoiceLiveSession.StartResponse()` - use `StartResponseAsync()` instead
29+
- `VoiceLiveSession.TruncateConversation()` - use `TruncateConversationAsync()` instead
30+
- Removed `RespondingAgentOptions` and associated property usage.
1231

1332
## 1.0.0-beta.3 (2025-09-26)
1433

sdk/ai/Azure.AI.VoiceLive/api/Azure.AI.VoiceLive.net8.0.cs

Lines changed: 0 additions & 50 deletions
Large diffs are not rendered by default.

sdk/ai/Azure.AI.VoiceLive/api/Azure.AI.VoiceLive.netstandard2.0.cs

Lines changed: 0 additions & 50 deletions
Large diffs are not rendered by default.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
#nullable disable
5+
6+
using System;
7+
using System.Collections.Generic;
8+
9+
namespace Azure.AI.VoiceLive
10+
{
11+
/// <summary> Configuration for the agent. </summary>
12+
internal partial class RespondingAgentOptions
13+
{}
14+
}

sdk/ai/Azure.AI.VoiceLive/src/Customizations/VoiceLiveSession.Commands.cs

Lines changed: 0 additions & 236 deletions
Large diffs are not rendered by default.

sdk/ai/Azure.AI.VoiceLive/src/Customizations/VoiceLiveSession.Protocol.cs

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -74,19 +74,6 @@ protected internal virtual async Task ConnectAsync(IDictionary<string, string> h
7474
}
7575
}
7676

77-
/// <summary>
78-
/// Initializes an underlying <see cref="WebSocket"/> instance for communication with the VoiceLive service and
79-
/// then connects to the service using this socket.
80-
/// </summary>
81-
/// <param name="cancellationToken">The cancellation token to use.</param>
82-
/// <param name="headers">Headers to send.</param>
83-
protected internal virtual void Connect(IDictionary<string, string> headers, CancellationToken cancellationToken = default)
84-
{
85-
#pragma warning disable AZC0106
86-
ConnectAsync(headers, cancellationToken).EnsureCompleted();
87-
#pragma warning restore AZC0106
88-
}
89-
9077
/// <summary>
9178
/// Closes the WebSocket connection gracefully.
9279
/// </summary>
@@ -110,17 +97,6 @@ await WebSocket.CloseAsync(
11097
}
11198
}
11299

113-
/// <summary>
114-
/// Closes the WebSocket connection gracefully.
115-
/// </summary>
116-
/// <param name="cancellationToken">The cancellation token to use.</param>
117-
public virtual void Close(CancellationToken cancellationToken = default)
118-
{
119-
#pragma warning disable AZC0107
120-
CloseAsync(cancellationToken).EnsureCompleted();
121-
#pragma warning restore AZC0107
122-
}
123-
124100
/// <summary>
125101
/// Gets the current state of the WebSocket connection.
126102
/// </summary>

sdk/ai/Azure.AI.VoiceLive/src/Customizations/VoiceLiveSession.Updates.cs

Lines changed: 6 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -68,20 +68,6 @@ public async IAsyncEnumerable<SessionUpdate> GetUpdatesAsync([EnumeratorCancella
6868
}
6969
}
7070

71-
/// <summary>
72-
/// Gets all server events from the VoiceLive service synchronously.
73-
/// </summary>
74-
/// <param name="cancellationToken">The cancellation token to use.</param>
75-
/// <returns>An enumerable of VoiceLive server events.</returns>
76-
/// <remarks>
77-
/// This method provides synchronous access to all server events from the service.
78-
/// For better performance and resource utilization, consider using <see cref="GetUpdatesAsync(CancellationToken)"/> instead.
79-
/// </remarks>
80-
public IEnumerable<SessionUpdate> GetUpdates(CancellationToken cancellationToken = default)
81-
{
82-
return GetUpdatesAsync(cancellationToken).ToBlockingEnumerable(cancellationToken);
83-
}
84-
8571
/// <summary>
8672
/// Gets server events of a specific type from the VoiceLive service.
8773
/// </summary>
@@ -130,25 +116,13 @@ private IEnumerable<SessionUpdate> ProcessMessage(BinaryData message)
130116
}
131117

132118
SessionUpdate sessionUpdate = null;
133-
try
134-
{
135-
// Try to parse as JSON first
136-
using JsonDocument document = JsonDocument.Parse(message);
137-
JsonElement root = document.RootElement;
138119

139-
// Deserialize as a server event
140-
sessionUpdate = SessionUpdate.DeserializeSessionUpdate(root, ModelSerializationExtensions.WireOptions);
141-
}
142-
catch (JsonException)
143-
{
144-
// If JSON parsing fails, ignore the message
145-
yield break;
146-
}
147-
catch (Exception)
148-
{
149-
// If deserialization fails completely, ignore the message
150-
yield break;
151-
}
120+
// Try to parse as JSON first
121+
using JsonDocument document = JsonDocument.Parse(message);
122+
JsonElement root = document.RootElement;
123+
124+
// Deserialize as a server event
125+
sessionUpdate = SessionUpdate.DeserializeSessionUpdate(root, ModelSerializationExtensions.WireOptions);
152126

153127
if (sessionUpdate != null)
154128
{

sdk/ai/Azure.AI.VoiceLive/src/Customizations/VoiceLiveSession.cs

Lines changed: 0 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -139,60 +139,6 @@ public virtual async Task SendInputAudioAsync(Stream audio, CancellationToken ca
139139
}
140140
}
141141

142-
/// <summary>
143-
/// Transmits audio data from a stream, ending the client turn once the stream is complete.
144-
/// </summary>
145-
/// <param name="audio">The audio stream to transmit.</param>
146-
/// <param name="cancellationToken">An optional cancellation token.</param>
147-
/// <exception cref="ArgumentNullException">Thrown when <paramref name="audio"/> is null.</exception>
148-
/// <exception cref="InvalidOperationException">Thrown when another audio stream is already being sent.</exception>
149-
public virtual void SendInputAudio(Stream audio, CancellationToken cancellationToken = default)
150-
{
151-
Argument.AssertNotNull(audio, nameof(audio));
152-
ThrowIfDisposed();
153-
154-
using (_audioSendSemaphore.AutoReleaseWait(cancellationToken))
155-
{
156-
if (_isSendingAudioStream)
157-
{
158-
throw new InvalidOperationException("Only one stream of audio may be sent at once.");
159-
}
160-
_isSendingAudioStream = true;
161-
}
162-
163-
byte[] buffer = null;
164-
try
165-
{
166-
buffer = ArrayPool<byte>.Shared.Rent(1024 * 16);
167-
while (true)
168-
{
169-
int bytesRead = audio.Read(buffer, 0, buffer.Length);
170-
if (bytesRead == 0)
171-
{
172-
break;
173-
}
174-
175-
ReadOnlyMemory<byte> audioMemory = buffer.AsMemory(0, bytesRead);
176-
BinaryData audioData = BinaryData.FromBytes(audioMemory);
177-
string base64Audio = Convert.ToBase64String(audioData.ToArray());
178-
ClientEventInputAudioBufferAppend appendCommand = new(base64Audio);
179-
BinaryData requestData = BinaryData.FromObjectAsJson(appendCommand);
180-
SendCommand(requestData, cancellationToken);
181-
}
182-
}
183-
finally
184-
{
185-
if (buffer is not null)
186-
{
187-
ArrayPool<byte>.Shared.Return(buffer);
188-
}
189-
using (_audioSendSemaphore.AutoReleaseWait(cancellationToken))
190-
{
191-
_isSendingAudioStream = false;
192-
}
193-
}
194-
}
195-
196142
/// <summary>
197143
/// Sends a command to the service asynchronously.
198144
/// </summary>
@@ -209,21 +155,6 @@ internal virtual async Task SendCommandAsync(ClientEvent command, CancellationTo
209155
await SendCommandAsync(data, cancellationToken).ConfigureAwait(false);
210156
}
211157

212-
/// <summary>
213-
/// Sends a command to the service.
214-
/// </summary>
215-
/// <param name="command">The command to send.</param>
216-
/// <param name="cancellationToken">The cancellation token to use.</param>
217-
/// <exception cref="ArgumentNullException">Thrown when <paramref name="command"/> is null.</exception>
218-
internal virtual void SendCommand(ClientEvent command, CancellationToken cancellationToken = default)
219-
{
220-
Argument.AssertNotNull(command, nameof(command));
221-
ThrowIfDisposed();
222-
223-
BinaryData data = BinaryData.FromObjectAsJson(command);
224-
SendCommand(data, cancellationToken);
225-
}
226-
227158
/// <summary>
228159
/// Sends raw data to the service asynchronously.
229160
/// </summary>
@@ -274,20 +205,6 @@ public virtual async Task SendCommandAsync(RequestContent data, CancellationToke
274205
await SendCommandAsync(BinaryData.FromStream(ms), cancellationToken).ConfigureAwait(false);
275206
}
276207

277-
#pragma warning disable AZC0107 // Client methods should return approved types
278-
/// <summary>
279-
/// Sends raw data to the service.
280-
/// </summary>
281-
/// <param name="data">The data to send.</param>
282-
/// <param name="cancellationToken">The cancellation token to use.</param>
283-
/// <exception cref="ArgumentNullException">Thrown when <paramref name="data"/> is null.</exception>
284-
public virtual void SendCommand(BinaryData data, CancellationToken cancellationToken = default)
285-
{
286-
// ClientWebSocket does not include a synchronous Send()
287-
SendCommandAsync(data, cancellationToken).EnsureCompleted();
288-
}
289-
#pragma warning restore AZC0107
290-
291208
/// <summary>
292209
/// Receives updates from the service asynchronously.
293210
/// </summary>
@@ -308,16 +225,6 @@ public virtual async IAsyncEnumerable<BinaryData> ReceiveUpdatesAsync([Enumerato
308225
}
309226
}
310227

311-
/// <summary>
312-
/// Receives updates from the service.
313-
/// </summary>
314-
/// <param name="cancellationToken">The cancellation token to use.</param>
315-
/// <returns>An enumerable of binary data messages.</returns>
316-
public virtual IEnumerable<BinaryData> ReceiveUpdates(CancellationToken cancellationToken = default)
317-
{
318-
throw new NotSupportedException("Synchronous enumeration of WebSocket messages is not supported. Use ReceiveUpdatesAsync instead.");
319-
}
320-
321228
/// <inheritdoc/>
322229
public void Dispose()
323230
{
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
#nullable disable
5+
6+
using System;
7+
using System.Collections.Generic;
8+
9+
namespace Azure.AI.VoiceLive
10+
{
11+
/// <summary> Base for session configuration in the response. </summary>
12+
public partial class VoiceLiveSessionResponse : VoiceLiveSessionOptions
13+
{
14+
/// <summary> The agent configuration for the session, if applicable. </summary>
15+
internal RespondingAgentOptions Agent { get; }
16+
}
17+
}

sdk/ai/Azure.AI.VoiceLive/src/Generated/AzureSemanticEouDetection.Serialization.cs

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)