Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
1 change: 1 addition & 0 deletions src/Custom/Realtime/GeneratorStubs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ namespace OpenAI.Realtime;
[CodeGenType("RealtimeResponseUsage")] public partial class ConversationTokenUsage { }
[CodeGenType("RealtimeToolType")] public readonly partial struct ConversationToolKind { }
[CodeGenType("DotNetRealtimeVoiceIds")] public readonly partial struct ConversationVoice { }
[CodeGenType("RealtimeSemanticVadTurnDetectionEagerness")] public readonly partial struct SemanticEagernessLevel { }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we can use a visitor to generate these rather than having to maintain stubs here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I totally agree with this. We’ve been maintaining separate generator stubs per client, and switching to a visitor would make it much easier to manage these going forward. I’ve created an issue to track this: #550, and we’ll look into addressing it as part of that. Thanks for the suggestion!

1 change: 0 additions & 1 deletion src/Custom/Realtime/Internal/GeneratorStubs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ namespace OpenAI.Realtime;
[Experimental("OPENAI002")][CodeGenType("RealtimeResponseStatusDetailsType")] internal readonly partial struct InternalRealtimeResponseStatusDetailsType { }
[Experimental("OPENAI002")][CodeGenType("RealtimeResponseVoice")] internal readonly partial struct InternalRealtimeResponseVoice { }
[Experimental("OPENAI002")][CodeGenType("RealtimeSemanticVadTurnDetection")] internal partial class InternalRealtimeSemanticVadTurnDetection { }
[Experimental("OPENAI002")][CodeGenType("RealtimeSemanticVadTurnDetectionEagerness")] internal readonly partial struct InternalRealtimeSemanticVadTurnDetectionEagerness { }
[Experimental("OPENAI002")][CodeGenType("RealtimeServerEventConversationCreated")] internal partial class InternalRealtimeServerEventConversationCreated { }
[Experimental("OPENAI002")][CodeGenType("RealtimeServerEventConversationCreatedConversation")] internal partial class InternalRealtimeServerEventConversationCreatedConversation { }
[Experimental("OPENAI002")][CodeGenType("RealtimeServerEventConversationItemInputAudioTranscriptionFailedError")] internal partial class InternalRealtimeServerEventConversationItemInputAudioTranscriptionFailedError { }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ internal static TurnDetectionOptions DeserializeTurnDetectionOptions(JsonElement
{
case "none": return InternalRealtimeNoTurnDetection.DeserializeInternalRealtimeNoTurnDetection(element, options);
case "server_vad": return InternalRealtimeServerVadTurnDetection.DeserializeInternalRealtimeServerVadTurnDetection(element, options);
case "semantic_vad": return InternalRealtimeSemanticVadTurnDetection.DeserializeInternalRealtimeSemanticVadTurnDetection(element, options);
default: return null;
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/Custom/Realtime/TurnDetectionOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ public static TurnDetectionOptions CreateServerVoiceActivityTurnDetectionOptions
};
}

