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
2 changes: 1 addition & 1 deletion .claude/skills/tryagi-openai/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ dnx tryAGI.OpenAI.CLI <group> --help
| `project-group` | 3 | |
| `project-group-role-assignment` | 3 | |
| `project-user-role-assignment` | 3 | |
| `realtime` | 8 | |
| `realtime` | 9 | |
| `response` | 5 | |
| `role` | 8 | |
| `skill` | 11 | |
Expand Down
1 change: 1 addition & 0 deletions .claude/skills/tryagi-openai/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ Given text and/or image inputs, classifies if those inputs are potentially harmf
| `create-client-secret` | `POST /realtime/client_secrets` | Create a Realtime client secret with an associated session configuration. Client secrets are short-lived tokens that can be passed to a client app, such as a web frontend or mobile client, which grants access to the Realtime API without leaking your main API key. You can configure a custom TTL for each client secret. You can also attach session configuration options to the client secret, which will be applied to any sessions created using that client secret, but these can also be overridden by the client connection. [Learn more about authentication with client secrets over WebRTC](/docs/guides/realtime-webrtc). Returns the created client secret and the effective session object. The client secret is a string that looks like `ek_1234`. |
| `create-session` | `POST /realtime/sessions` | Create an ephemeral API token for use in client-side applications with the Realtime API. Can be configured with the same session parameters as the `session.update` client event. It responds with a session object, plus a `client_secret` key which contains a usable ephemeral API token that can be used to authenticate browser clients for the Realtime API. Returns the created Realtime session object, plus an ephemeral key. |
| `create-transcription-session` | `POST /realtime/transcription_sessions` | Create an ephemeral API token for use in client-side applications with the Realtime API specifically for realtime transcriptions. Can be configured with the same session parameters as the `transcription_session.update` client event. It responds with a session object, plus a `client_secret` key which contains a usable ephemeral API token that can be used to authenticate browser clients for the Realtime API. Returns the created Realtime transcription session object, plus an ephemeral key. |
| `create-translation-client-secret` | `POST /realtime/translations/client_secrets` | Create a Realtime translation client secret with an associated translation session configuration. Client secrets are short-lived tokens that can be passed to a client app, such as a web frontend or mobile client, which grants access to the Realtime Translation API without leaking your main API key. You can configure a custom TTL for each client secret. Returns the created client secret and the effective translation session object. The client secret is a string that looks like `ek_1234`. |
| `hang-up-call` | `POST /realtime/calls/{call_id}/hangup` | End an active Realtime API call, whether it was initiated over SIP or WebRTC. |
| `refer-call` | `POST /realtime/calls/{call_id}/refer` | Transfer an active SIP call to a new destination using the SIP REFER verb. |
| `reject-call` | `POST /realtime/calls/{call_id}/reject` | Decline an incoming SIP call by returning a SIP status code to the caller. |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#nullable enable

