Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 14 additions & 10 deletions api/OpenAI.net8.0.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4341,13 +4341,12 @@ public class RealtimeClient {
public virtual Task<ClientResult> CreateEphemeralTokenAsync(BinaryContent content, RequestOptions options = null);
public virtual ClientResult CreateEphemeralTranscriptionToken(BinaryContent content, RequestOptions options = null);
public virtual Task<ClientResult> CreateEphemeralTranscriptionTokenAsync(BinaryContent content, RequestOptions options = null);
public RealtimeSession StartConversationSession(string model, CancellationToken cancellationToken = default);
public virtual Task<RealtimeSession> StartConversationSessionAsync(string model, RequestOptions options);
public virtual Task<RealtimeSession> StartConversationSessionAsync(string model, CancellationToken cancellationToken = default);
public virtual Task<RealtimeSession> StartSessionAsync(string model, string intent, RequestOptions options);
public RealtimeSession StartTranscriptionSession(CancellationToken cancellationToken = default);
public virtual Task<RealtimeSession> StartTranscriptionSessionAsync(RequestOptions options);
public virtual Task<RealtimeSession> StartTranscriptionSessionAsync(CancellationToken cancellationToken = default);
public RealtimeSession StartConversationSession(string model, RealtimeSessionOptions options = null, CancellationToken cancellationToken = default);
public virtual Task<RealtimeSession> StartConversationSessionAsync(string model, RealtimeSessionOptions options = null, CancellationToken cancellationToken = default);
public RealtimeSession StartSession(string model, string intent, RealtimeSessionOptions options = null, CancellationToken cancellationToken = default);
public virtual Task<RealtimeSession> StartSessionAsync(string model, string intent, RealtimeSessionOptions options = null, CancellationToken cancellationToken = default);
public RealtimeSession StartTranscriptionSession(RealtimeSessionOptions options = null, CancellationToken cancellationToken = default);
public virtual Task<RealtimeSession> StartTranscriptionSessionAsync(RealtimeSessionOptions options = null, CancellationToken cancellationToken = default);
}
[Experimental("OPENAI002")]
[Flags]
Expand Down Expand Up @@ -4387,7 +4386,7 @@ public class RealtimeItem : IJsonModel<RealtimeItem>, IPersistableModel<Realtime
}
[Experimental("OPENAI002")]
public class RealtimeSession : IDisposable {
protected internal RealtimeSession(RealtimeClient parentClient, Uri endpoint, ApiKeyCredential credential);
protected internal RealtimeSession(ApiKeyCredential credential, RealtimeClient parentClient, Uri endpoint, string model, string intent);
public Net.WebSockets.WebSocket WebSocket { get; protected set; }
public virtual void AddItem(RealtimeItem item, string previousItemId, CancellationToken cancellationToken = default);
public virtual void AddItem(RealtimeItem item, CancellationToken cancellationToken = default);
Expand All @@ -4403,8 +4402,8 @@ public class RealtimeSession : IDisposable {
public virtual void ConfigureSession(ConversationSessionOptions sessionOptions, CancellationToken cancellationToken = default);
public virtual void ConfigureTranscriptionSession(TranscriptionSessionOptions sessionOptions, CancellationToken cancellationToken = default);
public virtual Task ConfigureTranscriptionSessionAsync(TranscriptionSessionOptions sessionOptions, CancellationToken cancellationToken = default);
protected internal virtual void Connect(RequestOptions options);
protected internal virtual Task ConnectAsync(RequestOptions options);
protected internal virtual void Connect(string queryString = null, IDictionary<string, string> headers = null, CancellationToken cancellationToken = default);
protected internal virtual Task ConnectAsync(string queryString = null, IDictionary<string, string> headers = null, CancellationToken cancellationToken = default);
public virtual void DeleteItem(string itemId, CancellationToken cancellationToken = default);
public virtual Task DeleteItemAsync(string itemId, CancellationToken cancellationToken = default);
public void Dispose();
Expand All @@ -4430,6 +4429,11 @@ public class RealtimeSession : IDisposable {
public virtual Task TruncateItemAsync(string itemId, int contentPartIndex, TimeSpan audioDuration, CancellationToken cancellationToken = default);
}
[Experimental("OPENAI002")]
public class RealtimeSessionOptions {
public IDictionary<string, string> Headers { get; }
public string QueryString { get; set; }
}
[Experimental("OPENAI002")]
public class RealtimeUpdate : IJsonModel<RealtimeUpdate>, IPersistableModel<RealtimeUpdate> {
public string EventId { get; }
public RealtimeUpdateKind Kind { get; }
Expand Down
23 changes: 13 additions & 10 deletions api/OpenAI.netstandard2.0.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3792,13 +3792,12 @@ public class RealtimeClient {
public virtual Task<ClientResult> CreateEphemeralTokenAsync(BinaryContent content, RequestOptions options = null);
public virtual ClientResult CreateEphemeralTranscriptionToken(BinaryContent content, RequestOptions options = null);
public virtual Task<ClientResult> CreateEphemeralTranscriptionTokenAsync(BinaryContent content, RequestOptions options = null);
public RealtimeSession StartConversationSession(string model, CancellationToken cancellationToken = default);
public virtual Task<RealtimeSession> StartConversationSessionAsync(string model, RequestOptions options);
public virtual Task<RealtimeSession> StartConversationSessionAsync(string model, CancellationToken cancellationToken = default);
public virtual Task<RealtimeSession> StartSessionAsync(string model, string intent, RequestOptions options);
public RealtimeSession StartTranscriptionSession(CancellationToken cancellationToken = default);
public virtual Task<RealtimeSession> StartTranscriptionSessionAsync(RequestOptions options);
public virtual Task<RealtimeSession> StartTranscriptionSessionAsync(CancellationToken cancellationToken = default);
public RealtimeSession StartConversationSession(string model, RealtimeSessionOptions options = null, CancellationToken cancellationToken = default);
public virtual Task<RealtimeSession> StartConversationSessionAsync(string model, RealtimeSessionOptions options = null, CancellationToken cancellationToken = default);
public RealtimeSession StartSession(string model, string intent, RealtimeSessionOptions options = null, CancellationToken cancellationToken = default);
public virtual Task<RealtimeSession> StartSessionAsync(string model, string intent, RealtimeSessionOptions options = null, CancellationToken cancellationToken = default);
public RealtimeSession StartTranscriptionSession(RealtimeSessionOptions options = null, CancellationToken cancellationToken = default);
public virtual Task<RealtimeSession> StartTranscriptionSessionAsync(RealtimeSessionOptions options = null, CancellationToken cancellationToken = default);
}
[Flags]
public enum RealtimeContentModalities {
Expand Down Expand Up @@ -3834,7 +3833,7 @@ public class RealtimeItem : IJsonModel<RealtimeItem>, IPersistableModel<Realtime
protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options);
}
public class RealtimeSession : IDisposable {
protected internal RealtimeSession(RealtimeClient parentClient, Uri endpoint, ApiKeyCredential credential);
protected internal RealtimeSession(ApiKeyCredential credential, RealtimeClient parentClient, Uri endpoint, string model, string intent);
public Net.WebSockets.WebSocket WebSocket { get; protected set; }
public virtual void AddItem(RealtimeItem item, string previousItemId, CancellationToken cancellationToken = default);
public virtual void AddItem(RealtimeItem item, CancellationToken cancellationToken = default);
Expand All @@ -3850,8 +3849,8 @@ public class RealtimeSession : IDisposable {
public virtual void ConfigureSession(ConversationSessionOptions sessionOptions, CancellationToken cancellationToken = default);
public virtual void ConfigureTranscriptionSession(TranscriptionSessionOptions sessionOptions, CancellationToken cancellationToken = default);
public virtual Task ConfigureTranscriptionSessionAsync(TranscriptionSessionOptions sessionOptions, CancellationToken cancellationToken = default);
protected internal virtual void Connect(RequestOptions options);
protected internal virtual Task ConnectAsync(RequestOptions options);
protected internal virtual void Connect(string queryString = null, IDictionary<string, string> headers = null, CancellationToken cancellationToken = default);
protected internal virtual Task ConnectAsync(string queryString = null, IDictionary<string, string> headers = null, CancellationToken cancellationToken = default);
public virtual void DeleteItem(string itemId, CancellationToken cancellationToken = default);
public virtual Task DeleteItemAsync(string itemId, CancellationToken cancellationToken = default);
public void Dispose();
Expand All @@ -3876,6 +3875,10 @@ public class RealtimeSession : IDisposable {
public virtual void TruncateItem(string itemId, int contentPartIndex, TimeSpan audioDuration, CancellationToken cancellationToken = default);
public virtual Task TruncateItemAsync(string itemId, int contentPartIndex, TimeSpan audioDuration, CancellationToken cancellationToken = default);
}
public class RealtimeSessionOptions {
public IDictionary<string, string> Headers { get; }
public string QueryString { get; set; }
}
public class RealtimeUpdate : IJsonModel<RealtimeUpdate>, IPersistableModel<RealtimeUpdate> {
public string EventId { get; }
public RealtimeUpdateKind Kind { get; }
Expand Down
115 changes: 74 additions & 41 deletions src/Custom/Realtime/RealtimeClient.Protocol.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.ClientModel;
using System.ClientModel.Primitives;
using System.Threading;
using System.Threading.Tasks;

namespace OpenAI.Realtime;
Expand All @@ -10,43 +11,80 @@ namespace OpenAI.Realtime;
[CodeGenSuppress("CreateStartRealtimeSessionRequest", typeof(BinaryContent), typeof(RequestOptions))]
public partial class RealtimeClient
{
/// <summary>
/// <para>[Protocol Method]</para>
/// Creates a new realtime conversation operation instance, establishing a connection to the /realtime endpoint.
/// </summary>
/// <param name="model"></param>
/// <param name="options"></param>
/// <returns></returns>
public virtual async Task<RealtimeSession> StartConversationSessionAsync(string model, RequestOptions options)
/// <summary> Starts a new <see cref="RealtimeSession"/> for multimodal conversation. </summary>
/// <remarks>
/// The <see cref="RealtimeSession"/> abstracts bidirectional communication between the caller and service,
/// simultaneously sending and receiving WebSocket messages.
/// </remarks>
public virtual async Task<RealtimeSession> StartConversationSessionAsync(string model, RealtimeSessionOptions options = null, CancellationToken cancellationToken = default)
{
Argument.AssertNotNull(model, nameof(model));
return await StartSessionAsync(model, intent: null, options).ConfigureAwait(false);

return await StartSessionAsync(
model: model,
intent: null,
options: options,
cancellationToken: cancellationToken).ConfigureAwait(false);
}

/// <summary>
/// <para>[Protocol Method]</para>
/// Creates a new realtime transcription operation instance, establishing a connection to the /realtime endpoint.
/// </summary>
/// <param name="options"></param>
/// <returns></returns>
public virtual Task<RealtimeSession> StartTranscriptionSessionAsync(RequestOptions options)
=> StartSessionAsync(model: null, intent: "transcription", options);
/// <summary> Starts a new <see cref="RealtimeSession"/> for multimodal conversation. </summary>
/// <remarks>
/// The <see cref="RealtimeSession"/> abstracts bidirectional communication between the caller and service,
/// simultaneously sending and receiving WebSocket messages.
/// </remarks>
public RealtimeSession StartConversationSession(string model, RealtimeSessionOptions options = null, CancellationToken cancellationToken = default)
{
Argument.AssertNotNull(model, nameof(model));

return StartSession(
model: model,
intent: null,
options: options,
cancellationToken: cancellationToken);
}

/// <summary>
/// <para>[Protocol Method]</para>
/// Creates a new realtime operation instance, establishing a connection to the /realtime endpoint.
/// </summary>
/// <param name="model"></param>
/// <param name="intent"></param>
/// <param name="options"></param>
/// <returns></returns>
public virtual async Task<RealtimeSession> StartSessionAsync(string model, string intent, RequestOptions options)
/// <summary> Starts a new <see cref="RealtimeSession"/> for audio transcription.</summary>
/// <remarks>
/// The <see cref="RealtimeSession"/> abstracts bidirectional communication between the caller and service,
/// simultaneously sending and receiving WebSocket messages.
/// </remarks>
public virtual async Task<RealtimeSession> StartTranscriptionSessionAsync(RealtimeSessionOptions options = null, CancellationToken cancellationToken = default)
{
Uri fullEndpoint = BuildSessionEndpoint(_webSocketEndpoint, model, intent);
RealtimeSession provisionalSession = new(this, fullEndpoint, _keyCredential);
return await StartSessionAsync(
model: null,
intent: "transcription",
options: options,
cancellationToken: cancellationToken).ConfigureAwait(false);
}

/// <summary> Starts a new <see cref="RealtimeSession"/> for audio transcription.</summary>
/// <remarks>
/// The <see cref="RealtimeSession"/> abstracts bidirectional communication between the caller and service,
/// simultaneously sending and receiving WebSocket messages.
/// </remarks>
public RealtimeSession StartTranscriptionSession(RealtimeSessionOptions options = null, CancellationToken cancellationToken = default)
{
return StartSession(
model: null,
intent: "transcription",
options: options,
cancellationToken: cancellationToken);
}

/// <summary> Starts a new <see cref="RealtimeSession"/>. </summary>
/// <remarks>
/// The <see cref="RealtimeSession"/> abstracts bidirectional communication between the caller and service,
/// simultaneously sending and receiving WebSocket messages.
/// </remarks>
public virtual async Task<RealtimeSession> StartSessionAsync(string model, string intent, RealtimeSessionOptions options = null, CancellationToken cancellationToken = default)
{
options ??= new();

RealtimeSession provisionalSession = new(_keyCredential, this, _webSocketEndpoint, model, intent);

try
{
await provisionalSession.ConnectAsync(options).ConfigureAwait(false);
await provisionalSession.ConnectAsync(options.QueryString, options.Headers, cancellationToken).ConfigureAwait(false);
RealtimeSession result = provisionalSession;
provisionalSession = null;
return result;
Expand All @@ -57,18 +95,13 @@ public virtual async Task<RealtimeSession> StartSessionAsync(string model, strin
}
}

private static Uri BuildSessionEndpoint(Uri baseEndpoint, string model, string intent)
/// <summary> Starts a new <see cref="RealtimeSession"/>. </summary>
/// <remarks>
/// The <see cref="RealtimeSession"/> abstracts bidirectional communication between the caller and service,
/// simultaneously sending and receiving WebSocket messages.
/// </remarks>
public RealtimeSession StartSession(string model, string intent, RealtimeSessionOptions options = null, CancellationToken cancellationToken = default)
{
ClientUriBuilder builder = new();
builder.Reset(baseEndpoint);
if (!string.IsNullOrEmpty(model))
{
builder.AppendQuery("model", model, escape: true);
}
if (!string.IsNullOrEmpty(intent))
{
builder.AppendQuery("intent", intent, escape: true);
}
return builder.ToUri();
return StartSessionAsync(model, intent, options, cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult();
}
}
Loading