internal static TurnDetectionOptions CreateSemanticVoiceActivityTurnDetectionOptions(
InternalRealtimeSemanticVadTurnDetectionEagerness? eagernessLevel = null,
public static TurnDetectionOptions CreateSemanticVoiceActivityTurnDetectionOptions(
SemanticEagernessLevel? eagernessLevel = null,
bool? enableAutomaticResponseCreation = null,
bool? enableResponseInterruption = null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ internal static InternalRealtimeSemanticVadTurnDetection DeserializeInternalReal
bool? responseCreationEnabled = default;
bool? responseInterruptionEnabled = default;
IDictionary<string, BinaryData> additionalBinaryDataProperties = new ChangeTrackingDictionary<string, BinaryData>();
InternalRealtimeSemanticVadTurnDetectionEagerness? eagerness = default;
SemanticEagernessLevel? eagerness = default;
foreach (var prop in element.EnumerateObject())
{
if (prop.NameEquals("type"u8))
Expand Down Expand Up @@ -89,7 +89,7 @@ internal static InternalRealtimeSemanticVadTurnDetection DeserializeInternalReal
{
continue;
}
eagerness = new InternalRealtimeSemanticVadTurnDetectionEagerness(prop.Value.GetString());
eagerness = new SemanticEagernessLevel(prop.Value.GetString());
continue;
}
// Plugin customization: remove options.Format != "W" check
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ public InternalRealtimeSemanticVadTurnDetection() : this(TurnDetectionKind.Seman
{
}

internal InternalRealtimeSemanticVadTurnDetection(TurnDetectionKind kind, bool? responseCreationEnabled, bool? responseInterruptionEnabled, IDictionary<string, BinaryData> additionalBinaryDataProperties, InternalRealtimeSemanticVadTurnDetectionEagerness? eagerness) : base(kind, responseCreationEnabled, responseInterruptionEnabled, additionalBinaryDataProperties)
internal InternalRealtimeSemanticVadTurnDetection(TurnDetectionKind kind, bool? responseCreationEnabled, bool? responseInterruptionEnabled, IDictionary<string, BinaryData> additionalBinaryDataProperties, SemanticEagernessLevel? eagerness) : base(kind, responseCreationEnabled, responseInterruptionEnabled, additionalBinaryDataProperties)
{
Eagerness = eagerness;
}

internal InternalRealtimeSemanticVadTurnDetectionEagerness? Eagerness { get; set; }
public SemanticEagernessLevel? Eagerness { get; set; }
}
}

This file was deleted.

52 changes: 52 additions & 0 deletions src/Generated/Models/Realtime/SemanticEagernessLevel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// <auto-generated/>

#nullable disable

using System;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using OpenAI;

namespace OpenAI.Realtime
{
[Experimental("OPENAI002")]
public readonly partial struct SemanticEagernessLevel : IEquatable<SemanticEagernessLevel>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yay! Extensibile!

{
private readonly string _value;
private const string LowValue = "low";
private const string MediumValue = "medium";
private const string HighValue = "high";
private const string AutoValue = "auto";

public SemanticEagernessLevel(string value)
{
Argument.AssertNotNull(value, nameof(value));

_value = value;
}

public static SemanticEagernessLevel Low { get; } = new SemanticEagernessLevel(LowValue);

public static SemanticEagernessLevel Medium { get; } = new SemanticEagernessLevel(MediumValue);

public static SemanticEagernessLevel High { get; } = new SemanticEagernessLevel(HighValue);

public static SemanticEagernessLevel Auto { get; } = new SemanticEagernessLevel(AutoValue);

public static bool operator ==(SemanticEagernessLevel left, SemanticEagernessLevel right) => left.Equals(right);

public static bool operator !=(SemanticEagernessLevel left, SemanticEagernessLevel right) => !left.Equals(right);

public static implicit operator SemanticEagernessLevel(string value) => new SemanticEagernessLevel(value);

[EditorBrowsable(EditorBrowsableState.Never)]
public override bool Equals(object obj) => obj is SemanticEagernessLevel other && Equals(other);

public bool Equals(SemanticEagernessLevel other) => string.Equals(_value, other._value, StringComparison.InvariantCultureIgnoreCase);

[EditorBrowsable(EditorBrowsableState.Never)]
public override int GetHashCode() => _value != null ? StringComparer.InvariantCultureIgnoreCase.GetHashCode(_value) : 0;

public override string ToString() => _value;
}
}
12 changes: 12 additions & 0 deletions tests/Realtime/RealtimeSmokeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,18 @@ public void TurnDetectionSerializationWorks()
JsonNode serializedNode = JsonNode.Parse(serializedOptions);
Assert.That(serializedNode["turn_detection"]?["type"]?.GetValue<string>(), Is.EqualTo("server_vad"));
Assert.That(serializedNode["turn_detection"]?["threshold"]?.GetValue<float>(), Is.EqualTo(0.42f));

sessionOptions = new()
{
TurnDetectionOptions = TurnDetectionOptions.CreateSemanticVoiceActivityTurnDetectionOptions(
SemanticEagernessLevel.Medium, true, true)
};
serializedOptions = ModelReaderWriter.Write(sessionOptions);
serializedNode = JsonNode.Parse(serializedOptions);
Assert.That(serializedNode["turn_detection"]?["type"]?.GetValue<string>(), Is.EqualTo("semantic_vad"));
Assert.That(serializedNode["turn_detection"]?["eagerness"]?.GetValue<string>(), Is.EqualTo("medium"));
Assert.That(serializedNode["turn_detection"]?["create_response"]?.GetValue<bool>(), Is.EqualTo(true));
Assert.That(serializedNode["turn_detection"]?["interrupt_response"]?.GetValue<bool>(), Is.EqualTo(true));
}

[Test]
Expand Down