namespace tryAGI.OpenAI
{
public partial interface IRealtimeClient
{
/// <summary>
/// Create a Realtime translation client secret with an associated translation session configuration.<br/>
/// Client secrets are short-lived tokens that can be passed to a client app,<br/>
/// such as a web frontend or mobile client, which grants access to the Realtime<br/>
/// Translation API without leaking your main API key. You can configure a custom<br/>
/// TTL for each client secret.<br/>
/// Returns the created client secret and the effective translation session object.<br/>
/// The client secret is a string that looks like `ek_1234`.
/// </summary>
/// <param name="request"></param>
/// <param name="requestOptions">Per-request overrides such as headers, query parameters, timeout, retries, and response buffering.</param>
/// <param name="cancellationToken">The token to cancel the operation with</param>
/// <exception cref="global::tryAGI.OpenAI.ApiException"></exception>
global::System.Threading.Tasks.Task<global::tryAGI.OpenAI.RealtimeTranslationClientSecretCreateResponse> CreateTranslationClientSecretAsync(

global::tryAGI.OpenAI.RealtimeTranslationClientSecretCreateRequest request,
global::tryAGI.OpenAI.AutoSDKRequestOptions? requestOptions = default,
global::System.Threading.CancellationToken cancellationToken = default);
/// <summary>
/// Create a Realtime translation client secret with an associated translation session configuration.<br/>
/// Client secrets are short-lived tokens that can be passed to a client app,<br/>
/// such as a web frontend or mobile client, which grants access to the Realtime<br/>
/// Translation API without leaking your main API key. You can configure a custom<br/>
/// TTL for each client secret.<br/>
/// Returns the created client secret and the effective translation session object.<br/>
/// The client secret is a string that looks like `ek_1234`.
/// </summary>
/// <param name="request"></param>
/// <param name="requestOptions">Per-request overrides such as headers, query parameters, timeout, retries, and response buffering.</param>
/// <param name="cancellationToken">The token to cancel the operation with</param>
/// <exception cref="global::tryAGI.OpenAI.ApiException"></exception>
global::System.Threading.Tasks.Task<global::tryAGI.OpenAI.AutoSDKHttpResponse<global::tryAGI.OpenAI.RealtimeTranslationClientSecretCreateResponse>> CreateTranslationClientSecretAsResponseAsync(

global::tryAGI.OpenAI.RealtimeTranslationClientSecretCreateRequest request,
global::tryAGI.OpenAI.AutoSDKRequestOptions? requestOptions = default,
global::System.Threading.CancellationToken cancellationToken = default);
/// <summary>
/// Create a Realtime translation client secret with an associated translation session configuration.<br/>
/// Client secrets are short-lived tokens that can be passed to a client app,<br/>
/// such as a web frontend or mobile client, which grants access to the Realtime<br/>
/// Translation API without leaking your main API key. You can configure a custom<br/>
/// TTL for each client secret.<br/>
/// Returns the created client secret and the effective translation session object.<br/>
/// The client secret is a string that looks like `ek_1234`.
/// </summary>
/// <param name="expiresAfter">
/// Configuration for the client secret expiration. Expiration refers to the time after which<br/>
/// a client secret will no longer be valid for creating sessions. The session itself may<br/>
/// continue after that time once started. A secret can be used to create multiple sessions<br/>
/// until it expires.
/// </param>
/// <param name="session">
/// Realtime translation session configuration. Translation sessions stream source<br/>
/// audio in and translated audio plus transcript deltas out continuously.
/// </param>
/// <param name="requestOptions">Per-request overrides such as headers, query parameters, timeout, retries, and response buffering.</param>
/// <param name="cancellationToken">The token to cancel the operation with</param>
/// <exception cref="global::System.InvalidOperationException"></exception>
global::System.Threading.Tasks.Task<global::tryAGI.OpenAI.RealtimeTranslationClientSecretCreateResponse> CreateTranslationClientSecretAsync(
global::tryAGI.OpenAI.RealtimeTranslationSessionCreateRequest session,
global::tryAGI.OpenAI.RealtimeTranslationClientSecretCreateRequestExpiresAfter? expiresAfter = default,
global::tryAGI.OpenAI.AutoSDKRequestOptions? requestOptions = default,
global::System.Threading.CancellationToken cancellationToken = default);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
#nullable enable
#pragma warning disable CS0618 // Type or member is obsolete

namespace tryAGI.OpenAI.JsonConverters
{
/// <inheritdoc />
public class RealtimeTranslationClientEventJsonConverter : global::System.Text.Json.Serialization.JsonConverter<global::tryAGI.OpenAI.RealtimeTranslationClientEvent>
{
/// <inheritdoc />
public override global::tryAGI.OpenAI.RealtimeTranslationClientEvent Read(
ref global::System.Text.Json.Utf8JsonReader reader,
global::System.Type typeToConvert,
global::System.Text.Json.JsonSerializerOptions options)
{
options = options ?? throw new global::System.ArgumentNullException(nameof(options));
var typeInfoResolver = options.TypeInfoResolver ?? throw new global::System.InvalidOperationException("TypeInfoResolver is not set.");

using var __jsonDocument = global::System.Text.Json.JsonDocument.ParseValue(ref reader);
var __rawJson = __jsonDocument.RootElement.GetRawText();
var __jsonProps = new global::System.Collections.Generic.HashSet<string>();
if (__jsonDocument.RootElement.ValueKind == global::System.Text.Json.JsonValueKind.Object)
{
foreach (var __jsonProp in __jsonDocument.RootElement.EnumerateObject())
{
__jsonProps.Add(__jsonProp.Name);
if (__jsonProp.Value.ValueKind == global::System.Text.Json.JsonValueKind.Object)
{
foreach (var __nestedJsonProp in __jsonProp.Value.EnumerateObject())
{
__jsonProps.Add(__jsonProp.Name + "." + __nestedJsonProp.Name);
}
}

}
}

var __score0 = 0;
if (__jsonProps.Contains("event_id")) __score0++;
if (__jsonProps.Contains("session")) __score0++;
if (__jsonProps.Contains("session.audio")) __score0++;
if (__jsonProps.Contains("type")) __score0++;
var __score1 = 0;
if (__jsonProps.Contains("audio")) __score1++;
if (__jsonProps.Contains("event_id")) __score1++;
if (__jsonProps.Contains("type")) __score1++;
var __score2 = 0;
if (__jsonProps.Contains("event_id")) __score2++;
if (__jsonProps.Contains("type")) __score2++;
var __bestScore = 0;
var __bestIndex = -1;
if (__score0 > __bestScore) { __bestScore = __score0; __bestIndex = 0; }
if (__score1 > __bestScore) { __bestScore = __score1; __bestIndex = 1; }
if (__score2 > __bestScore) { __bestScore = __score2; __bestIndex = 2; }

global::tryAGI.OpenAI.RealtimeTranslationClientEventSessionUpdate? sessionUpdate = default;
global::tryAGI.OpenAI.RealtimeTranslationClientEventInputAudioBufferAppend? sessionInputAudioBufferAppend = default;
global::tryAGI.OpenAI.RealtimeTranslationClientEventSessionClose? sessionClose = default;
if (__bestIndex >= 0)
{
if (__bestIndex == 0)
{
try
{
var typeInfo = typeInfoResolver.GetTypeInfo(typeof(global::tryAGI.OpenAI.RealtimeTranslationClientEventSessionUpdate), options) as global::System.Text.Json.Serialization.Metadata.JsonTypeInfo<global::tryAGI.OpenAI.RealtimeTranslationClientEventSessionUpdate> ??
throw new global::System.InvalidOperationException($"Cannot get type info for {typeof(global::tryAGI.OpenAI.RealtimeTranslationClientEventSessionUpdate).Name}");
sessionUpdate = global::System.Text.Json.JsonSerializer.Deserialize(__rawJson, typeInfo);
}
catch (global::System.Text.Json.JsonException)
{
}
catch (global::System.InvalidOperationException)
{
}
}
else if (__bestIndex == 1)
{
try
{
var typeInfo = typeInfoResolver.GetTypeInfo(typeof(global::tryAGI.OpenAI.RealtimeTranslationClientEventInputAudioBufferAppend), options) as global::System.Text.Json.Serialization.Metadata.JsonTypeInfo<global::tryAGI.OpenAI.RealtimeTranslationClientEventInputAudioBufferAppend> ??
throw new global::System.InvalidOperationException($"Cannot get type info for {typeof(global::tryAGI.OpenAI.RealtimeTranslationClientEventInputAudioBufferAppend).Name}");
sessionInputAudioBufferAppend = global::System.Text.Json.JsonSerializer.Deserialize(__rawJson, typeInfo);
}
catch (global::System.Text.Json.JsonException)
{
}
catch (global::System.InvalidOperationException)
{
}
}
else if (__bestIndex == 2)
{
try
{
var typeInfo = typeInfoResolver.GetTypeInfo(typeof(global::tryAGI.OpenAI.RealtimeTranslationClientEventSessionClose), options) as global::System.Text.Json.Serialization.Metadata.JsonTypeInfo<global::tryAGI.OpenAI.RealtimeTranslationClientEventSessionClose> ??
throw new global::System.InvalidOperationException($"Cannot get type info for {typeof(global::tryAGI.OpenAI.RealtimeTranslationClientEventSessionClose).Name}");
sessionClose = global::System.Text.Json.JsonSerializer.Deserialize(__rawJson, typeInfo);
}
catch (global::System.Text.Json.JsonException)
{
}
catch (global::System.InvalidOperationException)
{
}
}
}

if (sessionUpdate == null && sessionInputAudioBufferAppend == null && sessionClose == null)
{
try
{
var typeInfo = typeInfoResolver.GetTypeInfo(typeof(global::tryAGI.OpenAI.RealtimeTranslationClientEventSessionUpdate), options) as global::System.Text.Json.Serialization.Metadata.JsonTypeInfo<global::tryAGI.OpenAI.RealtimeTranslationClientEventSessionUpdate> ??
throw new global::System.InvalidOperationException($"Cannot get type info for {typeof(global::tryAGI.OpenAI.RealtimeTranslationClientEventSessionUpdate).Name}");
sessionUpdate = global::System.Text.Json.JsonSerializer.Deserialize(__rawJson, typeInfo);
}
catch (global::System.Text.Json.JsonException)
{
}
catch (global::System.InvalidOperationException)
{
}

try
{
var typeInfo = typeInfoResolver.GetTypeInfo(typeof(global::tryAGI.OpenAI.RealtimeTranslationClientEventInputAudioBufferAppend), options) as global::System.Text.Json.Serialization.Metadata.JsonTypeInfo<global::tryAGI.OpenAI.RealtimeTranslationClientEventInputAudioBufferAppend> ??
throw new global::System.InvalidOperationException($"Cannot get type info for {typeof(global::tryAGI.OpenAI.RealtimeTranslationClientEventInputAudioBufferAppend).Name}");
sessionInputAudioBufferAppend = global::System.Text.Json.JsonSerializer.Deserialize(__rawJson, typeInfo);
}
catch (global::System.Text.Json.JsonException)
{
}
catch (global::System.InvalidOperationException)
{
}

try
{
var typeInfo = typeInfoResolver.GetTypeInfo(typeof(global::tryAGI.OpenAI.RealtimeTranslationClientEventSessionClose), options) as global::System.Text.Json.Serialization.Metadata.JsonTypeInfo<global::tryAGI.OpenAI.RealtimeTranslationClientEventSessionClose> ??
throw new global::System.InvalidOperationException($"Cannot get type info for {typeof(global::tryAGI.OpenAI.RealtimeTranslationClientEventSessionClose).Name}");
sessionClose = global::System.Text.Json.JsonSerializer.Deserialize(__rawJson, typeInfo);
}
catch (global::System.Text.Json.JsonException)
{
}
catch (global::System.InvalidOperationException)
{
}
}

var __value = new global::tryAGI.OpenAI.RealtimeTranslationClientEvent(
sessionUpdate,

sessionInputAudioBufferAppend,

sessionClose
);

return __value;
}

/// <inheritdoc />
public override void Write(
global::System.Text.Json.Utf8JsonWriter writer,
global::tryAGI.OpenAI.RealtimeTranslationClientEvent value,
global::System.Text.Json.JsonSerializerOptions options)
{
options = options ?? throw new global::System.ArgumentNullException(nameof(options));
var typeInfoResolver = options.TypeInfoResolver ?? throw new global::System.InvalidOperationException("TypeInfoResolver is not set.");

if (value.IsSessionUpdate)
{
var typeInfo = typeInfoResolver.GetTypeInfo(typeof(global::tryAGI.OpenAI.RealtimeTranslationClientEventSessionUpdate), options) as global::System.Text.Json.Serialization.Metadata.JsonTypeInfo<global::tryAGI.OpenAI.RealtimeTranslationClientEventSessionUpdate?> ??
throw new global::System.InvalidOperationException($"Cannot get type info for {typeof(global::tryAGI.OpenAI.RealtimeTranslationClientEventSessionUpdate).Name}");
global::System.Text.Json.JsonSerializer.Serialize(writer, value.SessionUpdate!, typeInfo);
}
else if (value.IsSessionInputAudioBufferAppend)
{
var typeInfo = typeInfoResolver.GetTypeInfo(typeof(global::tryAGI.OpenAI.RealtimeTranslationClientEventInputAudioBufferAppend), options) as global::System.Text.Json.Serialization.Metadata.JsonTypeInfo<global::tryAGI.OpenAI.RealtimeTranslationClientEventInputAudioBufferAppend?> ??
throw new global::System.InvalidOperationException($"Cannot get type info for {typeof(global::tryAGI.OpenAI.RealtimeTranslationClientEventInputAudioBufferAppend).Name}");
global::System.Text.Json.JsonSerializer.Serialize(writer, value.SessionInputAudioBufferAppend!, typeInfo);
}
else if (value.IsSessionClose)
{
var typeInfo = typeInfoResolver.GetTypeInfo(typeof(global::tryAGI.OpenAI.RealtimeTranslationClientEventSessionClose), options) as global::System.Text.Json.Serialization.Metadata.JsonTypeInfo<global::tryAGI.OpenAI.RealtimeTranslationClientEventSessionClose?> ??
throw new global::System.InvalidOperationException($"Cannot get type info for {typeof(global::tryAGI.OpenAI.RealtimeTranslationClientEventSessionClose).Name}");
global::System.Text.Json.JsonSerializer.Serialize(writer, value.SessionClose!, typeInfo);
}
}
}
}
Loading