Skip to content

Commit 57c7164

Browse files
authored
Refactor Start*Session methods in RealtimeClient (#658)
Replaced the `RequestOptions` parameter for a new `RealtimeSessionOptions` parameter and a `CancellationToken` parameter.
1 parent 9b23df7 commit 57c7164

File tree

9 files changed

+203
-159
lines changed

9 files changed

+203
-159
lines changed

api/OpenAI.net8.0.cs

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4346,13 +4346,12 @@ public class RealtimeClient {
43464346
public virtual Task<ClientResult> CreateEphemeralTokenAsync(BinaryContent content, RequestOptions options = null);
43474347
public virtual ClientResult CreateEphemeralTranscriptionToken(BinaryContent content, RequestOptions options = null);
43484348
public virtual Task<ClientResult> CreateEphemeralTranscriptionTokenAsync(BinaryContent content, RequestOptions options = null);
4349-
public RealtimeSession StartConversationSession(string model, CancellationToken cancellationToken = default);
4350-
public virtual Task<RealtimeSession> StartConversationSessionAsync(string model, RequestOptions options);
4351-
public virtual Task<RealtimeSession> StartConversationSessionAsync(string model, CancellationToken cancellationToken = default);
4352-
public virtual Task<RealtimeSession> StartSessionAsync(string model, string intent, RequestOptions options);
4353-
public RealtimeSession StartTranscriptionSession(CancellationToken cancellationToken = default);
4354-
public virtual Task<RealtimeSession> StartTranscriptionSessionAsync(RequestOptions options);
4355-
public virtual Task<RealtimeSession> StartTranscriptionSessionAsync(CancellationToken cancellationToken = default);
4349+
public RealtimeSession StartConversationSession(string model, RealtimeSessionOptions options = null, CancellationToken cancellationToken = default);
4350+
public virtual Task<RealtimeSession> StartConversationSessionAsync(string model, RealtimeSessionOptions options = null, CancellationToken cancellationToken = default);
4351+
public RealtimeSession StartSession(string model, string intent, RealtimeSessionOptions options = null, CancellationToken cancellationToken = default);
4352+
public virtual Task<RealtimeSession> StartSessionAsync(string model, string intent, RealtimeSessionOptions options = null, CancellationToken cancellationToken = default);
4353+
public RealtimeSession StartTranscriptionSession(RealtimeSessionOptions options = null, CancellationToken cancellationToken = default);
4354+
public virtual Task<RealtimeSession> StartTranscriptionSessionAsync(RealtimeSessionOptions options = null, CancellationToken cancellationToken = default);
43564355
}
43574356
[Experimental("OPENAI002")]
43584357
[Flags]
@@ -4392,7 +4391,7 @@ public class RealtimeItem : IJsonModel<RealtimeItem>, IPersistableModel<Realtime
43924391
}
43934392
[Experimental("OPENAI002")]
43944393
public class RealtimeSession : IDisposable {
4395-
protected internal RealtimeSession(RealtimeClient parentClient, Uri endpoint, ApiKeyCredential credential);
4394+
protected internal RealtimeSession(ApiKeyCredential credential, RealtimeClient parentClient, Uri endpoint, string model, string intent);
43964395
public Net.WebSockets.WebSocket WebSocket { get; protected set; }
43974396
public virtual void AddItem(RealtimeItem item, string previousItemId, CancellationToken cancellationToken = default);
43984397
public virtual void AddItem(RealtimeItem item, CancellationToken cancellationToken = default);
@@ -4408,8 +4407,8 @@ public class RealtimeSession : IDisposable {
44084407
public virtual void ConfigureSession(ConversationSessionOptions sessionOptions, CancellationToken cancellationToken = default);
44094408
public virtual void ConfigureTranscriptionSession(TranscriptionSessionOptions sessionOptions, CancellationToken cancellationToken = default);
44104409
public virtual Task ConfigureTranscriptionSessionAsync(TranscriptionSessionOptions sessionOptions, CancellationToken cancellationToken = default);
4411-
protected internal virtual void Connect(RequestOptions options);
4412-
protected internal virtual Task ConnectAsync(RequestOptions options);
4410+
protected internal virtual void Connect(string queryString = null, IDictionary<string, string> headers = null, CancellationToken cancellationToken = default);
4411+
protected internal virtual Task ConnectAsync(string queryString = null, IDictionary<string, string> headers = null, CancellationToken cancellationToken = default);
44134412
public virtual void DeleteItem(string itemId, CancellationToken cancellationToken = default);
44144413
public virtual Task DeleteItemAsync(string itemId, CancellationToken cancellationToken = default);
44154414
public void Dispose();
@@ -4435,6 +4434,11 @@ public class RealtimeSession : IDisposable {
44354434
public virtual Task TruncateItemAsync(string itemId, int contentPartIndex, TimeSpan audioDuration, CancellationToken cancellationToken = default);
44364435
}
44374436
[Experimental("OPENAI002")]
4437+
public class RealtimeSessionOptions {
4438+
public IDictionary<string, string> Headers { get; }
4439+
public string QueryString { get; set; }
4440+
}
4441+
[Experimental("OPENAI002")]
44384442
public class RealtimeUpdate : IJsonModel<RealtimeUpdate>, IPersistableModel<RealtimeUpdate> {
44394443
public string EventId { get; }
44404444
public RealtimeUpdateKind Kind { get; }

api/OpenAI.netstandard2.0.cs

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3794,13 +3794,12 @@ public class RealtimeClient {
37943794
public virtual Task<ClientResult> CreateEphemeralTokenAsync(BinaryContent content, RequestOptions options = null);
37953795
public virtual ClientResult CreateEphemeralTranscriptionToken(BinaryContent content, RequestOptions options = null);
37963796
public virtual Task<ClientResult> CreateEphemeralTranscriptionTokenAsync(BinaryContent content, RequestOptions options = null);
3797-
public RealtimeSession StartConversationSession(string model, CancellationToken cancellationToken = default);
3798-
public virtual Task<RealtimeSession> StartConversationSessionAsync(string model, RequestOptions options);
3799-
public virtual Task<RealtimeSession> StartConversationSessionAsync(string model, CancellationToken cancellationToken = default);
3800-
public virtual Task<RealtimeSession> StartSessionAsync(string model, string intent, RequestOptions options);
3801-
public RealtimeSession StartTranscriptionSession(CancellationToken cancellationToken = default);
3802-
public virtual Task<RealtimeSession> StartTranscriptionSessionAsync(RequestOptions options);
3803-
public virtual Task<RealtimeSession> StartTranscriptionSessionAsync(CancellationToken cancellationToken = default);
3797+
public RealtimeSession StartConversationSession(string model, RealtimeSessionOptions options = null, CancellationToken cancellationToken = default);
3798+
public virtual Task<RealtimeSession> StartConversationSessionAsync(string model, RealtimeSessionOptions options = null, CancellationToken cancellationToken = default);
3799+
public RealtimeSession StartSession(string model, string intent, RealtimeSessionOptions options = null, CancellationToken cancellationToken = default);
3800+
public virtual Task<RealtimeSession> StartSessionAsync(string model, string intent, RealtimeSessionOptions options = null, CancellationToken cancellationToken = default);
3801+
public RealtimeSession StartTranscriptionSession(RealtimeSessionOptions options = null, CancellationToken cancellationToken = default);
3802+
public virtual Task<RealtimeSession> StartTranscriptionSessionAsync(RealtimeSessionOptions options = null, CancellationToken cancellationToken = default);
38043803
}
38053804
[Flags]
38063805
public enum RealtimeContentModalities {
@@ -3836,7 +3835,7 @@ public class RealtimeItem : IJsonModel<RealtimeItem>, IPersistableModel<Realtime
38363835
protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options);
38373836
}
38383837
public class RealtimeSession : IDisposable {
3839-
protected internal RealtimeSession(RealtimeClient parentClient, Uri endpoint, ApiKeyCredential credential);
3838+
protected internal RealtimeSession(ApiKeyCredential credential, RealtimeClient parentClient, Uri endpoint, string model, string intent);
38403839
public Net.WebSockets.WebSocket WebSocket { get; protected set; }
38413840
public virtual void AddItem(RealtimeItem item, string previousItemId, CancellationToken cancellationToken = default);
38423841
public virtual void AddItem(RealtimeItem item, CancellationToken cancellationToken = default);
@@ -3852,8 +3851,8 @@ public class RealtimeSession : IDisposable {
38523851
public virtual void ConfigureSession(ConversationSessionOptions sessionOptions, CancellationToken cancellationToken = default);
38533852
public virtual void ConfigureTranscriptionSession(TranscriptionSessionOptions sessionOptions, CancellationToken cancellationToken = default);
38543853
public virtual Task ConfigureTranscriptionSessionAsync(TranscriptionSessionOptions sessionOptions, CancellationToken cancellationToken = default);
3855-
protected internal virtual void Connect(RequestOptions options);
3856-
protected internal virtual Task ConnectAsync(RequestOptions options);
3854+
protected internal virtual void Connect(string queryString = null, IDictionary<string, string> headers = null, CancellationToken cancellationToken = default);
3855+
protected internal virtual Task ConnectAsync(string queryString = null, IDictionary<string, string> headers = null, CancellationToken cancellationToken = default);
38573856
public virtual void DeleteItem(string itemId, CancellationToken cancellationToken = default);
38583857
public virtual Task DeleteItemAsync(string itemId, CancellationToken cancellationToken = default);
38593858
public void Dispose();
@@ -3878,6 +3877,10 @@ public class RealtimeSession : IDisposable {
38783877
public virtual void TruncateItem(string itemId, int contentPartIndex, TimeSpan audioDuration, CancellationToken cancellationToken = default);
38793878
public virtual Task TruncateItemAsync(string itemId, int contentPartIndex, TimeSpan audioDuration, CancellationToken cancellationToken = default);
38803879
}
3880+
public class RealtimeSessionOptions {
3881+
public IDictionary<string, string> Headers { get; }
3882+
public string QueryString { get; set; }
3883+
}
38813884
public class RealtimeUpdate : IJsonModel<RealtimeUpdate>, IPersistableModel<RealtimeUpdate> {
38823885
public string EventId { get; }
38833886
public RealtimeUpdateKind Kind { get; }
Lines changed: 74 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.ClientModel;
33
using System.ClientModel.Primitives;
4+
using System.Threading;
45
using System.Threading.Tasks;
56

67
namespace OpenAI.Realtime;
@@ -10,43 +11,80 @@ namespace OpenAI.Realtime;
1011
[CodeGenSuppress("CreateStartRealtimeSessionRequest", typeof(BinaryContent), typeof(RequestOptions))]
1112
public partial class RealtimeClient
1213
{
13-
/// <summary>
14-
/// <para>[Protocol Method]</para>
15-
/// Creates a new realtime conversation operation instance, establishing a connection to the /realtime endpoint.
16-
/// </summary>
17-
/// <param name="model"></param>
18-
/// <param name="options"></param>
19-
/// <returns></returns>
20-
public virtual async Task<RealtimeSession> StartConversationSessionAsync(string model, RequestOptions options)
14+
/// <summary> Starts a new <see cref="RealtimeSession"/> for multimodal conversation. </summary>
15+
/// <remarks>
16+
/// The <see cref="RealtimeSession"/> abstracts bidirectional communication between the caller and service,
17+
/// simultaneously sending and receiving WebSocket messages.
18+
/// </remarks>
19+
public virtual async Task<RealtimeSession> StartConversationSessionAsync(string model, RealtimeSessionOptions options = null, CancellationToken cancellationToken = default)
2120
{
2221
Argument.AssertNotNull(model, nameof(model));
23-
return await StartSessionAsync(model, intent: null, options).ConfigureAwait(false);
22+
23+
return await StartSessionAsync(
24+
model: model,
25+
intent: null,
26+
options: options,
27+
cancellationToken: cancellationToken).ConfigureAwait(false);
2428
}
2529

26-
/// <summary>
27-
/// <para>[Protocol Method]</para>
28-
/// Creates a new realtime transcription operation instance, establishing a connection to the /realtime endpoint.
29-
/// </summary>
30-
/// <param name="options"></param>
31-
/// <returns></returns>
32-
public virtual Task<RealtimeSession> StartTranscriptionSessionAsync(RequestOptions options)
33-
=> StartSessionAsync(model: null, intent: "transcription", options);
30+
/// <summary> Starts a new <see cref="RealtimeSession"/> for multimodal conversation. </summary>
31+
/// <remarks>
32+
/// The <see cref="RealtimeSession"/> abstracts bidirectional communication between the caller and service,
33+
/// simultaneously sending and receiving WebSocket messages.
34+
/// </remarks>
35+
public RealtimeSession StartConversationSession(string model, RealtimeSessionOptions options = null, CancellationToken cancellationToken = default)
36+
{
37+
Argument.AssertNotNull(model, nameof(model));
38+
39+
return StartSession(
40+
model: model,
41+
intent: null,
42+
options: options,
43+
cancellationToken: cancellationToken);
44+
}
3445

35-
/// <summary>
36-
/// <para>[Protocol Method]</para>
37-
/// Creates a new realtime operation instance, establishing a connection to the /realtime endpoint.
38-
/// </summary>
39-
/// <param name="model"></param>
40-
/// <param name="intent"></param>
41-
/// <param name="options"></param>
42-
/// <returns></returns>
43-
public virtual async Task<RealtimeSession> StartSessionAsync(string model, string intent, RequestOptions options)
46+
/// <summary> Starts a new <see cref="RealtimeSession"/> for audio transcription.</summary>
47+
/// <remarks>
48+
/// The <see cref="RealtimeSession"/> abstracts bidirectional communication between the caller and service,
49+
/// simultaneously sending and receiving WebSocket messages.
50+
/// </remarks>
51+
public virtual async Task<RealtimeSession> StartTranscriptionSessionAsync(RealtimeSessionOptions options = null, CancellationToken cancellationToken = default)
4452
{
45-
Uri fullEndpoint = BuildSessionEndpoint(_webSocketEndpoint, model, intent);
46-
RealtimeSession provisionalSession = new(this, fullEndpoint, _keyCredential);
53+
return await StartSessionAsync(
54+
model: null,
55+
intent: "transcription",
56+
options: options,
57+
cancellationToken: cancellationToken).ConfigureAwait(false);
58+
}
59+
60+
/// <summary> Starts a new <see cref="RealtimeSession"/> for audio transcription.</summary>
61+
/// <remarks>
62+
/// The <see cref="RealtimeSession"/> abstracts bidirectional communication between the caller and service,
63+
/// simultaneously sending and receiving WebSocket messages.
64+
/// </remarks>
65+
public RealtimeSession StartTranscriptionSession(RealtimeSessionOptions options = null, CancellationToken cancellationToken = default)
66+
{
67+
return StartSession(
68+
model: null,
69+
intent: "transcription",
70+
options: options,
71+
cancellationToken: cancellationToken);
72+
}
73+
74+
/// <summary> Starts a new <see cref="RealtimeSession"/>. </summary>
75+
/// <remarks>
76+
/// The <see cref="RealtimeSession"/> abstracts bidirectional communication between the caller and service,
77+
/// simultaneously sending and receiving WebSocket messages.
78+
/// </remarks>
79+
public virtual async Task<RealtimeSession> StartSessionAsync(string model, string intent, RealtimeSessionOptions options = null, CancellationToken cancellationToken = default)
80+
{
81+
options ??= new();
82+
83+
RealtimeSession provisionalSession = new(_keyCredential, this, _webSocketEndpoint, model, intent);
84+
4785
try
4886
{
49-
await provisionalSession.ConnectAsync(options).ConfigureAwait(false);
87+
await provisionalSession.ConnectAsync(options.QueryString, options.Headers, cancellationToken).ConfigureAwait(false);
5088
RealtimeSession result = provisionalSession;
5189
provisionalSession = null;
5290
return result;
@@ -57,18 +95,13 @@ public virtual async Task<RealtimeSession> StartSessionAsync(string model, strin
5795
}
5896
}
5997

60-
private static Uri BuildSessionEndpoint(Uri baseEndpoint, string model, string intent)
98+
/// <summary> Starts a new <see cref="RealtimeSession"/>. </summary>
99+
/// <remarks>
100+
/// The <see cref="RealtimeSession"/> abstracts bidirectional communication between the caller and service,
101+
/// simultaneously sending and receiving WebSocket messages.
102+
/// </remarks>
103+
public RealtimeSession StartSession(string model, string intent, RealtimeSessionOptions options = null, CancellationToken cancellationToken = default)
61104
{
62-
ClientUriBuilder builder = new();
63-
builder.Reset(baseEndpoint);
64-
if (!string.IsNullOrEmpty(model))
65-
{
66-
builder.AppendQuery("model", model, escape: true);
67-
}
68-
if (!string.IsNullOrEmpty(intent))
69-
{
70-
builder.AppendQuery("intent", intent, escape: true);
71-
}
72-
return builder.ToUri();
105+
return StartSessionAsync(model, intent, options, cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult();
73106
}
74107
}

0 commit comments

Comments
 (0)