diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a8d68fa..9854cf26 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,24 @@ # Release History +## 2.2.0-beta.1 (Unreleased) + +### Features added + +- Chat completion now supports audio input and output! + - To configure a chat completion to request audio output using the `gpt-4o-audio-preview` model, use `ChatResponseModalities.Text | ChatResponseModalities.Audio` as the value for `ChatCompletionOptions.ResponseModalities` and create a `ChatAudioOptions` instance for `ChatCompletionOptions.AudioOptions`. + - Input chat audio is provided to `UserChatMessage` instances using `ChatContentPart.CreateInputAudioPart()` + - Output chat audio is provided on the `OutputAudio` property of `ChatCompletion` + - References to prior assistant audio are provided via `OutputAudioReference` instances on the `AudioReference` property of `AssistantChatMessage`; `AssistantChatMessage(chatCompletion)` will automatically handle this, too + - For more information, see the example in the README +- Predicted output can be used with chat completion: the new `OutputPrediction` property on `ChatCompletionOptions` can be populated with `ChatMessageContentPart` instances via `ChatOutputPrediction.CreateStaticContentPrediction()` to substantially accelerate some varieties of requests. +- For `o3-mini`, `o1`, and later models with reasoning capabilities: + - The new `DeveloperChatMessage`, which replaces `SystemChatMessage`, can be used to provide instructions to the model + - `ChatCompletionOptions` can specify a `ReasoningEffortLevel` property to adjust the level of token consumption the model will attempt to apply + +### `[Experimental]` Breaking changes + +- The `IDictionary Metadata` property in several request options types in the Assistants and RealtimeConversation areas have had their setters removed, aligning them with other request use of collections. The dictionaries remain writeable and use both initializer syntax and range copies to produce the same effect. + ## 2.1.0 (2024-12-04) ### Features added diff --git a/README.md b/README.md index 2d138e8a..10a81560 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ It is generated from our [OpenAPI specification](https://github.com/openai/opena - [How to use chat completions with streaming](#how-to-use-chat-completions-with-streaming) - [How to use chat completions with tools and function calling](#how-to-use-chat-completions-with-tools-and-function-calling) - [How to use chat completions with structured outputs](#how-to-use-chat-completions-with-structured-outputs) +- [How to use chat completions with audio](#how-to-use-chat-completions-with-audio) - [How to generate text embeddings](#how-to-generate-text-embeddings) - [How to generate images](#how-to-generate-images) - [How to transcribe audio](#how-to-transcribe-audio) @@ -354,6 +355,75 @@ foreach (JsonElement stepElement in structuredJson.RootElement.GetProperty("step } ``` +## How to use chat completions with audio + +Starting with the `gpt-4o-audio-preview` model, chat completions can process audio input and output. + +This example demonstrates: + 1. Configuring the client with the supported `gpt-4o-audio-preview` model + 1. Supplying user audio input on a chat completion request + 1. Requesting model audio output from the chat completion operation + 1. Retrieving audio output from a `ChatCompletion` instance + 1. Using past audio output as `ChatMessage` conversation history + +```csharp +// Chat audio input and output is only supported on specific models, beginning with gpt-4o-audio-preview +ChatClient client = new("gpt-4o-audio-preview", Environment.GetEnvironmentVariable("OPENAI_API_KEY")); + +// Input audio is provided to a request by adding an audio content part to a user message +string audioFilePath = Path.Combine("Assets", "realtime_whats_the_weather_pcm16_24khz_mono.wav"); +byte[] audioFileRawBytes = File.ReadAllBytes(audioFilePath); +BinaryData audioData = BinaryData.FromBytes(audioFileRawBytes); +List messages = + [ + new UserChatMessage(ChatMessageContentPart.CreateInputAudioPart(audioData, ChatInputAudioFormat.Wav)), + ]; + +// Output audio is requested by configuring ChatCompletionOptions to include the appropriate +// ResponseModalities values and corresponding AudioOptions. +ChatCompletionOptions options = new() +{ + ResponseModalities = ChatResponseModalities.Text | ChatResponseModalities.Audio, + AudioOptions = new(ChatOutputAudioVoice.Alloy, ChatOutputAudioFormat.Mp3), +}; + +ChatCompletion completion = client.CompleteChat(messages, options); + +void PrintAudioContent() +{ + if (completion.OutputAudio is ChatOutputAudio outputAudio) + { + Console.WriteLine($"Response audio transcript: {outputAudio.Transcript}"); + string outputFilePath = $"{outputAudio.Id}.mp3"; + using (FileStream outputFileStream = File.OpenWrite(outputFilePath)) + { + outputFileStream.Write(outputAudio.AudioBytes); + } + Console.WriteLine($"Response audio written to file: {outputFilePath}"); + Console.WriteLine($"Valid on followup requests until: {outputAudio.ExpiresAt}"); + } +} + +PrintAudioContent(); + +// To refer to past audio output, create an assistant message from the earlier ChatCompletion, use the earlier +// response content part, or use ChatMessageContentPart.CreateAudioPart(string) to manually instantiate a part. + +messages.Add(new AssistantChatMessage(completion)); +messages.Add("Can you say that like a pirate?"); + +completion = client.CompleteChat(messages, options); + +PrintAudioContent(); +``` + +Streaming is highly parallel: `StreamingChatCompletionUpdate` instances can include a `OutputAudioUpdate` that may +contain any of: + +- The `Id` of the streamed audio content, which can be referenced by subsequent `AssistantChatMessage` instances via `ChatAudioReference` once the streaming response is complete; this may appear across multiple `StreamingChatCompletionUpdate` instances but will always be the same value when present +- The `ExpiresAt` value that describes when the `Id` will no longer be valid for use with `ChatAudioReference` in subsequent requests; this typically appears once and only once, in the final `StreamingOutputAudioUpdate` +- Incremental `TranscriptUpdate` and/or `AudioBytesUpdate` values, which can incrementally consumed and, when concatenated, form the complete audio transcript and audio output for the overall response; many of these typically appear + ## How to generate text embeddings In this example, you want to create a trip-planning website that allows customers to write a prompt describing the kind of hotel that they are looking for and then offers hotel recommendations that closely match this description. To achieve this, it is possible to use text embeddings to measure the relatedness of text strings. In summary, you can get embeddings of the hotel descriptions, store them in a vector database, and use them to build a search index that you can query using the embedding of a given customer's prompt. diff --git a/api/OpenAI.netstandard2.0.cs b/api/OpenAI.netstandard2.0.cs index b5b58780..84d1f0fa 100644 --- a/api/OpenAI.netstandard2.0.cs +++ b/api/OpenAI.netstandard2.0.cs @@ -224,7 +224,7 @@ public class AssistantCollectionOptions { public class AssistantCreationOptions : IJsonModel, IPersistableModel { public string Description { get; set; } public string Instructions { get; set; } - public IDictionary Metadata { get; set; } + public IDictionary Metadata { get; } public string Name { get; set; } public float? NucleusSamplingFactor { get; set; } public AssistantResponseFormat ResponseFormat { get; set; } @@ -244,7 +244,7 @@ public class AssistantModificationOptions : IJsonModel DefaultTools { get; } public string Description { get; set; } public string Instructions { get; set; } - public IDictionary Metadata { get; set; } + public IDictionary Metadata { get; } public string Model { get; set; } public string Name { get; set; } public float? NucleusSamplingFactor { get; set; } @@ -406,7 +406,7 @@ public class MessageCreationAttachment : IJsonModel, } public class MessageCreationOptions : IJsonModel, IPersistableModel { public IList Attachments { get; set; } - public IDictionary Metadata { get; set; } + public IDictionary Metadata { get; } public static explicit operator MessageCreationOptions(ClientResult result); public static implicit operator BinaryContent(MessageCreationOptions messageCreationOptions); } @@ -444,7 +444,7 @@ public enum MessageImageDetail { High = 2 } public class MessageModificationOptions : IJsonModel, IPersistableModel { - public IDictionary Metadata { get; set; } + public IDictionary Metadata { get; } public static explicit operator MessageModificationOptions(ClientResult result); public static implicit operator BinaryContent(MessageModificationOptions messageModificationOptions); } @@ -559,7 +559,7 @@ public class RunIncompleteDetails : IJsonModel, IPersistab public override readonly string ToString(); } public class RunModificationOptions : IJsonModel, IPersistableModel { - public IDictionary Metadata { get; set; } + public IDictionary Metadata { get; } public static explicit operator RunModificationOptions(ClientResult result); public static implicit operator BinaryContent(RunModificationOptions runModificationOptions); } @@ -809,7 +809,7 @@ public class TextAnnotationUpdate { } public class ThreadCreationOptions : IJsonModel, IPersistableModel { public IList InitialMessages { get; } - public IDictionary Metadata { get; set; } + public IDictionary Metadata { get; } public ToolResources ToolResources { get; set; } public static explicit operator ThreadCreationOptions(ClientResult result); public static implicit operator BinaryContent(ThreadCreationOptions threadCreationOptions); @@ -842,7 +842,7 @@ public class ThreadMessage : IJsonModel, IPersistableModel, IPersistableModel { - public IDictionary Metadata { get; set; } + public IDictionary Metadata { get; } public ToolResources ToolResources { get; set; } public static explicit operator ThreadModificationOptions(ClientResult result); public static implicit operator BinaryContent(ThreadModificationOptions threadModificationOptions); @@ -1050,10 +1050,13 @@ public class AudioTranslationOptions : IJsonModel, IPer public readonly partial struct GeneratedSpeechVoice : IEquatable { public GeneratedSpeechVoice(string value); public static GeneratedSpeechVoice Alloy { get; } + public static GeneratedSpeechVoice Ash { get; } + public static GeneratedSpeechVoice Coral { get; } public static GeneratedSpeechVoice Echo { get; } public static GeneratedSpeechVoice Fable { get; } public static GeneratedSpeechVoice Nova { get; } public static GeneratedSpeechVoice Onyx { get; } + public static GeneratedSpeechVoice Sage { get; } public static GeneratedSpeechVoice Shimmer { get; } public readonly bool Equals(GeneratedSpeechVoice other); [EditorBrowsable(EditorBrowsableState.Never)] @@ -1131,11 +1134,13 @@ public class AssistantChatMessage : ChatMessage, IJsonModel parameter instead.")] public AssistantChatMessage(ChatFunctionCall functionCall); public AssistantChatMessage(params ChatMessageContentPart[] contentParts); + public AssistantChatMessage(ChatOutputAudioReference outputAudioReference); public AssistantChatMessage(IEnumerable contentParts); public AssistantChatMessage(IEnumerable toolCalls); public AssistantChatMessage(string content); [Obsolete("This property is obsolete. Please use ToolCalls instead.")] public ChatFunctionCall FunctionCall { get; set; } + public ChatOutputAudioReference OutputAudioReference { get; set; } public string ParticipantName { get; set; } public string Refusal { get; set; } public IList ToolCalls { get; } @@ -1146,6 +1151,13 @@ public class AssistantChatMessage : ChatMessage, IJsonModel, IPersistableModel { + public ChatAudioOptions(ChatOutputAudioVoice outputAudioVoice, ChatOutputAudioFormat outputAudioFormat); + public ChatOutputAudioFormat OutputAudioFormat { get; } + public ChatOutputAudioVoice OutputAudioVoice { get; } + public static explicit operator ChatAudioOptions(ClientResult result); + public static implicit operator BinaryContent(ChatAudioOptions chatAudioOptions); + } public class ChatClient { protected ChatClient(); protected internal ChatClient(ClientPipeline pipeline, string model, OpenAIClientOptions options); @@ -1175,6 +1187,7 @@ public class ChatCompletion : IJsonModel, IPersistableModel RefusalTokenLogProbabilities { get; } public ChatMessageRole Role { get; } @@ -1186,6 +1199,7 @@ public class ChatCompletion : IJsonModel, IPersistableModel, IPersistableModel { public bool? AllowParallelToolCalls { get; set; } + public ChatAudioOptions AudioOptions { get; set; } public string EndUserId { get; set; } public float? FrequencyPenalty { get; set; } [Obsolete("This property is obsolete. Please use ToolChoice instead.")] @@ -1196,8 +1210,11 @@ public class ChatCompletionOptions : IJsonModel, IPersist public IDictionary LogitBiases { get; } public int? MaxOutputTokenCount { get; set; } public IDictionary Metadata { get; } + public ChatOutputPrediction OutputPrediction { get; set; } public float? PresencePenalty { get; set; } + public ChatReasoningEffortLevel? ReasoningEffortLevel { get; set; } public ChatResponseFormat ResponseFormat { get; set; } + public ChatResponseModalities ResponseModalities { get; set; } public long? Seed { get; set; } public IList StopSequences { get; } public bool? StoredOutputEnabled { get; set; } @@ -1256,6 +1273,20 @@ public class ChatFunctionChoice : IJsonModel, IPersistableMo public static bool operator !=(ChatImageDetailLevel left, ChatImageDetailLevel right); public override readonly string ToString(); } + public readonly partial struct ChatInputAudioFormat : IEquatable { + public ChatInputAudioFormat(string value); + public static ChatInputAudioFormat Mp3 { get; } + public static ChatInputAudioFormat Wav { get; } + public readonly bool Equals(ChatInputAudioFormat other); + [EditorBrowsable(EditorBrowsableState.Never)] + public override readonly bool Equals(object obj); + [EditorBrowsable(EditorBrowsableState.Never)] + public override readonly int GetHashCode(); + public static bool operator ==(ChatInputAudioFormat left, ChatInputAudioFormat right); + public static implicit operator ChatInputAudioFormat(string value); + public static bool operator !=(ChatInputAudioFormat left, ChatInputAudioFormat right); + public override readonly string ToString(); + } public class ChatInputTokenUsageDetails : IJsonModel, IPersistableModel { public int AudioTokenCount { get; } public int CachedTokenCount { get; } @@ -1267,9 +1298,13 @@ public class ChatMessage : IJsonModel, IPersistableModel contentParts); public static AssistantChatMessage CreateAssistantMessage(IEnumerable toolCalls); public static AssistantChatMessage CreateAssistantMessage(string content); + public static DeveloperChatMessage CreateDeveloperMessage(params ChatMessageContentPart[] contentParts); + public static DeveloperChatMessage CreateDeveloperMessage(IEnumerable contentParts); + public static DeveloperChatMessage CreateDeveloperMessage(string content); [Obsolete("This method is obsolete. Please use CreateToolMessage instead.")] public static FunctionChatMessage CreateFunctionMessage(string functionName, string content); public static SystemChatMessage CreateSystemMessage(params ChatMessageContentPart[] contentParts); @@ -1296,11 +1331,14 @@ public class ChatMessageContentPart : IJsonModel, IPersi public string ImageBytesMediaType { get; } public ChatImageDetailLevel? ImageDetailLevel { get; } public Uri ImageUri { get; } + public BinaryData InputAudioBytes { get; } + public ChatInputAudioFormat? InputAudioFormat { get; } public ChatMessageContentPartKind Kind { get; } public string Refusal { get; } public string Text { get; } public static ChatMessageContentPart CreateImagePart(BinaryData imageBytes, string imageBytesMediaType, ChatImageDetailLevel? imageDetailLevel = null); public static ChatMessageContentPart CreateImagePart(Uri imageUri, ChatImageDetailLevel? imageDetailLevel = null); + public static ChatMessageContentPart CreateInputAudioPart(BinaryData inputAudioBytes, ChatInputAudioFormat inputAudioFormat); public static ChatMessageContentPart CreateRefusalPart(string refusal); public static ChatMessageContentPart CreateTextPart(string text); public static explicit operator ChatMessageContentPart(ClientResult result); @@ -1310,21 +1348,97 @@ public class ChatMessageContentPart : IJsonModel, IPersi public enum ChatMessageContentPartKind { Text = 0, Refusal = 1, - Image = 2 + Image = 2, + InputAudio = 3 } public enum ChatMessageRole { System = 0, User = 1, Assistant = 2, Tool = 3, - Function = 4 + Function = 4, + Developer = 5 + } + public class ChatOutputAudio : IJsonModel, IPersistableModel { + public BinaryData AudioBytes { get; } + public DateTimeOffset ExpiresAt { get; } + public string Id { get; } + public string Transcript { get; } + public static explicit operator ChatOutputAudio(ClientResult result); + public static implicit operator BinaryContent(ChatOutputAudio chatOutputAudio); + } + public readonly partial struct ChatOutputAudioFormat : IEquatable { + public ChatOutputAudioFormat(string value); + public static ChatOutputAudioFormat Flac { get; } + public static ChatOutputAudioFormat Mp3 { get; } + public static ChatOutputAudioFormat Opus { get; } + public static ChatOutputAudioFormat Pcm16 { get; } + public static ChatOutputAudioFormat Wav { get; } + public readonly bool Equals(ChatOutputAudioFormat other); + [EditorBrowsable(EditorBrowsableState.Never)] + public override readonly bool Equals(object obj); + [EditorBrowsable(EditorBrowsableState.Never)] + public override readonly int GetHashCode(); + public static bool operator ==(ChatOutputAudioFormat left, ChatOutputAudioFormat right); + public static implicit operator ChatOutputAudioFormat(string value); + public static bool operator !=(ChatOutputAudioFormat left, ChatOutputAudioFormat right); + public override readonly string ToString(); + } + public class ChatOutputAudioReference : IJsonModel, IPersistableModel { + public ChatOutputAudioReference(string id); + public string Id { get; } + public static explicit operator ChatOutputAudioReference(ClientResult result); + public static implicit operator BinaryContent(ChatOutputAudioReference chatOutputAudioReference); + } + public readonly partial struct ChatOutputAudioVoice : IEquatable { + public ChatOutputAudioVoice(string value); + public static ChatOutputAudioVoice Alloy { get; } + public static ChatOutputAudioVoice Ash { get; } + public static ChatOutputAudioVoice Ballad { get; } + public static ChatOutputAudioVoice Coral { get; } + public static ChatOutputAudioVoice Echo { get; } + public static ChatOutputAudioVoice Sage { get; } + public static ChatOutputAudioVoice Shimmer { get; } + public static ChatOutputAudioVoice Verse { get; } + public readonly bool Equals(ChatOutputAudioVoice other); + [EditorBrowsable(EditorBrowsableState.Never)] + public override readonly bool Equals(object obj); + [EditorBrowsable(EditorBrowsableState.Never)] + public override readonly int GetHashCode(); + public static bool operator ==(ChatOutputAudioVoice left, ChatOutputAudioVoice right); + public static implicit operator ChatOutputAudioVoice(string value); + public static bool operator !=(ChatOutputAudioVoice left, ChatOutputAudioVoice right); + public override readonly string ToString(); + } + public class ChatOutputPrediction : IJsonModel, IPersistableModel { + public static ChatOutputPrediction CreateStaticContentPrediction(IEnumerable staticContentParts); + public static ChatOutputPrediction CreateStaticContentPrediction(string staticContent); + public static explicit operator ChatOutputPrediction(ClientResult result); + public static implicit operator BinaryContent(ChatOutputPrediction chatOutputPrediction); } public class ChatOutputTokenUsageDetails : IJsonModel, IPersistableModel { + public int AcceptedPredictionTokenCount { get; } public int AudioTokenCount { get; } public int ReasoningTokenCount { get; } + public int RejectedPredictionTokenCount { get; } public static explicit operator ChatOutputTokenUsageDetails(ClientResult result); public static implicit operator BinaryContent(ChatOutputTokenUsageDetails chatOutputTokenUsageDetails); } + public readonly partial struct ChatReasoningEffortLevel : IEquatable { + public ChatReasoningEffortLevel(string value); + public static ChatReasoningEffortLevel High { get; } + public static ChatReasoningEffortLevel Low { get; } + public static ChatReasoningEffortLevel Medium { get; } + public readonly bool Equals(ChatReasoningEffortLevel other); + [EditorBrowsable(EditorBrowsableState.Never)] + public override readonly bool Equals(object obj); + [EditorBrowsable(EditorBrowsableState.Never)] + public override readonly int GetHashCode(); + public static bool operator ==(ChatReasoningEffortLevel left, ChatReasoningEffortLevel right); + public static implicit operator ChatReasoningEffortLevel(string value); + public static bool operator !=(ChatReasoningEffortLevel left, ChatReasoningEffortLevel right); + public override readonly string ToString(); + } public class ChatResponseFormat : IJsonModel, IPersistableModel { public static ChatResponseFormat CreateJsonObjectFormat(); public static ChatResponseFormat CreateJsonSchemaFormat(string jsonSchemaFormatName, BinaryData jsonSchema, string jsonSchemaFormatDescription = null, bool? jsonSchemaIsStrict = null); @@ -1332,6 +1446,12 @@ public class ChatResponseFormat : IJsonModel, IPersistableMo public static explicit operator ChatResponseFormat(ClientResult result); public static implicit operator BinaryContent(ChatResponseFormat chatResponseFormat); } + [Flags] + public enum ChatResponseModalities { + Default = 0, + Text = 1, + Audio = 2 + } public class ChatTokenLogProbabilityDetails : IJsonModel, IPersistableModel { public float LogProbability { get; } public string Token { get; } @@ -1389,6 +1509,18 @@ public class ChatToolChoice : IJsonModel, IPersistableModel, IPersistableModel { + public DeveloperChatMessage(params ChatMessageContentPart[] contentParts); + public DeveloperChatMessage(IEnumerable contentParts); + public DeveloperChatMessage(string content); + public string ParticipantName { get; set; } + protected override ChatMessage JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options); + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options); + public new static explicit operator DeveloperChatMessage(ClientResult result); + public static implicit operator BinaryContent(DeveloperChatMessage developerChatMessage); + protected override ChatMessage PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options); + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options); + } [Obsolete("This class is obsolete. Please use ToolChatMessage instead.")] public class FunctionChatMessage : ChatMessage, IJsonModel, IPersistableModel { public FunctionChatMessage(string functionName, string content); @@ -1401,15 +1533,17 @@ public class FunctionChatMessage : ChatMessage, IJsonModel, protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options); } public static class OpenAIChatModelFactory { - public static ChatCompletion ChatCompletion(string id = null, ChatFinishReason finishReason = ChatFinishReason.Stop, ChatMessageContent content = null, string refusal = null, IEnumerable toolCalls = null, ChatMessageRole role = ChatMessageRole.System, ChatFunctionCall functionCall = null, IEnumerable contentTokenLogProbabilities = null, IEnumerable refusalTokenLogProbabilities = null, DateTimeOffset createdAt = default, string model = null, string systemFingerprint = null, ChatTokenUsage usage = null); + public static ChatCompletion ChatCompletion(string id = null, ChatFinishReason finishReason = ChatFinishReason.Stop, ChatMessageContent content = null, string refusal = null, IEnumerable toolCalls = null, ChatMessageRole role = ChatMessageRole.System, ChatFunctionCall functionCall = null, IEnumerable contentTokenLogProbabilities = null, IEnumerable refusalTokenLogProbabilities = null, DateTimeOffset createdAt = default, string model = null, string systemFingerprint = null, ChatTokenUsage usage = null, ChatOutputAudio outputAudio = null); public static ChatInputTokenUsageDetails ChatInputTokenUsageDetails(int audioTokenCount = 0, int cachedTokenCount = 0); - public static ChatOutputTokenUsageDetails ChatOutputTokenUsageDetails(int reasoningTokenCount = 0, int audioTokenCount = 0); + public static ChatOutputAudio ChatOutputAudio(BinaryData audioBytes, string id = null, string transcript = null, DateTimeOffset expiresAt = default); + public static ChatOutputTokenUsageDetails ChatOutputTokenUsageDetails(int reasoningTokenCount = 0, int audioTokenCount = 0, int acceptedPredictionTokenCount = 0, int rejectedPredictionTokenCount = 0); public static ChatTokenLogProbabilityDetails ChatTokenLogProbabilityDetails(string token = null, float logProbability = 0, ReadOnlyMemory? utf8Bytes = null, IEnumerable topLogProbabilities = null); public static ChatTokenTopLogProbabilityDetails ChatTokenTopLogProbabilityDetails(string token = null, float logProbability = 0, ReadOnlyMemory? utf8Bytes = null); public static ChatTokenUsage ChatTokenUsage(int outputTokenCount = 0, int inputTokenCount = 0, int totalTokenCount = 0, ChatOutputTokenUsageDetails outputTokenDetails = null, ChatInputTokenUsageDetails inputTokenDetails = null); - public static StreamingChatCompletionUpdate StreamingChatCompletionUpdate(string completionId = null, ChatMessageContent contentUpdate = null, StreamingChatFunctionCallUpdate functionCallUpdate = null, IEnumerable toolCallUpdates = null, ChatMessageRole? role = null, string refusalUpdate = null, IEnumerable contentTokenLogProbabilities = null, IEnumerable refusalTokenLogProbabilities = null, ChatFinishReason? finishReason = null, DateTimeOffset createdAt = default, string model = null, string systemFingerprint = null, ChatTokenUsage usage = null); + public static StreamingChatCompletionUpdate StreamingChatCompletionUpdate(string completionId = null, ChatMessageContent contentUpdate = null, StreamingChatFunctionCallUpdate functionCallUpdate = null, IEnumerable toolCallUpdates = null, ChatMessageRole? role = null, string refusalUpdate = null, IEnumerable contentTokenLogProbabilities = null, IEnumerable refusalTokenLogProbabilities = null, ChatFinishReason? finishReason = null, DateTimeOffset createdAt = default, string model = null, string systemFingerprint = null, ChatTokenUsage usage = null, StreamingChatOutputAudioUpdate outputAudioUpdate = null); [Obsolete("This class is obsolete. Please use StreamingChatToolCallUpdate instead.")] public static StreamingChatFunctionCallUpdate StreamingChatFunctionCallUpdate(string functionName = null, BinaryData functionArgumentsUpdate = null); + public static StreamingChatOutputAudioUpdate StreamingChatOutputAudioUpdate(string id = null, DateTimeOffset? expiresAt = null, string transcriptUpdate = null, BinaryData audioBytesUpdate = null); public static StreamingChatToolCallUpdate StreamingChatToolCallUpdate(int index = 0, string toolCallId = null, ChatToolCallKind kind = ChatToolCallKind.Function, string functionName = null, BinaryData functionArgumentsUpdate = null); } public class StreamingChatCompletionUpdate : IJsonModel, IPersistableModel { @@ -1421,6 +1555,7 @@ public class StreamingChatCompletionUpdate : IJsonModel RefusalTokenLogProbabilities { get; } public string RefusalUpdate { get; } public ChatMessageRole? Role { get; } @@ -1437,6 +1572,14 @@ public class StreamingChatFunctionCallUpdate : IJsonModel, IPersistableModel { + public BinaryData AudioBytesUpdate { get; } + public DateTimeOffset? ExpiresAt { get; } + public string Id { get; } + public string TranscriptUpdate { get; } + public static explicit operator StreamingChatOutputAudioUpdate(ClientResult result); + public static implicit operator BinaryContent(StreamingChatOutputAudioUpdate streamingChatOutputAudioUpdate); + } public class StreamingChatToolCallUpdate : IJsonModel, IPersistableModel { public BinaryData FunctionArgumentsUpdate { get; } public string FunctionName { get; } @@ -1945,6 +2088,7 @@ namespace OpenAI.RealtimeConversation { } [Flags] public enum ConversationContentModalities { + Default = 0, Text = 1, Audio = 2 } @@ -2000,6 +2144,22 @@ public class ConversationFunctionTool : ConversationTool, IJsonModel { + public ConversationIncompleteReason(string value); + public static ConversationIncompleteReason ClientCancelled { get; } + public static ConversationIncompleteReason ContentFilter { get; } + public static ConversationIncompleteReason MaxOutputTokens { get; } + public static ConversationIncompleteReason TurnDetected { get; } + public readonly bool Equals(ConversationIncompleteReason other); + [EditorBrowsable(EditorBrowsableState.Never)] + public override readonly bool Equals(object obj); + [EditorBrowsable(EditorBrowsableState.Never)] + public override readonly int GetHashCode(); + public static bool operator ==(ConversationIncompleteReason left, ConversationIncompleteReason right); + public static implicit operator ConversationIncompleteReason(string value); + public static bool operator !=(ConversationIncompleteReason left, ConversationIncompleteReason right); + public override readonly string ToString(); + } public class ConversationInputAudioClearedUpdate : ConversationUpdate, IJsonModel, IPersistableModel { protected override ConversationUpdate JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options); protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options); @@ -2039,9 +2199,9 @@ public class ConversationInputSpeechStartedUpdate : ConversationUpdate, IJsonMod protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options); } public class ConversationInputTokenUsageDetails : IJsonModel, IPersistableModel { - public int AudioTokens { get; } - public int CachedTokens { get; } - public int TextTokens { get; } + public int AudioTokenCount { get; } + public int CachedTokenCount { get; } + public int TextTokenCount { get; } public static explicit operator ConversationInputTokenUsageDetails(ClientResult result); public static implicit operator BinaryContent(ConversationInputTokenUsageDetails conversationInputTokenUsageDetails); } @@ -2257,8 +2417,8 @@ public class ConversationMaxTokensChoice : IJsonModel, IPersistableModel { - public int AudioTokens { get; } - public int TextTokens { get; } + public int AudioTokenCount { get; } + public int TextTokenCount { get; } public static explicit operator ConversationOutputTokenUsageDetails(ClientResult result); public static implicit operator BinaryContent(ConversationOutputTokenUsageDetails conversationOutputTokenUsageDetails); } @@ -2294,6 +2454,21 @@ public class ConversationResponseFinishedUpdate : ConversationUpdate, IJsonModel protected override ConversationUpdate PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options); protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options); } + public class ConversationResponseOptions : IJsonModel, IPersistableModel { + public ConversationContentModalities ContentModalities { get; set; } + public ResponseConversationSelection? ConversationSelection { get; set; } + public string Instructions { get; set; } + public ConversationMaxTokensChoice MaxOutputTokens { get; set; } + public IDictionary Metadata { get; } + public ConversationAudioFormat? OutputAudioFormat { get; set; } + public IList OverrideItems { get; } + public float? Temperature { get; set; } + public ConversationToolChoice ToolChoice { get; set; } + public IList Tools { get; } + public ConversationVoice? Voice { get; set; } + public static explicit operator ConversationResponseOptions(ClientResult result); + public static implicit operator BinaryContent(ConversationResponseOptions conversationResponseOptions); + } public class ConversationResponseStartedUpdate : ConversationUpdate, IJsonModel, IPersistableModel { public IReadOnlyList CreatedItems { get; } public string ResponseId { get; } @@ -2370,7 +2545,6 @@ public class ConversationSessionStartedUpdate : ConversationUpdate, IJsonModel, IPersistableModel { + public class ConversationStatusDetails : IJsonModel, IPersistableModel { + public string ErrorCode { get; } + public string ErrorKind { get; } + public ConversationIncompleteReason? IncompleteReason { get; } public ConversationStatus StatusKind { get; } public static explicit operator ConversationStatusDetails(ClientResult result); public static implicit operator BinaryContent(ConversationStatusDetails conversationStatusDetails); } public class ConversationTokenUsage : IJsonModel, IPersistableModel { + public int InputTokenCount { get; } public ConversationInputTokenUsageDetails InputTokenDetails { get; } - public int InputTokens { get; } + public int OutputTokenCount { get; } public ConversationOutputTokenUsageDetails OutputTokenDetails { get; } - public int OutputTokens { get; } - public int TotalTokens { get; } + public int TotalTokenCount { get; } public static explicit operator ConversationTokenUsage(ClientResult result); public static implicit operator BinaryContent(ConversationTokenUsage conversationTokenUsage); } @@ -2449,7 +2626,7 @@ public enum ConversationTurnDetectionKind { public abstract class ConversationTurnDetectionOptions : IJsonModel, IPersistableModel { public ConversationTurnDetectionKind Kind { get; protected internal set; } public static ConversationTurnDetectionOptions CreateDisabledTurnDetectionOptions(); - public static ConversationTurnDetectionOptions CreateServerVoiceActivityTurnDetectionOptions(float? detectionThreshold = null, TimeSpan? prefixPaddingDuration = null, TimeSpan? silenceDuration = null); + public static ConversationTurnDetectionOptions CreateServerVoiceActivityTurnDetectionOptions(float? detectionThreshold = null, TimeSpan? prefixPaddingDuration = null, TimeSpan? silenceDuration = null, bool? enableAutomaticResponseCreation = null); public static explicit operator ConversationTurnDetectionOptions(ClientResult result); public static implicit operator BinaryContent(ConversationTurnDetectionOptions conversationTurnDetectionOptions); } @@ -2494,8 +2671,13 @@ public enum ConversationUpdateKind { public readonly partial struct ConversationVoice : IEquatable { public ConversationVoice(string value); public static ConversationVoice Alloy { get; } + public static ConversationVoice Ash { get; } + public static ConversationVoice Ballad { get; } + public static ConversationVoice Coral { get; } public static ConversationVoice Echo { get; } + public static ConversationVoice Sage { get; } public static ConversationVoice Shimmer { get; } + public static ConversationVoice Verse { get; } public readonly bool Equals(ConversationVoice other); [EditorBrowsable(EditorBrowsableState.Never)] public override readonly bool Equals(object obj); @@ -2556,13 +2738,27 @@ public class RealtimeConversationSession : IDisposable { public virtual void SendInputAudio(Stream audio, CancellationToken cancellationToken = default); public virtual Task SendInputAudioAsync(BinaryData audio, CancellationToken cancellationToken = default); public virtual Task SendInputAudioAsync(Stream audio, CancellationToken cancellationToken = default); - public virtual void StartResponse(ConversationSessionOptions sessionOptionOverrides, CancellationToken cancellationToken = default); - public virtual void StartResponse(CancellationToken cancellationToken = default); - public virtual Task StartResponseAsync(ConversationSessionOptions sessionOptionOverrides, CancellationToken cancellationToken = default); + public virtual void StartResponse(ConversationResponseOptions options, CancellationToken cancellationToken = default); + public void StartResponse(CancellationToken cancellationToken = default); + public virtual Task StartResponseAsync(ConversationResponseOptions options, CancellationToken cancellationToken = default); public virtual Task StartResponseAsync(CancellationToken cancellationToken = default); 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 readonly partial struct ResponseConversationSelection : IEquatable { + public ResponseConversationSelection(string value); + public static ResponseConversationSelection Auto { get; } + public static ResponseConversationSelection None { get; } + public readonly bool Equals(ResponseConversationSelection other); + [EditorBrowsable(EditorBrowsableState.Never)] + public override readonly bool Equals(object obj); + [EditorBrowsable(EditorBrowsableState.Never)] + public override readonly int GetHashCode(); + public static bool operator ==(ResponseConversationSelection left, ResponseConversationSelection right); + public static implicit operator ResponseConversationSelection(string value); + public static bool operator !=(ResponseConversationSelection left, ResponseConversationSelection right); + public override readonly string ToString(); + } } namespace OpenAI.VectorStores { public class AddFileToVectorStoreOperation : OperationResult { @@ -2793,7 +2989,7 @@ public class VectorStoreCreationOptions : IJsonModel public FileChunkingStrategy ChunkingStrategy { get; set; } public VectorStoreExpirationPolicy ExpirationPolicy { get; set; } public IList FileIds { get; } - public IDictionary Metadata { get; set; } + public IDictionary Metadata { get; } public string Name { get; set; } public static explicit operator VectorStoreCreationOptions(ClientResult result); public static implicit operator BinaryContent(VectorStoreCreationOptions vectorStoreCreationOptions); @@ -2903,7 +3099,7 @@ public class VectorStoreFileCounts : IJsonModel, IPersist } public class VectorStoreModificationOptions : IJsonModel, IPersistableModel { public VectorStoreExpirationPolicy ExpirationPolicy { get; set; } - public IDictionary Metadata { get; set; } + public IDictionary Metadata { get; } public string Name { get; set; } public static explicit operator VectorStoreModificationOptions(ClientResult result); public static implicit operator BinaryContent(VectorStoreModificationOptions vectorStoreModificationOptions); diff --git a/examples/Chat/Example09_ChatWithAudio.cs b/examples/Chat/Example09_ChatWithAudio.cs new file mode 100644 index 00000000..b18ad79e --- /dev/null +++ b/examples/Chat/Example09_ChatWithAudio.cs @@ -0,0 +1,63 @@ +using NUnit.Framework; +using OpenAI.Chat; +using System; +using System.Collections.Generic; +using System.IO; + +namespace OpenAI.Examples; + +public partial class ChatExamples +{ + [Test] + public void Example09_ChatWithAudio() + { + // Chat audio input and output is only supported on specific models, beginning with gpt-4o-audio-preview + ChatClient client = new("gpt-4o-audio-preview", Environment.GetEnvironmentVariable("OPENAI_API_KEY")); + + // Input audio is provided to a request by adding an audio content part to a user message + string audioFilePath = Path.Combine("Assets", "realtime_whats_the_weather_pcm16_24khz_mono.wav"); + byte[] audioFileRawBytes = File.ReadAllBytes(audioFilePath); + BinaryData audioData = BinaryData.FromBytes(audioFileRawBytes); + List messages = + [ + new UserChatMessage(ChatMessageContentPart.CreateInputAudioPart(audioData, ChatInputAudioFormat.Wav)), + ]; + + // Output audio is requested by configuring ChatCompletionOptions to include the appropriate + // ResponseModalities values and corresponding AudioOptions. + ChatCompletionOptions options = new() + { + ResponseModalities = ChatResponseModalities.Text | ChatResponseModalities.Audio, + AudioOptions = new(ChatOutputAudioVoice.Alloy, ChatOutputAudioFormat.Mp3), + }; + + ChatCompletion completion = client.CompleteChat(messages, options); + + void PrintAudioContent() + { + if (completion.OutputAudio is ChatOutputAudio outputAudio) + { + Console.WriteLine($"Response audio transcript: {outputAudio.Transcript}"); + string outputFilePath = $"{outputAudio.Id}.mp3"; + using (FileStream outputFileStream = File.OpenWrite(outputFilePath)) + { + outputFileStream.Write(outputAudio.AudioBytes); + } + Console.WriteLine($"Response audio written to file: {outputFilePath}"); + Console.WriteLine($"Valid on followup requests until: {outputAudio.ExpiresAt}"); + } + } + + PrintAudioContent(); + + // To refer to past audio output, create an assistant message from the earlier ChatCompletion, use the earlier + // response content part, or use ChatMessageContentPart.CreateAudioPart(string) to manually instantiate a part. + + messages.Add(new AssistantChatMessage(completion)); + messages.Add("Can you say that like a pirate?"); + + completion = client.CompleteChat(messages, options); + + PrintAudioContent(); + } +} diff --git a/examples/Chat/Example09_ChatWithAudioAsync.cs b/examples/Chat/Example09_ChatWithAudioAsync.cs new file mode 100644 index 00000000..529c0c60 --- /dev/null +++ b/examples/Chat/Example09_ChatWithAudioAsync.cs @@ -0,0 +1,64 @@ +using NUnit.Framework; +using OpenAI.Chat; +using System; +using System.Collections.Generic; +using System.IO; +using System.Threading.Tasks; + +namespace OpenAI.Examples; + +public partial class ChatExamples +{ + [Test] + public async Task Example09_ChatWithAudioAsync() + { + // Chat audio input and output is only supported on specific models, beginning with gpt-4o-audio-preview + ChatClient client = new("gpt-4o-audio-preview", Environment.GetEnvironmentVariable("OPENAI_API_KEY")); + + // Input audio is provided to a request by adding an audio content part to a user message + string audioFilePath = Path.Combine("Assets", "realtime_whats_the_weather_pcm16_24khz_mono.wav"); + byte[] audioFileRawBytes = await File.ReadAllBytesAsync(audioFilePath); + BinaryData audioData = BinaryData.FromBytes(audioFileRawBytes); + List messages = + [ + new UserChatMessage(ChatMessageContentPart.CreateInputAudioPart(audioData, ChatInputAudioFormat.Wav)), + ]; + + // Output audio is requested by configuring ChatCompletionOptions to include the appropriate + // ResponseModalities values and corresponding AudioOptions. + ChatCompletionOptions options = new() + { + ResponseModalities = ChatResponseModalities.Text | ChatResponseModalities.Audio, + AudioOptions = new(ChatOutputAudioVoice.Alloy, ChatOutputAudioFormat.Mp3), + }; + + ChatCompletion completion = await client.CompleteChatAsync(messages, options); + + async Task PrintAudioContentAsync() + { + if (completion.OutputAudio is ChatOutputAudio outputAudio) + { + Console.WriteLine($"Response audio transcript: {outputAudio.Transcript}"); + string outputFilePath = $"{outputAudio.Id}.mp3"; + using (FileStream outputFileStream = File.OpenWrite(outputFilePath)) + { + await outputFileStream.WriteAsync(outputAudio.AudioBytes); + } + Console.WriteLine($"Response audio written to file: {outputFilePath}"); + Console.WriteLine($"Valid on followup requests until: {outputAudio.ExpiresAt}"); + } + } + + await PrintAudioContentAsync(); + + // To refer to past audio output, create an assistant message from the earlier ChatCompletion, use the earlier + // response content part, or use ChatMessageContentPart.CreateAudioPart(string) to manually instantiate a part. + + messages.Add(new AssistantChatMessage(completion)); + messages.Add("Can you say that like a pirate?"); + + completion = await client.CompleteChatAsync(messages, options); + + await PrintAudioContentAsync(); + } +} diff --git a/src/Custom/Assistants/Internal/GeneratorStubs.Internal.cs b/src/Custom/Assistants/Internal/GeneratorStubs.Internal.cs index 5748a3ab..0fc14de6 100644 --- a/src/Custom/Assistants/Internal/GeneratorStubs.Internal.cs +++ b/src/Custom/Assistants/Internal/GeneratorStubs.Internal.cs @@ -206,7 +206,11 @@ internal partial class InternalRunStepDeltaStepDetailsMessageCreationObject { } internal partial class InternalRunStepDeltaStepDetailsToolCallsObject { } [CodeGenModel("RunStepDeltaStepDetailsToolCallsFileSearchObject")] -internal partial class InternalRunStepDeltaStepDetailsToolCallsFileSearchObject { } +internal partial class InternalRunStepDeltaStepDetailsToolCallsFileSearchObject +{ + [CodeGenMember("FileSearch")] + public InternalRunStepDetailsToolCallsFileSearchObjectFileSearch FileSearch { get; set; } +} [CodeGenModel("RunStepDeltaStepDetailsToolCallsFunctionObject")] internal partial class InternalRunStepDeltaStepDetailsToolCallsFunctionObject { } diff --git a/src/Custom/Assistants/RunStepToolCallKind.cs b/src/Custom/Assistants/RunStepToolCallKind.cs index f4d83a56..f99fc0a7 100644 --- a/src/Custom/Assistants/RunStepToolCallKind.cs +++ b/src/Custom/Assistants/RunStepToolCallKind.cs @@ -3,7 +3,7 @@ namespace OpenAI.Assistants; [Experimental("OPENAI001")] -[CodeGenModel("RunStepDetailsToolCallKind")] +[CodeGenModel("RunStepDetailsToolCallType")] public enum RunStepToolCallKind { CodeInterpreter, diff --git a/src/Custom/Chat/ChatAudioOptions.cs b/src/Custom/Chat/ChatAudioOptions.cs new file mode 100644 index 00000000..03b4f6a5 --- /dev/null +++ b/src/Custom/Chat/ChatAudioOptions.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; + +namespace OpenAI.Chat; + +/// +/// Represents the configuration details for output audio requested in a chat completion request. +/// +/// +/// When provided to a instance's property, +/// the request's specified content modalities will be automatically updated to reflect desired audio output. +/// +[CodeGenModel("CreateChatCompletionRequestAudio")] +public partial class ChatAudioOptions +{ + // CUSTOM: Renamed. + /// + /// Gets or sets the voice model that the response should use to synthesize audio. + /// + [CodeGenMember("Voice")] + public ChatOutputAudioVoice OutputAudioVoice { get; } + + // CUSTOM: Renamed. + /// + /// Specifies the output format desired for synthesized audio. + /// + [CodeGenMember("Format")] + public ChatOutputAudioFormat OutputAudioFormat { get; } +} diff --git a/src/Custom/Chat/ChatCompletion.cs b/src/Custom/Chat/ChatCompletion.cs index 03f9ea3f..bb57e3c0 100644 --- a/src/Custom/Chat/ChatCompletion.cs +++ b/src/Custom/Chat/ChatCompletion.cs @@ -84,4 +84,7 @@ public partial class ChatCompletion // CUSTOM: Flattened choice message property. [Obsolete($"This property is obsolete. Please use {nameof(ToolCalls)} instead.")] public ChatFunctionCall FunctionCall => Choices[0].Message.FunctionCall; + + /// The audio response generated by the model. + public ChatOutputAudio OutputAudio => Choices[0].Message.Audio; } diff --git a/src/Custom/Chat/ChatCompletionOptions.cs b/src/Custom/Chat/ChatCompletionOptions.cs index d5b3b454..b0136a2b 100644 --- a/src/Custom/Chat/ChatCompletionOptions.cs +++ b/src/Custom/Chat/ChatCompletionOptions.cs @@ -176,4 +176,51 @@ public ChatCompletionOptions() /// [CodeGenMember("Store")] public bool? StoredOutputEnabled { get; set; } + + // CUSTOM: Renamed. + /// + /// (o1 and newer reasoning models only) Constrains effort on reasoning for reasoning models. + /// Currently supported values are , , and . + /// Reducing reasoning effort can result in faster responses and fewer tokens used on reasoning in a response. + /// + [CodeGenMember("ReasoningEffort")] + public ChatReasoningEffortLevel? ReasoningEffortLevel { get; set; } + + // CUSTOM: Made internal for automatic enablement via audio options. + [CodeGenMember("Modalities")] + private IList _internalModalities = new ChangeTrackingList(); + + /// + /// Specifies the content types that the model should generate in its responses. + /// + /// + /// Most models can generate text and the default ["text"] value, from , requests this. + /// Some models like gpt-4o-audio-preview can also generate audio, and this can be requested by combining ["text","audio"] via + /// the flags | . + /// + public ChatResponseModalities ResponseModalities + { + get => ChatResponseModalitiesExtensions.FromInternalModalities(_internalModalities); + set => _internalModalities = value.ToInternalModalities(); + } + + // CUSTOM: supplemented with custom setter to internally enable audio output via modalities. + [CodeGenMember("Audio")] + private ChatAudioOptions _audioOptions; + + public ChatAudioOptions AudioOptions + { + get => _audioOptions; + set + { + _audioOptions = value; + _internalModalities = value is null + ? new ChangeTrackingList() + : [InternalCreateChatCompletionRequestModality.Text, InternalCreateChatCompletionRequestModality.Audio]; + } + } + + // CUSTOM: rename. + [CodeGenMember("Prediction")] + public ChatOutputPrediction OutputPrediction { get; set; } } diff --git a/src/Custom/Chat/ChatInputAudioFormat.cs b/src/Custom/Chat/ChatInputAudioFormat.cs new file mode 100644 index 00000000..cd32981e --- /dev/null +++ b/src/Custom/Chat/ChatInputAudioFormat.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; + +namespace OpenAI.Chat; + +[CodeGenModel("ChatCompletionRequestMessageContentPartAudioInputAudioFormat")] +public readonly partial struct ChatInputAudioFormat +{ + +} diff --git a/src/Custom/Chat/ChatMessageContent.Serialization.cs b/src/Custom/Chat/ChatMessageContent.Serialization.cs new file mode 100644 index 00000000..6bae5371 --- /dev/null +++ b/src/Custom/Chat/ChatMessageContent.Serialization.cs @@ -0,0 +1,51 @@ +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text.Json; + +namespace OpenAI.Chat; + +public partial class ChatMessageContent +{ + internal void WriteTo(Utf8JsonWriter writer, ModelReaderWriterOptions options = null) + { + if (Count == 0) + { + writer.WriteNullValue(); + } + else if (Count == 1 && this[0].Kind == ChatMessageContentPartKind.Text) + { + writer.WriteStringValue(this[0].Text); + } + else + { + writer.WriteStartArray(); + foreach (ChatMessageContentPart part in this) + { + writer.WriteObjectValue(part, options); + } + writer.WriteEndArray(); + } + } + + internal static ChatMessageContent DeserializeChatMessageContent(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new("W"); + if (element.ValueKind == JsonValueKind.String) + { + return new(element.GetString()); + } + else if (element.ValueKind == JsonValueKind.Array) + { + List parts = []; + foreach (JsonElement contentPartElement in element.EnumerateArray()) + { + parts.Add(ChatMessageContentPart.DeserializeChatMessageContentPart(contentPartElement, options)); + } + return new(parts); + } + return new(); + } +} diff --git a/src/Custom/Chat/ChatMessageContent.cs b/src/Custom/Chat/ChatMessageContent.cs index f7a63114..54868ae3 100644 --- a/src/Custom/Chat/ChatMessageContent.cs +++ b/src/Custom/Chat/ChatMessageContent.cs @@ -9,7 +9,7 @@ namespace OpenAI.Chat; public partial class ChatMessageContent : Collection { public ChatMessageContent() - : this(Array.Empty()) + : base(new ChangeTrackingList()) { } diff --git a/src/Custom/Chat/ChatMessageContentPart.Serialization.cs b/src/Custom/Chat/ChatMessageContentPart.Serialization.cs index eb2277bf..20faaf3f 100644 --- a/src/Custom/Chat/ChatMessageContentPart.Serialization.cs +++ b/src/Custom/Chat/ChatMessageContentPart.Serialization.cs @@ -33,6 +33,11 @@ internal static void WriteCoreContentPart(ChatMessageContentPart instance, Utf8J writer.WritePropertyName("image_url"u8); writer.WriteObjectValue(instance._imageUri, options); } + else if (instance._kind == ChatMessageContentPartKind.InputAudio) + { + writer.WritePropertyName("input_audio"u8); + writer.WriteObjectValue(instance._inputAudio, options); + } writer.WriteSerializedAdditionalRawData(instance._additionalBinaryDataProperties, options); writer.WriteEndObject(); } @@ -50,6 +55,7 @@ internal static ChatMessageContentPart DeserializeChatMessageContentPart(JsonEle string text = default; string refusal = default; InternalChatCompletionRequestMessageContentPartImageImageUrl imageUri = default; + InternalChatCompletionRequestMessageContentPartAudioInputAudio inputAudio = default; IDictionary serializedAdditionalRawData = default; Dictionary rawDataDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) @@ -74,12 +80,18 @@ internal static ChatMessageContentPart DeserializeChatMessageContentPart(JsonEle refusal = property.Value.GetString(); continue; } + if (property.NameEquals("input_audio"u8)) + { + inputAudio = InternalChatCompletionRequestMessageContentPartAudioInputAudio + .DeserializeInternalChatCompletionRequestMessageContentPartAudioInputAudio(property.Value, options); + continue; + } if (true) { rawDataDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); } } serializedAdditionalRawData = rawDataDictionary; - return new ChatMessageContentPart(kind, text, imageUri, refusal, serializedAdditionalRawData); + return new ChatMessageContentPart(kind, text, imageUri, refusal, inputAudio, serializedAdditionalRawData); } } diff --git a/src/Custom/Chat/ChatMessageContentPart.cs b/src/Custom/Chat/ChatMessageContentPart.cs index f170d8b8..1d960780 100644 --- a/src/Custom/Chat/ChatMessageContentPart.cs +++ b/src/Custom/Chat/ChatMessageContentPart.cs @@ -19,6 +19,10 @@ namespace OpenAI.Chat; /// Call to create a that /// encapsulates a refusal coming from the model. /// +/// +/// Call to create a content part +/// encapsulating input audio for user role messages. +/// /// /// [CodeGenModel("ChatMessageContentPart")] @@ -28,6 +32,7 @@ public partial class ChatMessageContentPart private readonly ChatMessageContentPartKind _kind; private readonly string _text; private readonly InternalChatCompletionRequestMessageContentPartImageImageUrl _imageUri; + private readonly InternalChatCompletionRequestMessageContentPartAudioInputAudio _inputAudio; private readonly string _refusal; // CUSTOM: Made internal. @@ -36,12 +41,19 @@ internal ChatMessageContentPart() } // CUSTOM: Added to support deserialization. - internal ChatMessageContentPart(ChatMessageContentPartKind kind, string text, InternalChatCompletionRequestMessageContentPartImageImageUrl imageUri, string refusal, IDictionary serializedAdditionalRawData) + internal ChatMessageContentPart( + ChatMessageContentPartKind kind, + string text = default, + InternalChatCompletionRequestMessageContentPartImageImageUrl imageUri = default, + string refusal = default, + InternalChatCompletionRequestMessageContentPartAudioInputAudio inputAudio = default, + IDictionary serializedAdditionalRawData = default) { _kind = kind; _text = text; _imageUri = imageUri; _refusal = refusal; + _inputAudio = inputAudio; _additionalBinaryDataProperties = serializedAdditionalRawData; } @@ -68,6 +80,24 @@ internal ChatMessageContentPart(ChatMessageContentPartKind kind, string text, In /// Present when is . public string ImageBytesMediaType => _imageUri?.ImageBytesMediaType; + /// + /// The encoded binary audio payload associated with the content part. + /// + /// + /// Present when is . The content part + /// represents user role audio input. + /// + public BinaryData InputAudioBytes => _inputAudio?.Data; + + /// + /// The encoding format that the audio data provided in should be interpreted with. + /// + /// + /// Present when is . The content part + /// represents user role audio input. + /// + public ChatInputAudioFormat? InputAudioFormat => _inputAudio?.Format; + // CUSTOM: Spread. /// /// The level of detail with which the model should process the image and generate its textual understanding of @@ -88,12 +118,7 @@ public static ChatMessageContentPart CreateTextPart(string text) { Argument.AssertNotNull(text, nameof(text)); - return new ChatMessageContentPart( - kind: ChatMessageContentPartKind.Text, - text: text, - imageUri: null, - refusal: null, - serializedAdditionalRawData: null); + return new ChatMessageContentPart(ChatMessageContentPartKind.Text, text: text); } /// Creates a new that encapsulates an image. @@ -109,10 +134,7 @@ public static ChatMessageContentPart CreateImagePart(Uri imageUri, ChatImageDeta return new ChatMessageContentPart( kind: ChatMessageContentPartKind.Image, - text: null, - imageUri: new(imageUri) { Detail = imageDetailLevel }, - refusal: null, - serializedAdditionalRawData: null); + imageUri: new(imageUri) { Detail = imageDetailLevel }); } /// Creates a new that encapsulates an image. @@ -131,10 +153,7 @@ public static ChatMessageContentPart CreateImagePart(BinaryData imageBytes, stri return new ChatMessageContentPart( kind: ChatMessageContentPartKind.Image, - text: null, - imageUri: new(imageBytes, imageBytesMediaType) { Detail = imageDetailLevel }, - refusal: null, - serializedAdditionalRawData: null); + imageUri: new(imageBytes, imageBytesMediaType) { Detail = imageDetailLevel }); } /// Creates a new that encapsulates a refusal coming from the model. @@ -146,10 +165,23 @@ public static ChatMessageContentPart CreateRefusalPart(string refusal) return new ChatMessageContentPart( kind: ChatMessageContentPartKind.Refusal, - text: null, - imageUri: null, - refusal: refusal, - serializedAdditionalRawData: null); + refusal: refusal); + } + + /// Creates a new that encapsulates user role input audio in a known format. + /// + /// Binary audio content parts may only be used with instances to represent user audio input. When referring to + /// past audio output from the model, use instead. + /// + /// The audio data. + /// The format of the audio data. + public static ChatMessageContentPart CreateInputAudioPart(BinaryData inputAudioBytes, ChatInputAudioFormat inputAudioFormat) + { + Argument.AssertNotNull(inputAudioBytes, nameof(inputAudioBytes)); + + return new ChatMessageContentPart( + kind: ChatMessageContentPartKind.InputAudio, + inputAudio: new(inputAudioBytes, inputAudioFormat)); } /// diff --git a/src/Custom/Chat/ChatMessageContentPartKind.Serialization.cs b/src/Custom/Chat/ChatMessageContentPartKind.Serialization.cs index 2ef688cd..eae666c7 100644 --- a/src/Custom/Chat/ChatMessageContentPartKind.Serialization.cs +++ b/src/Custom/Chat/ChatMessageContentPartKind.Serialization.cs @@ -13,6 +13,7 @@ internal static partial class ChatMessageContentPartKindExtensions ChatMessageContentPartKind.Text => "text", ChatMessageContentPartKind.Refusal => "refusal", ChatMessageContentPartKind.Image => "image_url", + ChatMessageContentPartKind.InputAudio => "input_audio", _ => throw new ArgumentOutOfRangeException(nameof(value), value, "Unknown ChatMessageContentPartKind value.") }; @@ -21,6 +22,7 @@ public static ChatMessageContentPartKind ToChatMessageContentPartKind(this strin if (StringComparer.OrdinalIgnoreCase.Equals(value, "text")) return ChatMessageContentPartKind.Text; if (StringComparer.OrdinalIgnoreCase.Equals(value, "refusal")) return ChatMessageContentPartKind.Refusal; if (StringComparer.OrdinalIgnoreCase.Equals(value, "image_url")) return ChatMessageContentPartKind.Image; + if (StringComparer.OrdinalIgnoreCase.Equals(value, "input_audio")) return ChatMessageContentPartKind.InputAudio; throw new ArgumentOutOfRangeException(nameof(value), value, "Unknown ChatMessageContentPartKind value."); } } diff --git a/src/Custom/Chat/ChatMessageContentPartKind.cs b/src/Custom/Chat/ChatMessageContentPartKind.cs index a6cc4f5e..c371039b 100644 --- a/src/Custom/Chat/ChatMessageContentPartKind.cs +++ b/src/Custom/Chat/ChatMessageContentPartKind.cs @@ -9,5 +9,7 @@ public enum ChatMessageContentPartKind Refusal, - Image + Image, + + InputAudio, } \ No newline at end of file diff --git a/src/Custom/Chat/ChatMessageRole.cs b/src/Custom/Chat/ChatMessageRole.cs index 6611ec5d..53dce4c7 100644 --- a/src/Custom/Chat/ChatMessageRole.cs +++ b/src/Custom/Chat/ChatMessageRole.cs @@ -11,6 +11,11 @@ namespace OpenAI.Chat; /// Description /// /// +/// - +/// developer - +/// Instructions to the model that guide the behavior of future assistant messages. Replaces system in o1 and newer models. +/// +/// /// - /// system - /// Instructions to the model that guide the behavior of future assistant messages. @@ -92,4 +97,14 @@ public enum ChatMessageRole /// [CodeGenMember("Function")] Function, + + /// + /// The developer role, which provides instructions to the model that guide the behavior of future + /// assistant messages + /// + /// + /// developer replaces system when using o1 and newer models. + /// + [CodeGenMember("Developer")] + Developer, } \ No newline at end of file diff --git a/src/Custom/Chat/ChatOutputAudio.cs b/src/Custom/Chat/ChatOutputAudio.cs new file mode 100644 index 00000000..1c151bc9 --- /dev/null +++ b/src/Custom/Chat/ChatOutputAudio.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Text.RegularExpressions; + +namespace OpenAI.Chat; + +/// +/// Represents the audio output generated by the model as part of a chat completion response. +/// +[CodeGenModel("ChatCompletionResponseMessageAudio")] +public partial class ChatOutputAudio +{ + // CUSTOM: Renamed. + [CodeGenMember("Data")] + public BinaryData AudioBytes { get; } +} \ No newline at end of file diff --git a/src/Custom/Chat/ChatOutputAudioFormat.cs b/src/Custom/Chat/ChatOutputAudioFormat.cs new file mode 100644 index 00000000..12cb5e90 --- /dev/null +++ b/src/Custom/Chat/ChatOutputAudioFormat.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; + +namespace OpenAI.Chat; + +/// +/// Specifies the audio format the model should use when generating output audio as part of a chat completion +/// response. +/// +[CodeGenModel("CreateChatCompletionRequestAudioFormat")] +public readonly partial struct ChatOutputAudioFormat +{ + +} diff --git a/src/Custom/Chat/ChatOutputAudioReference.cs b/src/Custom/Chat/ChatOutputAudioReference.cs new file mode 100644 index 00000000..2991ca10 --- /dev/null +++ b/src/Custom/Chat/ChatOutputAudioReference.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Text.RegularExpressions; + +namespace OpenAI.Chat; + +/// +/// Represents an ID-based reference to a past audio output as received from a prior chat completion response, as +/// provided when creating an instance for use in a conversation history. +/// +/// +/// This value is obtained from the or +/// properties for streaming and non-streaming +/// responses, respectively. The constructor overload can also be +/// used to automatically populate the appropriate properties from a instance. +/// +[CodeGenModel("ChatCompletionRequestAssistantMessageAudio")] +public partial class ChatOutputAudioReference +{ +} \ No newline at end of file diff --git a/src/Custom/Chat/ChatOutputAudioVoice.cs b/src/Custom/Chat/ChatOutputAudioVoice.cs new file mode 100644 index 00000000..4d8fc3bd --- /dev/null +++ b/src/Custom/Chat/ChatOutputAudioVoice.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; + +namespace OpenAI.Chat; + +/// +/// Specifies the available voices that the model can use when generating output audio as part of a chat completion. +/// +[CodeGenModel("CreateChatCompletionRequestAudioVoice")] +public readonly partial struct ChatOutputAudioVoice +{ + +} diff --git a/src/Custom/Chat/ChatOutputPrediction.cs b/src/Custom/Chat/ChatOutputPrediction.cs new file mode 100644 index 00000000..d355c4d3 --- /dev/null +++ b/src/Custom/Chat/ChatOutputPrediction.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; + +namespace OpenAI.Chat; + +[CodeGenModel("ChatOutputPrediction")] +public partial class ChatOutputPrediction +{ + public static ChatOutputPrediction CreateStaticContentPrediction(IEnumerable staticContentParts) + => new InternalChatOutputPredictionContent(new ChatMessageContent(staticContentParts)); + + public static ChatOutputPrediction CreateStaticContentPrediction(string staticContent) + => new InternalChatOutputPredictionContent([ChatMessageContentPart.CreateTextPart(staticContent)]); +} \ No newline at end of file diff --git a/src/Custom/Chat/ChatOutputTokenUsageDetails.cs b/src/Custom/Chat/ChatOutputTokenUsageDetails.cs index cf2be788..27bac369 100644 --- a/src/Custom/Chat/ChatOutputTokenUsageDetails.cs +++ b/src/Custom/Chat/ChatOutputTokenUsageDetails.cs @@ -14,4 +14,10 @@ public partial class ChatOutputTokenUsageDetails /// The number of audio tokens in the output. [CodeGenMember("AudioTokens")] public int AudioTokenCount { get; } + + [CodeGenMember("AcceptedPredictionTokens")] + public int AcceptedPredictionTokenCount { get; } + + [CodeGenMember("RejectedPredictionTokens")] + public int RejectedPredictionTokenCount { get; } } \ No newline at end of file diff --git a/src/Custom/Chat/ChatReasoningEffortLevel.cs b/src/Custom/Chat/ChatReasoningEffortLevel.cs new file mode 100644 index 00000000..8f11b7d7 --- /dev/null +++ b/src/Custom/Chat/ChatReasoningEffortLevel.cs @@ -0,0 +1,9 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; + +namespace OpenAI.Chat; + +[CodeGenModel("CreateChatCompletionRequestReasoningEffort")] +public readonly partial struct ChatReasoningEffortLevel +{} \ No newline at end of file diff --git a/src/Custom/Chat/ChatResponseModalities.Serialization.cs b/src/Custom/Chat/ChatResponseModalities.Serialization.cs new file mode 100644 index 00000000..252d9b7a --- /dev/null +++ b/src/Custom/Chat/ChatResponseModalities.Serialization.cs @@ -0,0 +1,37 @@ +using System.Collections.Generic; + +namespace OpenAI.Chat; + +internal static partial class ChatResponseModalitiesExtensions +{ + internal static IList ToInternalModalities(this ChatResponseModalities modalities) + { + ChangeTrackingList internalModalities = new(); + if (modalities.HasFlag(ChatResponseModalities.Text)) + { + internalModalities.Add(InternalCreateChatCompletionRequestModality.Text); + } + if (modalities.HasFlag(ChatResponseModalities.Audio)) + { + internalModalities.Add(InternalCreateChatCompletionRequestModality.Audio); + } + return internalModalities; + } + + internal static ChatResponseModalities FromInternalModalities(IEnumerable internalModalities) + { + ChatResponseModalities result = 0; + foreach (InternalCreateChatCompletionRequestModality internalModality in internalModalities ?? []) + { + if (internalModality == InternalCreateChatCompletionRequestModality.Text) + { + result |= ChatResponseModalities.Text; + } + else if (internalModality == InternalCreateChatCompletionRequestModality.Audio) + { + result |= ChatResponseModalities.Audio; + } + } + return result; + } +} \ No newline at end of file diff --git a/src/Custom/Chat/ChatResponseModalities.cs b/src/Custom/Chat/ChatResponseModalities.cs new file mode 100644 index 00000000..d6bb276d --- /dev/null +++ b/src/Custom/Chat/ChatResponseModalities.cs @@ -0,0 +1,30 @@ +using System; + +namespace OpenAI.Chat; + +/// +/// Specifies the types of output content the model should generate for a chat completion request. +/// +/// +/// Most models can generate text, which is the default . Some models like +/// gpt-4o-audio-preview can also generate audio, which can be requested by combining +/// +/// | . +/// +/// +[Flags] +public enum ChatResponseModalities : int +{ + /// + /// The value which specifies that the model should produce its default set of output content modalities. + /// + Default = 0, + /// + /// The flag that, if included, specifies that the model should generate text content in its response. + /// + Text = 1 << 0, + /// + /// The flag that, if included, specifies that the model should generate audio content in its response. + /// + Audio = 1 << 1, +} \ No newline at end of file diff --git a/src/Custom/Chat/Internal/GeneratorStubs.cs b/src/Custom/Chat/Internal/GeneratorStubs.cs index 660bc6d7..3547f3a9 100644 --- a/src/Custom/Chat/Internal/GeneratorStubs.cs +++ b/src/Custom/Chat/Internal/GeneratorStubs.cs @@ -36,7 +36,7 @@ internal readonly partial struct InternalChatCompletionResponseMessageRole { } [CodeGenModel("ChatCompletionStreamOptions")] internal partial class InternalChatCompletionStreamOptions { } -[CodeGenModel("ChatCompletionStreamResponseDeltaRole")] +[CodeGenModel("ChatCompletionStreamResponseDeltaRole2")] internal readonly partial struct InternalChatCompletionStreamResponseDeltaRole { } [CodeGenModel("CreateChatCompletionFunctionResponse")] @@ -93,5 +93,17 @@ internal readonly partial struct InternalCreateChatCompletionStreamResponseServi [CodeGenModel("CreateChatCompletionStreamResponseUsage")] internal partial class InternalCreateChatCompletionStreamResponseUsage { } -[CodeGenModel("FunctionParameters")] -internal partial class InternalFunctionParameters { } \ No newline at end of file +[CodeGenModel("CreateChatCompletionRequestModality")] +internal readonly partial struct InternalCreateChatCompletionRequestModality { } + +[CodeGenModel("ChatCompletionRequestMessageContentPartAudioType")] +internal readonly partial struct InternalChatCompletionRequestMessageContentPartAudioType { } + +[CodeGenModel("ChatCompletionRequestMessageContentPartAudio")] +internal partial class InternalChatCompletionRequestMessageContentPartAudio { } + +[CodeGenModel("ChatCompletionRequestMessageContentPartAudioInputAudio")] +internal partial class InternalChatCompletionRequestMessageContentPartAudioInputAudio { } + +[CodeGenModel("UnknownChatOutputPrediction")] +internal partial class InternalUnknownChatOutputPrediction { } \ No newline at end of file diff --git a/src/Custom/Chat/Internal/InternalChatCompletionResponseMessage.Serialization.cs b/src/Custom/Chat/Internal/InternalChatCompletionResponseMessage.Serialization.cs index 28c03901..9ed3a9c7 100644 --- a/src/Custom/Chat/Internal/InternalChatCompletionResponseMessage.Serialization.cs +++ b/src/Custom/Chat/Internal/InternalChatCompletionResponseMessage.Serialization.cs @@ -4,30 +4,16 @@ namespace OpenAI.Chat; -internal partial class InternalChatCompletionResponseMessage : IJsonModel +[CodeGenSerialization(nameof(Content), SerializationValueHook = nameof(SerializeContentValue), DeserializationValueHook = nameof(DeserializeContentValue))] +internal partial class InternalChatCompletionResponseMessage { [MethodImpl(MethodImplOptions.AggressiveInlining)] private void SerializeContentValue(Utf8JsonWriter writer, ModelReaderWriterOptions options) - { - if (Content.Count > 0) - { - writer.WriteStringValue(Content[0].Text); - } - else - { - writer.WriteNullValue(); - } - } + => Content.WriteTo(writer, options); [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void DeserializeContentValue(JsonProperty property, ref ChatMessageContent content, ModelReaderWriterOptions options = null) { - if (property.Value.ValueKind == JsonValueKind.Null) - { - // This is a collection property. We must return an empty collection instead of a null value. - content = new ChatMessageContent(); - return; - } - content = new ChatMessageContent(property.Value.GetString()); + content = ChatMessageContent.DeserializeChatMessageContent(property.Value, options); } } diff --git a/src/Custom/Chat/Internal/InternalChatCompletionResponseMessage.cs b/src/Custom/Chat/Internal/InternalChatCompletionResponseMessage.cs index c8aadb21..607a63c7 100644 --- a/src/Custom/Chat/Internal/InternalChatCompletionResponseMessage.cs +++ b/src/Custom/Chat/Internal/InternalChatCompletionResponseMessage.cs @@ -5,7 +5,6 @@ namespace OpenAI.Chat; [CodeGenModel("ChatCompletionResponseMessage")] [CodeGenSuppress("InternalChatCompletionResponseMessage", typeof(IEnumerable))] -[CodeGenSerialization(nameof(Content), SerializationValueHook = nameof(SerializeContentValue), DeserializationValueHook = nameof(DeserializeContentValue))] internal partial class InternalChatCompletionResponseMessage { // CUSTOM: Changed type from InternalChatCompletionResponseMessageRole. diff --git a/src/Custom/Chat/Internal/InternalChatCompletionStreamResponseDelta.Serialization.cs b/src/Custom/Chat/Internal/InternalChatCompletionStreamResponseDelta.Serialization.cs index 186ff112..4e0758f3 100644 --- a/src/Custom/Chat/Internal/InternalChatCompletionStreamResponseDelta.Serialization.cs +++ b/src/Custom/Chat/Internal/InternalChatCompletionStreamResponseDelta.Serialization.cs @@ -4,30 +4,16 @@ namespace OpenAI.Chat; -internal partial class InternalChatCompletionStreamResponseDelta : IJsonModel +[CodeGenSerialization(nameof(Content), SerializationValueHook = nameof(SerializeContentValue), DeserializationValueHook = nameof(DeserializeContentValue))] +internal partial class InternalChatCompletionStreamResponseDelta { [MethodImpl(MethodImplOptions.AggressiveInlining)] private void SerializeContentValue(Utf8JsonWriter writer, ModelReaderWriterOptions options) - { - if (Content.Count > 0) - { - writer.WriteStringValue(Content[0].Text); - } - else - { - writer.WriteNullValue(); - } - } + => Content.WriteTo(writer, options); [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void DeserializeContentValue(JsonProperty property, ref ChatMessageContent content, ModelReaderWriterOptions options = null) { - if (property.Value.ValueKind == JsonValueKind.Null) - { - // This is a collection property. We must return an empty collection instead of a null value. - content = new ChatMessageContent(); - return; - } - content = new ChatMessageContent(property.Value.ToString()); + content = ChatMessageContent.DeserializeChatMessageContent(property.Value, options); } } diff --git a/src/Custom/Chat/Internal/InternalChatCompletionStreamResponseDelta.cs b/src/Custom/Chat/Internal/InternalChatCompletionStreamResponseDelta.cs index 80c11199..1b7c58d6 100644 --- a/src/Custom/Chat/Internal/InternalChatCompletionStreamResponseDelta.cs +++ b/src/Custom/Chat/Internal/InternalChatCompletionStreamResponseDelta.cs @@ -4,7 +4,6 @@ namespace OpenAI.Chat; [CodeGenModel("ChatCompletionStreamResponseDelta")] [CodeGenSuppress("InternalChatCompletionStreamResponseDelta")] -[CodeGenSerialization(nameof(Content), SerializationValueHook = nameof(SerializeContentValue), DeserializationValueHook = nameof(DeserializeContentValue))] internal partial class InternalChatCompletionStreamResponseDelta { // CUSTOM: Changed type from string. diff --git a/src/Custom/Chat/Internal/InternalChatOutputPredictionContent.Serialization.cs b/src/Custom/Chat/Internal/InternalChatOutputPredictionContent.Serialization.cs new file mode 100644 index 00000000..a7a0933e --- /dev/null +++ b/src/Custom/Chat/Internal/InternalChatOutputPredictionContent.Serialization.cs @@ -0,0 +1,22 @@ +using System.ClientModel.Primitives; +using System.Data; +using System.Text.Json; +using System; +using System.Collections; +using System.Runtime.CompilerServices; + +namespace OpenAI.Chat; + +[CodeGenSerialization(nameof(Content), SerializationValueHook = nameof(SerializeContentValue), DeserializationValueHook = nameof(DeserializeContentValue))] +internal partial class InternalChatOutputPredictionContent +{ + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void SerializeContentValue(Utf8JsonWriter writer, ModelReaderWriterOptions options = null) + => Content.WriteTo(writer, options); + + private static void DeserializeContentValue(JsonProperty property, ref ChatMessageContent content) + { + content = ChatMessageContent.DeserializeChatMessageContent(property.Value); + } +} \ No newline at end of file diff --git a/src/Custom/Chat/Internal/InternalChatOutputPredictionContent.cs b/src/Custom/Chat/Internal/InternalChatOutputPredictionContent.cs new file mode 100644 index 00000000..a3d643a9 --- /dev/null +++ b/src/Custom/Chat/Internal/InternalChatOutputPredictionContent.cs @@ -0,0 +1,15 @@ +using System.ClientModel.Primitives; +using System.Data; +using System.Text.Json; +using System; +using System.Collections; + +namespace OpenAI.Chat; + +[CodeGenModel("ChatOutputPredictionContent")] +internal partial class InternalChatOutputPredictionContent +{ + // CUSTOM: Assign type to a collection of content parts + [CodeGenMember("Content")] + public ChatMessageContent Content { get; set; } = new(); +} \ No newline at end of file diff --git a/src/Custom/Chat/Internal/InternalChatOutputPredictionKind.cs b/src/Custom/Chat/Internal/InternalChatOutputPredictionKind.cs new file mode 100644 index 00000000..c0ee32bb --- /dev/null +++ b/src/Custom/Chat/Internal/InternalChatOutputPredictionKind.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; + +namespace OpenAI.Chat; + +[CodeGenModel("ChatOutputPredictionType")] +internal readonly partial struct InternalChatOutputPredictionKind +{ + // CUSTOM: Rename for clarity. + [CodeGenMember("Content")] + public static InternalChatOutputPredictionKind StaticContent { get; } = new InternalChatOutputPredictionKind(ContentValue); +} \ No newline at end of file diff --git a/src/Custom/Chat/AssistantChatMessage.Serialization.cs b/src/Custom/Chat/Messages/AssistantChatMessage.Serialization.cs similarity index 59% rename from src/Custom/Chat/AssistantChatMessage.Serialization.cs rename to src/Custom/Chat/Messages/AssistantChatMessage.Serialization.cs index d5fac577..a38e1403 100644 --- a/src/Custom/Chat/AssistantChatMessage.Serialization.cs +++ b/src/Custom/Chat/Messages/AssistantChatMessage.Serialization.cs @@ -15,35 +15,13 @@ internal static void SerializeAssistantChatMessage(AssistantChatMessage instance internal override void WriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) { writer.WriteStartObject(); - writer.WritePropertyName("role"u8); - writer.WriteStringValue(Role.ToSerialString()); - - // Content is optional, can be a single string or a collection of ChatMessageContentPart. - if (Optional.IsDefined(Content) && Content.IsInnerCollectionDefined()) - { - if (Content.Count > 0) - { - writer.WritePropertyName("content"u8); - if (Content.Count == 1 && Content[0].Text != null) - { - writer.WriteStringValue(Content[0].Text); - } - else - { - writer.WriteStartArray(); - foreach (ChatMessageContentPart part in Content) - { - writer.WriteObjectValue(part, options); - } - writer.WriteEndArray(); - } - } - } - + WriteRoleProperty(writer, options); + WriteContentProperty(writer, options); writer.WriteOptionalProperty("refusal"u8, Refusal, options); writer.WriteOptionalProperty("name"u8, ParticipantName, options); writer.WriteOptionalCollection("tool_calls"u8, ToolCalls, options); writer.WriteOptionalProperty("function_call"u8, FunctionCall, options); + writer.WriteOptionalProperty("audio"u8, OutputAudioReference, options); writer.WriteSerializedAdditionalRawData(_additionalBinaryDataProperties, options); writer.WriteEndObject(); } diff --git a/src/Custom/Chat/AssistantChatMessage.cs b/src/Custom/Chat/Messages/AssistantChatMessage.cs similarity index 87% rename from src/Custom/Chat/AssistantChatMessage.cs rename to src/Custom/Chat/Messages/AssistantChatMessage.cs index db2b80de..99d83eec 100644 --- a/src/Custom/Chat/AssistantChatMessage.cs +++ b/src/Custom/Chat/Messages/AssistantChatMessage.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; namespace OpenAI.Chat; @@ -83,6 +84,18 @@ public AssistantChatMessage(ChatFunctionCall functionCall) FunctionCall = functionCall; } + /// + /// Creates a new instance of that represents a prior response from the model + /// that included audio with a correlation ID. + /// + /// The audio reference with an id, produced by the model. + public AssistantChatMessage(ChatOutputAudioReference outputAudioReference) + { + Argument.AssertNotNull(outputAudioReference, nameof(outputAudioReference)); + + OutputAudioReference = outputAudioReference; + } + /// /// Creates a new instance of from a with /// an assistant role response. @@ -109,6 +122,10 @@ public AssistantChatMessage(ChatCompletion chatCompletion) Refusal = chatCompletion.Refusal; FunctionCall = chatCompletion.FunctionCall; + if (chatCompletion.OutputAudio is not null) + { + OutputAudioReference = new(chatCompletion.OutputAudio.Id); + } foreach (ChatToolCall toolCall in chatCompletion.ToolCalls ?? []) { ToolCalls.Add(toolCall); @@ -129,4 +146,8 @@ public AssistantChatMessage(ChatCompletion chatCompletion) [Obsolete($"This property is obsolete. Please use {nameof(ToolCalls)} instead.")] public ChatFunctionCall FunctionCall { get; set; } + + // CUSTOM: Renamed. + [CodeGenMember("Audio")] + public ChatOutputAudioReference OutputAudioReference { get; set; } } \ No newline at end of file diff --git a/src/Custom/Chat/ChatMessage.Serialization.cs b/src/Custom/Chat/Messages/ChatMessage.Serialization.cs similarity index 61% rename from src/Custom/Chat/ChatMessage.Serialization.cs rename to src/Custom/Chat/Messages/ChatMessage.Serialization.cs index 7124d94a..384a67d1 100644 --- a/src/Custom/Chat/ChatMessage.Serialization.cs +++ b/src/Custom/Chat/Messages/ChatMessage.Serialization.cs @@ -7,7 +7,8 @@ namespace OpenAI.Chat; [CodeGenSuppress("global::System.ClientModel.Primitives.IJsonModel.Write", typeof(Utf8JsonWriter), typeof(ModelReaderWriterOptions))] -public partial class ChatMessage : IJsonModel +[CodeGenSerialization(nameof(Content), SerializationValueHook = nameof(SerializeContentValue), DeserializationValueHook = nameof(DeserializeContentValue))] +public partial class ChatMessage { [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void SerializeContentValue(Utf8JsonWriter writer, ModelReaderWriterOptions options = null) @@ -18,25 +19,7 @@ internal void SerializeContentValue(Utf8JsonWriter writer, ModelReaderWriterOpti [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void DeserializeContentValue(JsonProperty property, ref ChatMessageContent content, ModelReaderWriterOptions options = null) { - if (property.Value.ValueKind == JsonValueKind.Null) - { - return; - } - else if (property.Value.ValueKind == JsonValueKind.String) - { - content = new ChatMessageContent(property.Value.GetString()); - } - else if (property.Value.ValueKind == JsonValueKind.Array) - { - IList parts = []; - - foreach (var item in property.Value.EnumerateArray()) - { - parts.Add(ChatMessageContentPart.DeserializeChatMessageContentPart(item, options)); - } - - content = new ChatMessageContent(parts); - } + content = ChatMessageContent.DeserializeChatMessageContent(property.Value, options); } void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) @@ -47,4 +30,21 @@ internal static void WriteCore(ChatMessage instance, Utf8JsonWriter writer, Mode internal virtual void WriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) => throw new InvalidOperationException($"The {nameof(WriteCore)} method should be invoked on an overriding type derived from {nameof(ChatMessage)}."); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal void WriteRoleProperty(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WritePropertyName("role"u8); + writer.WriteStringValue(Role.ToSerialString()); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal void WriteContentProperty(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + if (Optional.IsDefined(Content) && Content.IsInnerCollectionDefined()) + { + writer.WritePropertyName("content"u8); + Content.WriteTo(writer, options); + } + } } diff --git a/src/Custom/Chat/ChatMessage.cs b/src/Custom/Chat/Messages/ChatMessage.cs similarity index 88% rename from src/Custom/Chat/ChatMessage.cs rename to src/Custom/Chat/Messages/ChatMessage.cs index 78dcab46..08221dd2 100644 --- a/src/Custom/Chat/ChatMessage.cs +++ b/src/Custom/Chat/Messages/ChatMessage.cs @@ -53,9 +53,13 @@ namespace OpenAI.Chat; /// /// [CodeGenModel("ChatCompletionRequestMessage")] -[CodeGenSerialization(nameof(Content), SerializationValueHook = nameof(SerializeContentValue), DeserializationValueHook = nameof(DeserializeContentValue))] public partial class ChatMessage { + /// + /// The content associated with the message. The interpretation of this content will vary depending on the message type. + /// + public ChatMessageContent Content { get; } = new ChatMessageContent(); + // CUSTOM: Changed type from string to ChatMessageRole. [CodeGenMember("Role")] internal ChatMessageRole Role { get; set; } @@ -89,11 +93,6 @@ internal ChatMessage(ChatMessageRole role, string content = null) : this(role) } } - /// - /// The content associated with the message. The interpretation of this content will vary depending on the message type. - /// - public ChatMessageContent Content { get; } = new ChatMessageContent(); - #region SystemChatMessage /// public static SystemChatMessage CreateSystemMessage(string content) => new(content); @@ -105,6 +104,17 @@ internal ChatMessage(ChatMessageRole role, string content = null) : this(role) public static SystemChatMessage CreateSystemMessage(params ChatMessageContentPart[] contentParts) => new(contentParts); #endregion + #region DeveloperChatMessage + /// + public static DeveloperChatMessage CreateDeveloperMessage(string content) => new(content); + + /// + public static DeveloperChatMessage CreateDeveloperMessage(IEnumerable contentParts) => new(contentParts); + + /// + public static DeveloperChatMessage CreateDeveloperMessage(params ChatMessageContentPart[] contentParts) => new(contentParts); + #endregion + #region UserChatMessage /// public static UserChatMessage CreateUserMessage(string content) => new(content); @@ -134,6 +144,10 @@ internal ChatMessage(ChatMessageRole role, string content = null) : this(role) /// public static AssistantChatMessage CreateAssistantMessage(ChatCompletion chatCompletion) => new(chatCompletion); + + /// + public static AssistantChatMessage CreateAssistantMessage(ChatOutputAudioReference outputAudioReference) => new(outputAudioReference); + #endregion #region ToolChatMessage diff --git a/src/Custom/Chat/Messages/DeveloperChatMessage.Serialization.cs b/src/Custom/Chat/Messages/DeveloperChatMessage.Serialization.cs new file mode 100644 index 00000000..56b11107 --- /dev/null +++ b/src/Custom/Chat/Messages/DeveloperChatMessage.Serialization.cs @@ -0,0 +1,25 @@ +using System; +using System.ClientModel.Primitives; +using System.Text.Json; + +namespace OpenAI.Chat; + +[CodeGenSuppress("global::System.ClientModel.Primitives.IJsonModel.Write", typeof(Utf8JsonWriter), typeof(ModelReaderWriterOptions))] +public partial class DeveloperChatMessage : IJsonModel +{ + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + => CustomSerializationHelpers.SerializeInstance(this, SerializeDeveloperChatMessage, writer, options); + + internal static void SerializeDeveloperChatMessage(DeveloperChatMessage instance, Utf8JsonWriter writer, ModelReaderWriterOptions options) + => instance.WriteCore(writer, options); + + internal override void WriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + WriteRoleProperty(writer, options); + WriteContentProperty(writer, options); + writer.WriteOptionalProperty("name"u8, ParticipantName, options); + writer.WriteSerializedAdditionalRawData(_additionalBinaryDataProperties, options); + writer.WriteEndObject(); + } +} \ No newline at end of file diff --git a/src/Custom/Chat/Messages/DeveloperChatMessage.cs b/src/Custom/Chat/Messages/DeveloperChatMessage.cs new file mode 100644 index 00000000..e21ae9c0 --- /dev/null +++ b/src/Custom/Chat/Messages/DeveloperChatMessage.cs @@ -0,0 +1,59 @@ +using System.Collections.Generic; + +namespace OpenAI.Chat; + +/// +/// Represents a chat message of the developer role as supplied to a chat completion request. A developer message is +/// generally supplied as the first message to a chat completion request and guides the model's behavior across future +/// assistant role response messages. These messages may help control behavior, style, tone, and +/// restrictions for a model-based assistant. Developer messages replace system messages for o1 models and newer. +/// +[CodeGenModel("ChatCompletionRequestDeveloperMessage")] +[CodeGenSuppress("DeveloperChatMessage", typeof(ChatMessageContent))] +public partial class DeveloperChatMessage : ChatMessage +{ + /// + /// Creates a new instance of using a collection of content items. + /// For developer messages, these can only be of type text. + /// + /// + /// The collection of content items associated with the message. + /// + public DeveloperChatMessage(IEnumerable contentParts) + : base(ChatMessageRole.Developer, contentParts) + { } + + /// + /// Creates a new instance of using a collection of content items. + /// For developer messages, these can only be of type text. + /// + /// + /// The collection of content items associated with the message. + /// + public DeveloperChatMessage(params ChatMessageContentPart[] contentParts) + : base(ChatMessageRole.Developer, contentParts) + { + Argument.AssertNotNullOrEmpty(contentParts, nameof(contentParts)); + } + + /// + /// Creates a new instance of with a single item of text content. + /// + /// The text content of the message. + public DeveloperChatMessage(string content) + : base(ChatMessageRole.Developer, content) + { + Argument.AssertNotNull(content, nameof(content)); + } + + // CUSTOM: Hide the default constructor. + internal DeveloperChatMessage() + { + } + + /// + /// An optional name for the participant. + /// + [CodeGenMember("Name")] + public string ParticipantName { get; set; } +} \ No newline at end of file diff --git a/src/Custom/Chat/FunctionChatMessage.Serialization.cs b/src/Custom/Chat/Messages/FunctionChatMessage.Serialization.cs similarity index 66% rename from src/Custom/Chat/FunctionChatMessage.Serialization.cs rename to src/Custom/Chat/Messages/FunctionChatMessage.Serialization.cs index d3618bb1..68fea522 100644 --- a/src/Custom/Chat/FunctionChatMessage.Serialization.cs +++ b/src/Custom/Chat/Messages/FunctionChatMessage.Serialization.cs @@ -17,25 +17,10 @@ internal static void SerializeFunctionChatMessage(FunctionChatMessage instance, internal override void WriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) { writer.WriteStartObject(); - writer.WritePropertyName("role"u8); - writer.WriteStringValue(Role.ToSerialString()); + WriteRoleProperty(writer, options); + WriteContentProperty(writer, options); writer.WritePropertyName("name"u8); writer.WriteStringValue(FunctionName); - - // Content is required, can be a single string or null. - if (Optional.IsDefined(Content) && Content.IsInnerCollectionDefined()) - { - writer.WritePropertyName("content"u8); - if (Content.Count > 0 && Content[0].Text != null) - { - writer.WriteStringValue(Content[0].Text); - } - else - { - writer.WriteNullValue(); - } - } - writer.WriteSerializedAdditionalRawData(_additionalBinaryDataProperties, options); writer.WriteEndObject(); } diff --git a/src/Custom/Chat/FunctionChatMessage.cs b/src/Custom/Chat/Messages/FunctionChatMessage.cs similarity index 85% rename from src/Custom/Chat/FunctionChatMessage.cs rename to src/Custom/Chat/Messages/FunctionChatMessage.cs index f91e7730..54d98fdc 100644 --- a/src/Custom/Chat/FunctionChatMessage.cs +++ b/src/Custom/Chat/Messages/FunctionChatMessage.cs @@ -30,6 +30,13 @@ public FunctionChatMessage(string functionName, string content) Argument.AssertNotNull(functionName, nameof(functionName)); FunctionName = functionName; + + // FunctionChatMessage treats content as *required* but explicitly *nullable*. If null content was provided, + // enforce manifestation of the (nullable) content collection via .Clear(). + if (!Content.IsInnerCollectionDefined()) + { + Content.Clear(); + } } // CUSTOM: Renamed. diff --git a/src/Custom/Chat/SystemChatMessage.Serialization.cs b/src/Custom/Chat/Messages/SystemChatMessage.Serialization.cs similarity index 57% rename from src/Custom/Chat/SystemChatMessage.Serialization.cs rename to src/Custom/Chat/Messages/SystemChatMessage.Serialization.cs index 4907c78b..debd1f9b 100644 --- a/src/Custom/Chat/SystemChatMessage.Serialization.cs +++ b/src/Custom/Chat/Messages/SystemChatMessage.Serialization.cs @@ -16,28 +16,8 @@ internal static void SerializeSystemChatMessage(SystemChatMessage instance, Utf8 internal override void WriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) { writer.WriteStartObject(); - writer.WritePropertyName("role"u8); - writer.WriteStringValue(Role.ToSerialString()); - - // Content is required, can be a single string or a collection of ChatMessageContentPart. - if (Optional.IsDefined(Content) && Content.IsInnerCollectionDefined()) - { - writer.WritePropertyName("content"u8); - if (Content.Count == 1 && Content[0].Text != null) - { - writer.WriteStringValue(Content[0].Text); - } - else - { - writer.WriteStartArray(); - foreach (ChatMessageContentPart part in Content) - { - writer.WriteObjectValue(part, options); - } - writer.WriteEndArray(); - } - } - + WriteRoleProperty(writer, options); + WriteContentProperty(writer, options); writer.WriteOptionalProperty("name"u8, ParticipantName, options); writer.WriteSerializedAdditionalRawData(_additionalBinaryDataProperties, options); writer.WriteEndObject(); diff --git a/src/Custom/Chat/SystemChatMessage.cs b/src/Custom/Chat/Messages/SystemChatMessage.cs similarity index 95% rename from src/Custom/Chat/SystemChatMessage.cs rename to src/Custom/Chat/Messages/SystemChatMessage.cs index 8e4cad09..946295bd 100644 --- a/src/Custom/Chat/SystemChatMessage.cs +++ b/src/Custom/Chat/Messages/SystemChatMessage.cs @@ -6,7 +6,7 @@ namespace OpenAI.Chat; /// Represents a chat message of the system role as supplied to a chat completion request. A system message is /// generally supplied as the first message to a chat completion request and guides the model's behavior across future /// assistant role response messages. These messages may help control behavior, style, tone, and -/// restrictions for a model-based assistant. +/// restrictions for a model-based assistant. Developer messages replace system messages for o1 models and newer. /// [CodeGenModel("ChatCompletionRequestSystemMessage")] [CodeGenSuppress("SystemChatMessage", typeof(ChatMessageContent))] diff --git a/src/Custom/Chat/ToolChatMessage.Serialization.cs b/src/Custom/Chat/Messages/ToolChatMessage.Serialization.cs similarity index 57% rename from src/Custom/Chat/ToolChatMessage.Serialization.cs rename to src/Custom/Chat/Messages/ToolChatMessage.Serialization.cs index b3cc7e41..fb5e88a9 100644 --- a/src/Custom/Chat/ToolChatMessage.Serialization.cs +++ b/src/Custom/Chat/Messages/ToolChatMessage.Serialization.cs @@ -15,30 +15,10 @@ internal static void SerializeToolChatMessage(ToolChatMessage instance, Utf8Json internal override void WriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) { writer.WriteStartObject(); - writer.WritePropertyName("role"u8); - writer.WriteStringValue(Role.ToSerialString()); + WriteRoleProperty(writer, options); writer.WritePropertyName("tool_call_id"u8); writer.WriteStringValue(ToolCallId); - - // Content is required, can be a single string or a collection of ChatMessageContentPart. - if (Optional.IsDefined(Content) && Content.IsInnerCollectionDefined()) - { - writer.WritePropertyName("content"u8); - if (Content.Count == 1 && Content[0].Text != null) - { - writer.WriteStringValue(Content[0].Text); - } - else - { - writer.WriteStartArray(); - foreach (ChatMessageContentPart part in Content) - { - writer.WriteObjectValue(part, options); - } - writer.WriteEndArray(); - } - } - + WriteContentProperty(writer, options); writer.WriteSerializedAdditionalRawData(_additionalBinaryDataProperties, options); writer.WriteEndObject(); } diff --git a/src/Custom/Chat/ToolChatMessage.cs b/src/Custom/Chat/Messages/ToolChatMessage.cs similarity index 100% rename from src/Custom/Chat/ToolChatMessage.cs rename to src/Custom/Chat/Messages/ToolChatMessage.cs diff --git a/src/Custom/Chat/UserChatMessage.Serialization.cs b/src/Custom/Chat/Messages/UserChatMessage.Serialization.cs similarity index 57% rename from src/Custom/Chat/UserChatMessage.Serialization.cs rename to src/Custom/Chat/Messages/UserChatMessage.Serialization.cs index 615d62fe..5b09cabf 100644 --- a/src/Custom/Chat/UserChatMessage.Serialization.cs +++ b/src/Custom/Chat/Messages/UserChatMessage.Serialization.cs @@ -15,28 +15,8 @@ internal static void SerializeUserChatMessage(UserChatMessage instance, Utf8Json internal override void WriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) { writer.WriteStartObject(); - writer.WritePropertyName("role"u8); - writer.WriteStringValue(Role.ToSerialString()); - - // Content is required, can be a single string or a collection of ChatMessageContentPart. - if (Optional.IsDefined(Content) && Content.IsInnerCollectionDefined()) - { - writer.WritePropertyName("content"u8); - if (Content.Count == 1 && Content[0].Text != null) - { - writer.WriteStringValue(Content[0].Text); - } - else - { - writer.WriteStartArray(); - foreach (ChatMessageContentPart part in Content) - { - writer.WriteObjectValue(part, options); - } - writer.WriteEndArray(); - } - } - + WriteRoleProperty(writer, options); + WriteContentProperty(writer, options); writer.WriteOptionalProperty("name"u8, ParticipantName, options); writer.WriteSerializedAdditionalRawData(_additionalBinaryDataProperties, options); writer.WriteEndObject(); diff --git a/src/Custom/Chat/UserChatMessage.cs b/src/Custom/Chat/Messages/UserChatMessage.cs similarity index 100% rename from src/Custom/Chat/UserChatMessage.cs rename to src/Custom/Chat/Messages/UserChatMessage.cs diff --git a/src/Custom/Chat/OpenAIChatModelFactory.cs b/src/Custom/Chat/OpenAIChatModelFactory.cs index f4503f98..4a08548a 100644 --- a/src/Custom/Chat/OpenAIChatModelFactory.cs +++ b/src/Custom/Chat/OpenAIChatModelFactory.cs @@ -22,7 +22,8 @@ public static ChatCompletion ChatCompletion( DateTimeOffset createdAt = default, string model = null, string systemFingerprint = null, - ChatTokenUsage usage = null) + ChatTokenUsage usage = null, + ChatOutputAudio outputAudio = null) { content ??= new ChatMessageContent(); toolCalls ??= new List(); @@ -32,6 +33,7 @@ public static ChatCompletion ChatCompletion( InternalChatCompletionResponseMessage message = new InternalChatCompletionResponseMessage( refusal, toolCalls.ToList(), + outputAudio, role, content, functionCall, @@ -63,6 +65,7 @@ public static ChatCompletion ChatCompletion( additionalBinaryDataProperties: null); } + /// Initializes a new instance of . /// A new instance for mocking. public static ChatTokenLogProbabilityDetails ChatTokenLogProbabilityDetails(string token = null, float logProbability = default, ReadOnlyMemory? utf8Bytes = null, IEnumerable topLogProbabilities = null) @@ -113,9 +116,24 @@ public static ChatInputTokenUsageDetails ChatInputTokenUsageDetails(int audioTok /// Initializes a new instance of . /// A new instance for mocking. - public static ChatOutputTokenUsageDetails ChatOutputTokenUsageDetails(int reasoningTokenCount = default, int audioTokenCount = default) + public static ChatOutputTokenUsageDetails ChatOutputTokenUsageDetails(int reasoningTokenCount = default, int audioTokenCount = default, int acceptedPredictionTokenCount = default, int rejectedPredictionTokenCount = 0) { - return new ChatOutputTokenUsageDetails(reasoningTokenCount, audioTokenCount, additionalBinaryDataProperties: null); + return new ChatOutputTokenUsageDetails( + audioTokenCount: audioTokenCount, + reasoningTokenCount: reasoningTokenCount, + acceptedPredictionTokenCount: acceptedPredictionTokenCount, + rejectedPredictionTokenCount: rejectedPredictionTokenCount, + additionalBinaryDataProperties: null); + } + + public static ChatOutputAudio ChatOutputAudio(BinaryData audioBytes, string id = null, string transcript = null, DateTimeOffset expiresAt = default) + { + return new ChatOutputAudio( + id, + expiresAt, + transcript, + audioBytes, + additionalBinaryDataProperties: null); } /// Initializes a new instance of . @@ -133,7 +151,8 @@ public static StreamingChatCompletionUpdate StreamingChatCompletionUpdate( DateTimeOffset createdAt = default, string model = null, string systemFingerprint = null, - ChatTokenUsage usage = null) + ChatTokenUsage usage = null, + StreamingChatOutputAudioUpdate outputAudioUpdate = null) { contentUpdate ??= new ChatMessageContent(); toolCallUpdates ??= new List(); @@ -141,6 +160,7 @@ public static StreamingChatCompletionUpdate StreamingChatCompletionUpdate( refusalTokenLogProbabilities ??= new List(); InternalChatCompletionStreamResponseDelta delta = new InternalChatCompletionStreamResponseDelta( + outputAudioUpdate, functionCallUpdate, toolCallUpdates.ToList(), refusalUpdate, @@ -185,6 +205,28 @@ public static StreamingChatFunctionCallUpdate StreamingChatFunctionCallUpdate(st additionalBinaryDataProperties: null); } + /// + /// Initializes a new instance of . + /// + /// + /// + /// + /// + /// + public static StreamingChatOutputAudioUpdate StreamingChatOutputAudioUpdate( + string id = null, + DateTimeOffset? expiresAt = null, + string transcriptUpdate = null, + BinaryData audioBytesUpdate = null) + { + return new StreamingChatOutputAudioUpdate( + id, + expiresAt, + transcriptUpdate, + audioBytesUpdate, + additionalBinaryDataProperties: null); + } + /// Initializes a new instance of . /// A new instance for mocking. public static StreamingChatToolCallUpdate StreamingChatToolCallUpdate(int index = default, string toolCallId = null, ChatToolCallKind kind = default, string functionName = null, BinaryData functionArgumentsUpdate = null) diff --git a/src/Custom/Chat/Streaming/StreamingChatCompletionUpdate.cs b/src/Custom/Chat/Streaming/StreamingChatCompletionUpdate.cs index 54441795..93d39201 100644 --- a/src/Custom/Chat/Streaming/StreamingChatCompletionUpdate.cs +++ b/src/Custom/Chat/Streaming/StreamingChatCompletionUpdate.cs @@ -93,10 +93,7 @@ public partial class StreamingChatCompletionUpdate /// Each streaming update contains only a small portion of tokens. To reconstitute the entire chat completion, /// all values across streaming updates must be combined. /// - public ChatMessageContent ContentUpdate => - _contentUpdate - ??= InternalChoiceDelta?.Content - ?? new ChatMessageContent(); + public ChatMessageContent ContentUpdate => _contentUpdate ??= InternalChoiceDelta?.Content ?? []; // CUSTOM: Flattened choice delta property. /// The tool calls generated by the model, such as function calls. @@ -112,4 +109,12 @@ public IReadOnlyList ToolCallUpdates // CUSTOM: Flattened choice delta property. [Obsolete($"This property is obsolete. Please use {nameof(ToolCallUpdates)} instead.")] public StreamingChatFunctionCallUpdate FunctionCallUpdate => InternalChoiceDelta?.FunctionCall; + + // CUSTOM: Flattened choice delta property. + /// + /// Incremental output audio generated by the model. Only expected when output audio has been requested via providing + /// to and only available with + /// supported models. + /// + public StreamingChatOutputAudioUpdate OutputAudioUpdate => InternalChoiceDelta?.Audio; } diff --git a/src/Custom/Chat/Streaming/StreamingChatOutputAudioUpdate.cs b/src/Custom/Chat/Streaming/StreamingChatOutputAudioUpdate.cs new file mode 100644 index 00000000..ef1058f9 --- /dev/null +++ b/src/Custom/Chat/Streaming/StreamingChatOutputAudioUpdate.cs @@ -0,0 +1,28 @@ +namespace OpenAI.Chat; + +using System; + +/// +/// Represents an audio update in a streaming chat response. +/// +[CodeGenModel("ChatCompletionMessageAudioChunk")] +public partial class StreamingChatOutputAudioUpdate +{ + // CUSTOM: Renamed for clarity of incremental data availability while streaming. + /// + /// The next, incremental audio transcript part from the streaming response. payloads + /// across all received instances should be concatenated to form the + /// full response audio transcript. + /// + [CodeGenMember("Transcript")] + public string TranscriptUpdate { get; } + + // CUSTOM: Renamed for clarity of incremental data availability while streaming. + /// + /// The next, incremental response audio data chunk from the streaming response. payloads + /// across all received instances should be concatenated to form the + /// full response audio. + /// + [CodeGenMember("Data")] + public BinaryData AudioBytesUpdate { get; } +} diff --git a/src/Custom/Embeddings/EmbeddingClient.cs b/src/Custom/Embeddings/EmbeddingClient.cs index cd07961a..2386d007 100644 --- a/src/Custom/Embeddings/EmbeddingClient.cs +++ b/src/Custom/Embeddings/EmbeddingClient.cs @@ -2,7 +2,9 @@ using System.ClientModel; using System.ClientModel.Primitives; using System.Collections.Generic; +using System.IO; using System.Linq; +using System.Text.Json; using System.Threading; using System.Threading.Tasks; @@ -99,7 +101,7 @@ public virtual async Task> GenerateEmbeddingAsync( Argument.AssertNotNullOrEmpty(input, nameof(input)); options ??= new(); - CreateEmbeddingGenerationOptions(BinaryData.FromObjectAsJson(input, SourceGenerationContext.Default.String), ref options); + CreateEmbeddingGenerationOptions(input, ref options); using BinaryContent content = options; ClientResult result = await GenerateEmbeddingsAsync(content, cancellationToken.ToRequestOptions()).ConfigureAwait(false); @@ -118,7 +120,7 @@ public virtual ClientResult GenerateEmbedding(string input, Emb Argument.AssertNotNullOrEmpty(input, nameof(input)); options ??= new(); - CreateEmbeddingGenerationOptions(BinaryData.FromObjectAsJson(input, SourceGenerationContext.Default.String), ref options); + CreateEmbeddingGenerationOptions(input, ref options); using BinaryContent content = options; ClientResult result = GenerateEmbeddings(content, cancellationToken.ToRequestOptions()); @@ -137,7 +139,7 @@ public virtual async Task> GenerateEmbed Argument.AssertNotNullOrEmpty(inputs, nameof(inputs)); options ??= new(); - CreateEmbeddingGenerationOptions(BinaryData.FromObjectAsJson(inputs, SourceGenerationContext.Default.IEnumerableString), ref options); + CreateEmbeddingGenerationOptions(inputs, ref options); using BinaryContent content = options; ClientResult result = await GenerateEmbeddingsAsync(content, cancellationToken.ToRequestOptions()).ConfigureAwait(false); @@ -157,7 +159,7 @@ public virtual ClientResult GenerateEmbeddings(IEnume Argument.AssertNotNullOrEmpty(inputs, nameof(inputs)); options ??= new(); - CreateEmbeddingGenerationOptions(BinaryData.FromObjectAsJson(inputs, SourceGenerationContext.Default.IEnumerableString), ref options); + CreateEmbeddingGenerationOptions(inputs, ref options); using BinaryContent content = options; ClientResult result = GenerateEmbeddings(content, cancellationToken.ToRequestOptions()); @@ -165,8 +167,8 @@ public virtual ClientResult GenerateEmbeddings(IEnume } // CUSTOM: Added to simplify passing the input as a collection of ReadOnlyMemory tokens instead of BinaryData. - /// Generates embeddings representing the text inputs. - /// The text inputs to generate embeddings for. + /// Generates embeddings representing the tokenized text inputs. + /// The tokenized text inputs to generate embeddings for. /// The options to configure the embedding generation. /// A token that can be used to cancel this method call. /// is null. @@ -176,7 +178,7 @@ public virtual async Task> GenerateEmbed Argument.AssertNotNullOrEmpty(inputs, nameof(inputs)); options ??= new(); - CreateEmbeddingGenerationOptions(BinaryData.FromObjectAsJson(inputs, SourceGenerationContext.Default.IEnumerableReadOnlyMemoryInt32), ref options); + CreateEmbeddingGenerationOptions(inputs, ref options); using BinaryContent content = options; ClientResult result = await GenerateEmbeddingsAsync(content, cancellationToken.ToRequestOptions()).ConfigureAwait(false); @@ -184,8 +186,8 @@ public virtual async Task> GenerateEmbed } // CUSTOM: Added to simplify passing the input as a collection of ReadOnlyMemory of tokens instead of BinaryData. - /// Generates embeddings representing the text inputs. - /// The text inputs to generate embeddings for. + /// Generates embeddings representing the tokenized text inputs. + /// The tokenized text inputs to generate embeddings for. /// The options to configure the embedding generation. /// A token that can be used to cancel this method call. /// is null. @@ -195,16 +197,69 @@ public virtual ClientResult GenerateEmbeddings(IEnume Argument.AssertNotNullOrEmpty(inputs, nameof(inputs)); options ??= new(); - CreateEmbeddingGenerationOptions(BinaryData.FromObjectAsJson(inputs, SourceGenerationContext.Default.IEnumerableReadOnlyMemoryInt32), ref options); + CreateEmbeddingGenerationOptions(inputs, ref options); using BinaryContent content = options; ClientResult result = GenerateEmbeddings(content, cancellationToken.ToRequestOptions()); return ClientResult.FromValue((OpenAIEmbeddingCollection)result, result.GetRawResponse()); } - private void CreateEmbeddingGenerationOptions(BinaryData input, ref EmbeddingGenerationOptions options) + private void CreateEmbeddingGenerationOptions(string input, ref EmbeddingGenerationOptions options) + { + using MemoryStream stream = new(); + using Utf8JsonWriter writer = new(stream); + + writer.WriteStringValue(input); + writer.Flush(); + + options.Input = BinaryData.FromBytes(stream.ToArray()); + options.Model = _model; + options.EncodingFormat = InternalCreateEmbeddingRequestEncodingFormat.Base64; + } + + private void CreateEmbeddingGenerationOptions(IEnumerable inputs, ref EmbeddingGenerationOptions options) + { + using MemoryStream stream = new(); + using Utf8JsonWriter writer = new(stream); + + writer.WriteStartArray(); + + foreach (string input in inputs) + { + writer.WriteStringValue(input); + } + + writer.WriteEndArray(); + writer.Flush(); + + options.Input = BinaryData.FromBytes(stream.ToArray()); + options.Model = _model; + options.EncodingFormat = InternalCreateEmbeddingRequestEncodingFormat.Base64; + } + + private void CreateEmbeddingGenerationOptions(IEnumerable> inputs, ref EmbeddingGenerationOptions options) { - options.Input = input; + using MemoryStream stream = new(); + using Utf8JsonWriter writer = new(stream); + + writer.WriteStartArray(); + + foreach (ReadOnlyMemory input in inputs) + { + writer.WriteStartArray(); + + foreach (int tokenId in input.ToArray()) + { + writer.WriteNumberValue(tokenId); + } + + writer.WriteEndArray(); + } + + writer.WriteEndArray(); + writer.Flush(); + + options.Input = BinaryData.FromBytes(stream.ToArray()); options.Model = _model; options.EncodingFormat = InternalCreateEmbeddingRequestEncodingFormat.Base64; } diff --git a/src/Custom/Embeddings/EmbeddingGenerationOptions.cs b/src/Custom/Embeddings/EmbeddingGenerationOptions.cs index 0c376079..ba546cba 100644 --- a/src/Custom/Embeddings/EmbeddingGenerationOptions.cs +++ b/src/Custom/Embeddings/EmbeddingGenerationOptions.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; namespace OpenAI.Embeddings; @@ -10,75 +9,17 @@ public partial class EmbeddingGenerationOptions // CUSTOM: // - Made internal. This value comes from a parameter on the client method. // - Added setter. - /// - /// Input text to embed, encoded as a string or array of tokens. To embed multiple inputs in a - /// single request, pass an array of strings or array of token arrays. Each input must not exceed - /// the max input tokens for the model (8191 tokens for `text-embedding-ada-002`) and cannot be an - /// empty string. - /// [Example Python code](https://github.com/openai/openai-cookbook/blob/main/examples/How_to_count_tokens_with_tiktoken.ipynb) - /// for counting tokens. - /// - /// To assign an object to this property use . - /// - /// - /// To assign an already formatted json string to this property use . - /// - /// - /// - /// Supported types: - /// - /// - /// - /// - /// - /// where T is of type - /// - /// - /// where T is of type - /// - /// - /// where T is of type IList{long} - /// - /// - /// - /// Examples: - /// - /// - /// BinaryData.FromObjectAsJson("foo") - /// Creates a payload of "foo". - /// - /// - /// BinaryData.FromString("\"foo\"") - /// Creates a payload of "foo". - /// - /// - /// BinaryData.FromObjectAsJson(new { key = "value" }) - /// Creates a payload of { "key": "value" }. - /// - /// - /// BinaryData.FromString("{\"key\": \"value\"}") - /// Creates a payload of { "key": "value" }. - /// - /// - /// - /// + [CodeGenMember("Input")] internal BinaryData Input { get; set; } // CUSTOM: // - Made internal. The model is specified by the client. // - Added setter. - /// - /// ID of the model to use. You can use the [List models](/docs/api-reference/models/list) API to - /// see all of your available models, or see our [Model overview](/docs/models/overview) for - /// descriptions of them. - /// + [CodeGenMember("Model")] internal InternalCreateEmbeddingRequestModel Model { get; set; } // CUSTOM: Made internal. We always request the embedding as a base64-encoded string for better performance. - /// - /// The format to return the embeddings in. Can be either `float` or - /// [`base64`](https://pypi.org/project/pybase64/). - /// + [CodeGenMember("EncodingFormat")] internal InternalCreateEmbeddingRequestEncodingFormat? EncodingFormat { get; set; } // CUSTOM: Made public now that there are no required properties. diff --git a/src/Custom/Files/Internal/GeneratorStubs.cs b/src/Custom/Files/Internal/GeneratorStubs.cs index 7d9c6326..509a21a9 100644 --- a/src/Custom/Files/Internal/GeneratorStubs.cs +++ b/src/Custom/Files/Internal/GeneratorStubs.cs @@ -3,9 +3,6 @@ namespace OpenAI.Files; [CodeGenModel("DeleteFileResponseObject")] internal readonly partial struct InternalDeleteFileResponseObject { } -[CodeGenModel("ListFilesResponseObject")] -internal readonly partial struct InternalListFilesResponseObject { } - [CodeGenModel("OpenAIFileObject")] internal readonly partial struct InternalOpenAIFileObject { } @@ -13,6 +10,7 @@ internal readonly partial struct InternalOpenAIFileObject { } [CodeGenModel("CompleteUploadRequest")] internal partial class InternalCompleteUploadRequest { } [CodeGenModel("CreateUploadRequest")] internal partial class InternalCreateUploadRequest { } [CodeGenModel("CreateUploadRequestPurpose")] internal readonly partial struct InternalCreateUploadRequestPurpose { } +[CodeGenModel("ListFilesResponseObject")] internal readonly partial struct InternalListFilesResponseObject { } [CodeGenModel("Upload")] internal partial class InternalUpload { } [CodeGenModel("UploadObject")] internal readonly partial struct InternalUploadObject { } [CodeGenModel("UploadPart")] internal partial class InternalUploadPart { } diff --git a/src/Custom/Files/OpenAIFileCollection.Serialization.cs b/src/Custom/Files/OpenAIFileCollection.Serialization.cs index 2a498dbe..d56a22ba 100644 --- a/src/Custom/Files/OpenAIFileCollection.Serialization.cs +++ b/src/Custom/Files/OpenAIFileCollection.Serialization.cs @@ -40,7 +40,10 @@ internal static OpenAIFileCollection DeserializeOpenAIFileCollection(JsonElement return null; } IReadOnlyList data = default; - InternalListFilesResponseObject @object = default; + string @object = default; + string firstId = default; + string lastId = default; + bool hasMore = false; IDictionary serializedAdditionalRawData = default; Dictionary rawDataDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) @@ -57,7 +60,22 @@ internal static OpenAIFileCollection DeserializeOpenAIFileCollection(JsonElement } if (property.NameEquals("object"u8)) { - @object = new InternalListFilesResponseObject(property.Value.GetString()); + @object = property.Value.GetString(); + continue; + } + if (property.NameEquals("first_id"u8)) + { + firstId = property.Value.GetString(); + continue; + } + if (property.NameEquals("last_id"u8)) + { + lastId = property.Value.GetString(); + continue; + } + if (property.NameEquals("has_more"u8)) + { + hasMore = property.Value.GetBoolean(); continue; } if (true) @@ -66,7 +84,7 @@ internal static OpenAIFileCollection DeserializeOpenAIFileCollection(JsonElement } } serializedAdditionalRawData = rawDataDictionary; - return new OpenAIFileCollection(data, @object, serializedAdditionalRawData); + return new OpenAIFileCollection(data, @object, firstId, lastId, hasMore, serializedAdditionalRawData); } } diff --git a/src/Custom/Files/OpenAIFileCollection.cs b/src/Custom/Files/OpenAIFileCollection.cs index 3114ff3b..4693bb44 100644 --- a/src/Custom/Files/OpenAIFileCollection.cs +++ b/src/Custom/Files/OpenAIFileCollection.cs @@ -7,31 +7,48 @@ namespace OpenAI.Files; [CodeGenModel("ListFilesResponse")] [CodeGenSuppress("Data")] [CodeGenSuppress(nameof(OpenAIFileCollection))] -[CodeGenSuppress(nameof(OpenAIFileCollection),typeof(InternalListFilesResponseObject), typeof(IDictionary))] +[CodeGenSuppress(nameof(OpenAIFileCollection), typeof(string), typeof(string), typeof(bool))] +[CodeGenSuppress(nameof(OpenAIFileCollection), typeof(InternalListFilesResponseObject), typeof(string), typeof(string), typeof(bool), typeof(IDictionary))] public partial class OpenAIFileCollection : ReadOnlyCollection { // CUSTOM: Made private. This property does not add value in the context of a strongly-typed class. - /// Gets the object. + [CodeGenMember("Object")] private InternalListFilesResponseObject Object { get; } = InternalListFilesResponseObject.List; + // CUSTOM: Internalizing pending stanardized pagination representation for the list operation. + [CodeGenMember("FirstId")] + internal string FirstId { get; } + + [CodeGenMember("LastId")] + internal string LastId { get; } + + [CodeGenMember("HasMore")] + internal bool HasMore { get; } + /// Initializes a new instance of . /// /// is null. - internal OpenAIFileCollection(IEnumerable data) + internal OpenAIFileCollection(IEnumerable data, string firstId, string lastId, bool hasMore) : base([.. data]) { Argument.AssertNotNull(data, nameof(data)); + FirstId = firstId; + LastId = lastId; + HasMore = hasMore; } /// Initializes a new instance of . /// /// /// Keeps track of any properties unknown to the library. - internal OpenAIFileCollection(IReadOnlyList data, InternalListFilesResponseObject @object, IDictionary serializedAdditionalRawData) + internal OpenAIFileCollection(IReadOnlyList data, string @object, string firstId, string lastId, bool hasMore, IDictionary serializedAdditionalRawData) : base([.. data]) { Object = @object; SerializedAdditionalRawData = serializedAdditionalRawData; + FirstId = firstId; + LastId = lastId; + HasMore = hasMore; } /// Initializes a new instance of for deserialization. diff --git a/src/Custom/Files/OpenAIFilesModelFactory.cs b/src/Custom/Files/OpenAIFilesModelFactory.cs index 3dcaafac..78242157 100644 --- a/src/Custom/Files/OpenAIFilesModelFactory.cs +++ b/src/Custom/Files/OpenAIFilesModelFactory.cs @@ -38,11 +38,10 @@ public static OpenAIFile OpenAIFileInfo(string id = null, int? sizeInBytes = nul /// A new instance for mocking. public static OpenAIFileCollection OpenAIFileCollection(IEnumerable items = null) { - items ??= new List(); - return new OpenAIFileCollection( - items.ToList(), - InternalListFilesResponseObject.List, - serializedAdditionalRawData: null); + items?.ToList() ?? [], + firstId: null, + lastId : null, + hasMore: false); } } diff --git a/src/Custom/FineTuning/Internal/GeneratorStubs.cs b/src/Custom/FineTuning/Internal/GeneratorStubs.cs index eb14cf3b..117370cc 100644 --- a/src/Custom/FineTuning/Internal/GeneratorStubs.cs +++ b/src/Custom/FineTuning/Internal/GeneratorStubs.cs @@ -136,3 +136,32 @@ internal partial class HyperparameterOptions { } [CodeGenModel("CreateFineTuningJobRequestWandbIntegration")] internal partial class WeightsAndBiasesIntegration { } + +// TODO: not yet integrated + +[CodeGenModel("FineTuneChatRequestInput")] +internal partial class InternalTodoFineTuneChatRequestInput { } + +[CodeGenModel("FineTuneCompletionRequestInput")] +internal partial class InternalTodoFineTuneCompletionRequestInput { } + +[CodeGenModel("FineTuneDPOMethod")] +internal partial class InternalTodoFineTuneDPOMethod { } + +[CodeGenModel("FineTuneDPOMethodHyperparameters")] +internal partial class InternalTodoFineTuneDPOMethodHyperparameters { } + +[CodeGenModel("FineTuneMethod")] +internal partial class InternalTodoFineTuneMethod { } + +[CodeGenModel("FineTuneMethodType")] +internal readonly partial struct InternalTodoFineTuneMethodType { } + +[CodeGenModel("FineTuneSupervisedMethod")] +internal partial class InternalTodoFineTuneSupervisedMethod { } + +[CodeGenModel("FineTuneSupervisedMethodHyperparameters")] +internal partial class InternalFineTuneSupervisedMethodHyperparameters { } + +[CodeGenModel("FineTuningJobEventType")] +internal readonly partial struct InternalFineTuningJobEventType { } \ No newline at end of file diff --git a/src/Custom/Moderations/ModerationClient.cs b/src/Custom/Moderations/ModerationClient.cs index c28aace7..eb38878d 100644 --- a/src/Custom/Moderations/ModerationClient.cs +++ b/src/Custom/Moderations/ModerationClient.cs @@ -2,7 +2,9 @@ using System.ClientModel; using System.ClientModel.Primitives; using System.Collections.Generic; +using System.IO; using System.Linq; +using System.Text.Json; using System.Threading; using System.Threading.Tasks; @@ -97,7 +99,7 @@ public virtual async Task> ClassifyTextAsync(stri Argument.AssertNotNullOrEmpty(input, nameof(input)); ModerationOptions options = new(); - CreateModerationOptions(BinaryData.FromObjectAsJson(input, SourceGenerationContext.Default.String), ref options); + CreateModerationOptions(input, ref options); using BinaryContent content = options; ClientResult result = await ClassifyTextAsync(content, cancellationToken.ToRequestOptions()).ConfigureAwait(false); @@ -114,7 +116,7 @@ public virtual ClientResult ClassifyText(string input, Cancell Argument.AssertNotNullOrEmpty(input, nameof(input)); ModerationOptions options = new(); - CreateModerationOptions(BinaryData.FromObjectAsJson(input, SourceGenerationContext.Default.String), ref options); + CreateModerationOptions(input, ref options); using BinaryContent content = options; ClientResult result = ClassifyText(content, cancellationToken.ToRequestOptions()); @@ -131,7 +133,7 @@ public virtual async Task> ClassifyText Argument.AssertNotNullOrEmpty(inputs, nameof(inputs)); ModerationOptions options = new(); - CreateModerationOptions(BinaryData.FromObjectAsJson(inputs, SourceGenerationContext.Default.IEnumerableString), ref options); + CreateModerationOptions(inputs, ref options); using BinaryContent content = options; ClientResult result = await ClassifyTextAsync(content, cancellationToken.ToRequestOptions()).ConfigureAwait(false); @@ -148,16 +150,41 @@ public virtual ClientResult ClassifyText(IEnumerable Argument.AssertNotNullOrEmpty(inputs, nameof(inputs)); ModerationOptions options = new(); - CreateModerationOptions(BinaryData.FromObjectAsJson(inputs, SourceGenerationContext.Default.IEnumerableString), ref options); + CreateModerationOptions(inputs, ref options); using BinaryContent content = options; ClientResult result = ClassifyText(content, cancellationToken.ToRequestOptions()); return ClientResult.FromValue((ModerationResultCollection)result, result.GetRawResponse()); } - private void CreateModerationOptions(BinaryData input, ref ModerationOptions options) + private void CreateModerationOptions(string input, ref ModerationOptions options) { - options.Input = input; + using MemoryStream stream = new(); + using Utf8JsonWriter writer = new(stream); + + writer.WriteStringValue(input); + writer.Flush(); + + options.Input = BinaryData.FromBytes(stream.ToArray()); + options.Model = _model; + } + + private void CreateModerationOptions(IEnumerable inputs, ref ModerationOptions options) + { + using MemoryStream stream = new(); + using Utf8JsonWriter writer = new(stream); + + writer.WriteStartArray(); + + foreach (string input in inputs) + { + writer.WriteStringValue(input); + } + + writer.WriteEndArray(); + writer.Flush(); + + options.Input = BinaryData.FromBytes(stream.ToArray()); options.Model = _model; } } diff --git a/src/Custom/Moderations/ModerationOptions.cs b/src/Custom/Moderations/ModerationOptions.cs index a2561def..b88459dd 100644 --- a/src/Custom/Moderations/ModerationOptions.cs +++ b/src/Custom/Moderations/ModerationOptions.cs @@ -10,57 +10,11 @@ internal partial class ModerationOptions // CUSTOM: // - Made internal. This value comes from a parameter on the client method. // - Added setter. - /// - /// The input text to classify - /// - /// To assign an object to this property use . - /// - /// - /// To assign an already formatted json string to this property use . - /// - /// - /// - /// Supported types: - /// - /// - /// - /// - /// - /// where T is of type - /// - /// - /// - /// Examples: - /// - /// - /// BinaryData.FromObjectAsJson("foo") - /// Creates a payload of "foo". - /// - /// - /// BinaryData.FromString("\"foo\"") - /// Creates a payload of "foo". - /// - /// - /// BinaryData.FromObjectAsJson(new { key = "value" }) - /// Creates a payload of { "key": "value" }. - /// - /// - /// BinaryData.FromString("{\"key\": \"value\"}") - /// Creates a payload of { "key": "value" }. - /// - /// - /// - /// + [CodeGenMember("Input")] internal BinaryData Input { get; set; } // CUSTOM: Made internal. The model is specified by the client. - /// - /// Two content moderations models are available: `text-moderation-stable` and - /// `text-moderation-latest`. The default is `text-moderation-latest` which will be automatically - /// upgraded over time. This ensures you are always using our most accurate model. If you use - /// `text-moderation-stable`, we will provide advanced notice before updating the model. Accuracy - /// of `text-moderation-stable` may be slightly lower than for `text-moderation-latest`. - /// + [CodeGenMember("Model")] internal InternalCreateModerationRequestModel? Model { get; set; } // CUSTOM: Made public now that there are no required properties. diff --git a/src/Custom/OpenAIModelFactory.cs b/src/Custom/OpenAIModelFactory.cs index e3aa789b..48ad6dd2 100644 --- a/src/Custom/OpenAIModelFactory.cs +++ b/src/Custom/OpenAIModelFactory.cs @@ -1,36 +1,6 @@ -using OpenAI.Embeddings; -using System; -using System.Collections.Generic; -using System.Linq; - namespace OpenAI; [CodeGenModel("OpenAIModelFactory")] internal static partial class OpenAIModelFactory { - /// Initializes a new instance of . - /// The list of embeddings generated by the model. - /// The name of the model used to generate the embedding. - /// The usage information for the request. - /// A new instance for mocking. - public static OpenAIEmbeddingCollection OpenAIEmbeddingCollection(IEnumerable data = null, EmbeddingTokenUsage usage = null, string model = null) - { - data ??= new List(); - - return new OpenAIEmbeddingCollection(data?.ToList(), model, InternalCreateEmbeddingResponseObject.List, usage, serializedAdditionalRawData: null); - } - - /// Initializes a new instance of . - /// The index of the embedding in the list of embeddings. - /// - /// The embedding vector, which is a list of floats. The length of vector depends on the model as - /// listed in the [embedding guide](/docs/guides/embeddings). - /// - /// A new instance for mocking. - public static OpenAIEmbedding OpenAIEmbedding(ReadOnlyMemory vector = default, int index = default) - { - // TODO: Vector must be converted to base64-encoded string. - return new OpenAIEmbedding(index, BinaryData.FromObjectAsJson(vector, SourceGenerationContext.Default.ReadOnlyMemorySingle), InternalEmbeddingObject.Embedding, serializedAdditionalRawData: null); - } - } diff --git a/src/Custom/RealtimeConversation/ConversationContentModalities.Serialization.cs b/src/Custom/RealtimeConversation/ConversationContentModalities.Serialization.cs index 134a8352..742db33f 100644 --- a/src/Custom/RealtimeConversation/ConversationContentModalities.Serialization.cs +++ b/src/Custom/RealtimeConversation/ConversationContentModalities.Serialization.cs @@ -9,7 +9,7 @@ internal static partial class ConversationContentModalitiesExtensions { internal static IList ToInternalModalities(this ConversationContentModalities modalities) { - List internalModalities = []; + ChangeTrackingList internalModalities = new(); if (modalities.HasFlag(ConversationContentModalities.Text)) { internalModalities.Add(InternalRealtimeRequestSessionModality.Text); diff --git a/src/Custom/RealtimeConversation/ConversationContentModalities.cs b/src/Custom/RealtimeConversation/ConversationContentModalities.cs index 4b7cecba..e1f8dd4b 100644 --- a/src/Custom/RealtimeConversation/ConversationContentModalities.cs +++ b/src/Custom/RealtimeConversation/ConversationContentModalities.cs @@ -8,6 +8,7 @@ namespace OpenAI.RealtimeConversation; [Flags] public enum ConversationContentModalities : int { + Default = 0, Text = 1 << 0, Audio = 1 << 1, } \ No newline at end of file diff --git a/src/Custom/RealtimeConversation/ConversationIncompleteReason.cs b/src/Custom/RealtimeConversation/ConversationIncompleteReason.cs new file mode 100644 index 00000000..bb2b76df --- /dev/null +++ b/src/Custom/RealtimeConversation/ConversationIncompleteReason.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; + +namespace OpenAI.RealtimeConversation; + +[Experimental("OPENAI002")] +[CodeGenModel("RealtimeResponseStatusDetailsReason")] +public readonly partial struct ConversationIncompleteReason +{ +} \ No newline at end of file diff --git a/src/Custom/RealtimeConversation/ConversationInputTokenUsageDetails.cs b/src/Custom/RealtimeConversation/ConversationInputTokenUsageDetails.cs new file mode 100644 index 00000000..713ca5b8 --- /dev/null +++ b/src/Custom/RealtimeConversation/ConversationInputTokenUsageDetails.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; + +namespace OpenAI.RealtimeConversation; + +[Experimental("OPENAI002")] +[CodeGenModel("RealtimeResponseUsageInputTokenDetails")] +public partial class ConversationInputTokenUsageDetails +{ + // CUSTOM: Remove output model optionality, make 'Count' names consistent with Chat + + [CodeGenMember("AudioTokens")] + public int AudioTokenCount { get; } + + [CodeGenMember("CachedTokens")] + public int CachedTokenCount { get; } + + [CodeGenMember("TextTokens")] + public int TextTokenCount { get; } +} diff --git a/src/Custom/RealtimeConversation/ConversationItem.cs b/src/Custom/RealtimeConversation/ConversationItem.cs index 7d24f954..96bc2080 100644 --- a/src/Custom/RealtimeConversation/ConversationItem.cs +++ b/src/Custom/RealtimeConversation/ConversationItem.cs @@ -5,7 +5,7 @@ namespace OpenAI.RealtimeConversation; [Experimental("OPENAI002")] -[CodeGenModel("RealtimeRequestItem")] +[CodeGenModel("RealtimeConversationRequestItem")] public partial class ConversationItem { public string FunctionCallId => (this as InternalRealtimeRequestFunctionCallItem)?.CallId; diff --git a/src/Custom/RealtimeConversation/ConversationOutputTokenUsageDetails.cs b/src/Custom/RealtimeConversation/ConversationOutputTokenUsageDetails.cs new file mode 100644 index 00000000..ba1c3656 --- /dev/null +++ b/src/Custom/RealtimeConversation/ConversationOutputTokenUsageDetails.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; + +namespace OpenAI.RealtimeConversation; + +[Experimental("OPENAI002")] +[CodeGenModel("RealtimeResponseUsageOutputTokenDetails")] +public partial class ConversationOutputTokenUsageDetails +{ + // CUSTOM: Remove output model optionality, make 'Count' names consistent with Chat + + [CodeGenMember("TextTokens")] + public int TextTokenCount { get; } + + [CodeGenMember("AudioTokens")] + public int AudioTokenCount { get; } +} diff --git a/src/Custom/RealtimeConversation/ConversationResponseOptions.cs b/src/Custom/RealtimeConversation/ConversationResponseOptions.cs new file mode 100644 index 00000000..6060d172 --- /dev/null +++ b/src/Custom/RealtimeConversation/ConversationResponseOptions.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; +using System.ClientModel.Primitives; +using System.Text.Json; +using System.Diagnostics.CodeAnalysis; +using System.Linq; + +namespace OpenAI.RealtimeConversation; + +[Experimental("OPENAI002")] +[CodeGenModel("RealtimeResponseCreateParams")] +public partial class ConversationResponseOptions +{ + [CodeGenMember("Conversation")] + public ResponseConversationSelection? ConversationSelection { get; set; } + + [CodeGenMember("Modalities")] + private IList _internalModalities; + + public ConversationContentModalities ContentModalities + { + get => ConversationContentModalitiesExtensions.FromInternalModalities(_internalModalities); + set => _internalModalities = value.ToInternalModalities(); + } + + [CodeGenMember("ToolChoice")] + private BinaryData _internalToolChoice; + + public ConversationToolChoice ToolChoice + { + get => ConversationToolChoice.FromBinaryData(_internalToolChoice); + set + { + _internalToolChoice = value is not null + ? ModelReaderWriter.Write(value) + : null; + } + } + + [CodeGenMember("MaxResponseOutputTokens")] + private BinaryData _maxResponseOutputTokens; + + public ConversationMaxTokensChoice MaxOutputTokens + { + get => ConversationMaxTokensChoice.FromBinaryData(_maxResponseOutputTokens); + set + { + _maxResponseOutputTokens = value == null ? null : ModelReaderWriter.Write(value); + } + } + + [CodeGenMember("Input")] + public IList OverrideItems { get; } +} diff --git a/src/Custom/RealtimeConversation/ConversationSessionOptions.cs b/src/Custom/RealtimeConversation/ConversationSessionOptions.cs index 14f2abeb..5a0bd2be 100644 --- a/src/Custom/RealtimeConversation/ConversationSessionOptions.cs +++ b/src/Custom/RealtimeConversation/ConversationSessionOptions.cs @@ -9,6 +9,9 @@ namespace OpenAI.RealtimeConversation; [CodeGenModel("RealtimeRequestSession")] public partial class ConversationSessionOptions { + [CodeGenMember("Model")] + internal InternalRealtimeRequestSessionModel? Model { get; set; } + [CodeGenMember("Modalities")] private IList _internalModalities; diff --git a/src/Custom/RealtimeConversation/ConversationStatusDetails.cs b/src/Custom/RealtimeConversation/ConversationStatusDetails.cs index fc4a7f94..346eebd1 100644 --- a/src/Custom/RealtimeConversation/ConversationStatusDetails.cs +++ b/src/Custom/RealtimeConversation/ConversationStatusDetails.cs @@ -8,6 +8,16 @@ namespace OpenAI.RealtimeConversation; [CodeGenModel("RealtimeResponseStatusDetails")] public partial class ConversationStatusDetails { - [CodeGenMember("Kind")] + [CodeGenMember("Type")] public ConversationStatus StatusKind { get; } + + [CodeGenMember("Reason")] + public ConversationIncompleteReason? IncompleteReason { get; } + + public string ErrorKind => Error?.Type ?? string.Empty; + + public string ErrorCode => Error?.Code ?? string.Empty; + + [CodeGenMember("Error")] + internal InternalRealtimeResponseStatusDetailsError Error { get; set; } } \ No newline at end of file diff --git a/src/Custom/RealtimeConversation/ConversationTokenUsage.cs b/src/Custom/RealtimeConversation/ConversationTokenUsage.cs new file mode 100644 index 00000000..1842c2b1 --- /dev/null +++ b/src/Custom/RealtimeConversation/ConversationTokenUsage.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; + +namespace OpenAI.RealtimeConversation; + +public partial class ConversationTokenUsage +{ + // CUSTOM: Renamed, nullability removed + [CodeGenMember("InputTokens")] + public int InputTokenCount { get; } + + // CUSTOM: Renamed, nullability removed + [CodeGenMember("OutputTokens")] + public int OutputTokenCount { get; } + + // CUSTOM: Renamed, nullability removed + [CodeGenMember("TotalTokens")] + public int TotalTokenCount { get; } +} \ No newline at end of file diff --git a/src/Custom/RealtimeConversation/ConversationTurnDetectionOptions.cs b/src/Custom/RealtimeConversation/ConversationTurnDetectionOptions.cs index efcb54a9..e8ebe583 100644 --- a/src/Custom/RealtimeConversation/ConversationTurnDetectionOptions.cs +++ b/src/Custom/RealtimeConversation/ConversationTurnDetectionOptions.cs @@ -18,13 +18,15 @@ public static ConversationTurnDetectionOptions CreateDisabledTurnDetectionOption public static ConversationTurnDetectionOptions CreateServerVoiceActivityTurnDetectionOptions( float? detectionThreshold = null, TimeSpan? prefixPaddingDuration = null, - TimeSpan? silenceDuration = null) + TimeSpan? silenceDuration = null, + bool? enableAutomaticResponseCreation = null) { return new InternalRealtimeServerVadTurnDetection() { Threshold = detectionThreshold, PrefixPaddingMs = prefixPaddingDuration, - SilenceDurationMs = silenceDuration + SilenceDurationMs = silenceDuration, + CreateResponse = enableAutomaticResponseCreation, }; } } \ No newline at end of file diff --git a/src/Custom/RealtimeConversation/GeneratorStubs.cs b/src/Custom/RealtimeConversation/GeneratorStubs.cs index e5594d79..3e3cfce8 100644 --- a/src/Custom/RealtimeConversation/GeneratorStubs.cs +++ b/src/Custom/RealtimeConversation/GeneratorStubs.cs @@ -9,7 +9,5 @@ namespace OpenAI.RealtimeConversation; [Experimental("OPENAI002")][CodeGenModel("RealtimeMessageRole")] public readonly partial struct ConversationMessageRole { } [Experimental("OPENAI002")][CodeGenModel("RealtimeResponseStatus")] public readonly partial struct ConversationStatus { } [Experimental("OPENAI002")][CodeGenModel("RealtimeResponseUsage")] public partial class ConversationTokenUsage { } -[Experimental("OPENAI002")][CodeGenModel("RealtimeResponseUsageInputTokenDetails")] public partial class ConversationInputTokenUsageDetails { } -[Experimental("OPENAI002")][CodeGenModel("RealtimeResponseUsageOutputTokenDetails")] public partial class ConversationOutputTokenUsageDetails { } [Experimental("OPENAI002")][CodeGenModel("RealtimeToolType")] public readonly partial struct ConversationToolKind { } [Experimental("OPENAI002")][CodeGenModel("RealtimeVoice")] public readonly partial struct ConversationVoice { } diff --git a/src/Custom/RealtimeConversation/Internal/GeneratorStubs.cs b/src/Custom/RealtimeConversation/Internal/GeneratorStubs.cs index 74c2eca2..d26ba5e9 100644 --- a/src/Custom/RealtimeConversation/Internal/GeneratorStubs.cs +++ b/src/Custom/RealtimeConversation/Internal/GeneratorStubs.cs @@ -12,20 +12,26 @@ namespace OpenAI.RealtimeConversation; [Experimental("OPENAI002")][CodeGenModel("RealtimeClientEventResponseCancel")] internal partial class InternalRealtimeClientEventResponseCancel { } [Experimental("OPENAI002")][CodeGenModel("RealtimeClientEventSessionUpdate")] internal partial class InternalRealtimeClientEventSessionUpdate { } [Experimental("OPENAI002")][CodeGenModel("RealtimeClientEventType")] internal readonly partial struct InternalRealtimeClientEventType { } +[Experimental("OPENAI002")][CodeGenModel("RealtimeConversationResponseItemObject")] internal readonly partial struct InternalRealtimeConversationResponseItemObject { } [Experimental("OPENAI002")][CodeGenModel("RealtimeItemType")] internal readonly partial struct InternalRealtimeItemType { } +[Experimental("OPENAI002")][CodeGenModel("RealtimeModality")] internal readonly partial struct InternalRealtimeRequestSessionModality { } [Experimental("OPENAI002")][CodeGenModel("RealtimeRequestAudioContentPart")] internal partial class InternalRealtimeRequestAudioContentPart { } [Experimental("OPENAI002")][CodeGenModel("RealtimeRequestFunctionCallItem")] internal partial class InternalRealtimeRequestFunctionCallItem { } [Experimental("OPENAI002")][CodeGenModel("RealtimeRequestFunctionCallOutputItem")] internal partial class InternalRealtimeRequestFunctionCallOutputItem { } [Experimental("OPENAI002")][CodeGenModel("RealtimeRequestMessageItem")] internal partial class InternalRealtimeRequestMessageItem { } -[Experimental("OPENAI002")][CodeGenModel("RealtimeRequestSessionModality")] internal readonly partial struct InternalRealtimeRequestSessionModality { } +[Experimental("OPENAI002")][CodeGenModel("RealtimeRequestSessionModel")] internal readonly partial struct InternalRealtimeRequestSessionModel { } [Experimental("OPENAI002")][CodeGenModel("RealtimeRequestTextContentPart")] internal partial class InternalRealtimeRequestTextContentPart { } [Experimental("OPENAI002")][CodeGenModel("RealtimeResponseAudioContentPart")] internal partial class InternalRealtimeResponseAudioContentPart { } [Experimental("OPENAI002")][CodeGenModel("RealtimeResponseFunctionCallItem")] internal partial class InternalRealtimeResponseFunctionCallItem { } [Experimental("OPENAI002")][CodeGenModel("RealtimeResponseFunctionCallOutputItem")] internal partial class InternalRealtimeResponseFunctionCallOutputItem { } -[Experimental("OPENAI002")][CodeGenModel("RealtimeResponseItemObject")] internal readonly partial struct InternalRealtimeResponseItemObject { } +[Experimental("OPENAI002")][CodeGenModel("RealtimeResponseModality")] internal readonly partial struct InternalRealtimeResponseModality { } [Experimental("OPENAI002")][CodeGenModel("RealtimeResponseObject")] internal readonly partial struct InternalRealtimeResponseObject { } +[Experimental("OPENAI002")][CodeGenModel("RealtimeResponseOutputAudioFormat")] internal readonly partial struct InternalRealtimeResponseOutputAudioFormat { } [Experimental("OPENAI002")][CodeGenModel("RealtimeResponseSessionObject")] internal readonly partial struct InternalRealtimeResponseSessionObject { } +[Experimental("OPENAI002")][CodeGenModel("RealtimeResponseStatusDetailsError")] internal partial class InternalRealtimeResponseStatusDetailsError { } +[Experimental("OPENAI002")][CodeGenModel("RealtimeResponseStatusDetailsType")] internal readonly partial struct InternalRealtimeResponseStatusDetailsType { } [Experimental("OPENAI002")][CodeGenModel("RealtimeResponseTextContentPart")] internal partial class InternalRealtimeResponseTextContentPart { } +[Experimental("OPENAI002")][CodeGenModel("RealtimeResponseVoice")] internal readonly partial struct InternalRealtimeResponseVoice { } [Experimental("OPENAI002")][CodeGenModel("RealtimeServerEventConversationCreated")] internal partial class InternalRealtimeServerEventConversationCreated { } [Experimental("OPENAI002")][CodeGenModel("RealtimeServerEventConversationCreatedConversation")] internal partial class InternalRealtimeServerEventConversationCreatedConversation { } [Experimental("OPENAI002")][CodeGenModel("RealtimeServerEventConversationItemInputAudioTranscriptionFailedError")] internal partial class InternalRealtimeServerEventConversationItemInputAudioTranscriptionFailedError { } @@ -35,10 +41,9 @@ namespace OpenAI.RealtimeConversation; [Experimental("OPENAI002")][CodeGenModel("RealtimeToolChoiceObject")] internal partial class InternalRealtimeToolChoiceObject { } [Experimental("OPENAI002")][CodeGenModel("UnknownRealtimeClientEvent")] internal partial class UnknownRealtimeClientEvent { } [Experimental("OPENAI002")][CodeGenModel("UnknownRealtimeContentPart")] internal partial class UnknownRealtimeContentPart { } -[Experimental("OPENAI002")][CodeGenModel("UnknownRealtimeRequestItem")] internal partial class UnknownRealtimeRequestItem { } +[Experimental("OPENAI002")][CodeGenModel("UnknownRealtimeConversationRequestItem")] internal partial class UnknownRealtimeRequestItem { } +[Experimental("OPENAI002")][CodeGenModel("UnknownRealtimeConversationResponseItem")] internal partial class UnknownRealtimeResponseItem { } [Experimental("OPENAI002")][CodeGenModel("UnknownRealtimeRequestMessageItem")] internal partial class UnknownRealtimeRequestMessageItem { } -[Experimental("OPENAI002")][CodeGenModel("UnknownRealtimeResponseItem")] internal partial class UnknownRealtimeResponseItem { } -[Experimental("OPENAI002")][CodeGenModel("UnknownRealtimeResponseStatusDetails")] internal partial class UnknownRealtimeResponseStatusDetails { } [Experimental("OPENAI002")][CodeGenModel("UnknownRealtimeServerEvent")] internal partial class UnknownRealtimeServerEvent { } [Experimental("OPENAI002")][CodeGenModel("UnknownRealtimeTool")] internal partial class UnknownRealtimeTool { } [Experimental("OPENAI002")][CodeGenModel("UnknownRealtimeToolChoiceObject")] internal partial class UnknownRealtimeToolChoiceObject { } diff --git a/src/Custom/RealtimeConversation/Internal/InternalRealtimeClientEventResponseCreateResponse.cs b/src/Custom/RealtimeConversation/Internal/InternalRealtimeClientEventResponseCreateResponse.cs deleted file mode 100644 index b4338272..00000000 --- a/src/Custom/RealtimeConversation/Internal/InternalRealtimeClientEventResponseCreateResponse.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ClientModel.Primitives; -using System.Text.Json; -using System.Diagnostics.CodeAnalysis; -using System.Linq; - -namespace OpenAI.RealtimeConversation; - -[Experimental("OPENAI002")] -[CodeGenModel("RealtimeClientEventResponseCreateResponse")] -internal partial class InternalRealtimeClientEventResponseCreateResponse -{ - [CodeGenMember("ToolChoice")] - public BinaryData ToolChoice { get; set; } - - public static InternalRealtimeClientEventResponseCreateResponse FromSessionOptions( - ConversationSessionOptions sessionOptions) - { - Argument.AssertNotNull(sessionOptions, nameof(sessionOptions)); - if (Optional.IsDefined(sessionOptions.InputAudioFormat)) - { - throw new InvalidOperationException($"{nameof(sessionOptions.InputAudioFormat)} cannot be overriden" - + " per response."); - } - BinaryData maxTokensChoice = Optional.IsDefined(sessionOptions.MaxOutputTokens) - ? ModelReaderWriter.Write(sessionOptions.MaxOutputTokens) - : null; - IList internalModalities - = sessionOptions.ContentModalities.ToInternalModalities(); - IList rawModalities = internalModalities.Count > 0 - ? internalModalities.Select(modality => modality.ToString()).ToList() - : new ChangeTrackingList(); - BinaryData toolChoice = Optional.IsDefined(sessionOptions.ToolChoice) - ? ModelReaderWriter.Write(sessionOptions.ToolChoice) - : null; - InternalRealtimeClientEventResponseCreateResponse internalOptions = new( - modalities: rawModalities, - instructions: sessionOptions.Instructions, - voice: sessionOptions.Voice?.ToString(), - outputAudioFormat: sessionOptions.OutputAudioFormat?.ToString(), - tools: sessionOptions.Tools, - toolChoice: toolChoice, - temperature: sessionOptions.Temperature, - maxOutputTokens: maxTokensChoice, - additionalBinaryDataProperties: null); - return internalOptions; - } -} diff --git a/src/Custom/RealtimeConversation/Internal/InternalRealtimeResponse.cs b/src/Custom/RealtimeConversation/Internal/InternalRealtimeResponse.cs index 0c26a8a2..bb6d9f17 100644 --- a/src/Custom/RealtimeConversation/Internal/InternalRealtimeResponse.cs +++ b/src/Custom/RealtimeConversation/Internal/InternalRealtimeResponse.cs @@ -10,4 +10,13 @@ internal partial class InternalRealtimeResponse { [CodeGenMember("Output")] public IReadOnlyList Output { get; } + + [CodeGenMember("Modalities")] + internal IReadOnlyList Modalities { get; } + + [CodeGenMember("Voice")] + public ConversationVoice? Voice { get; } + + [CodeGenMember("OutputAudioFormat")] + public ConversationAudioFormat? OutputAudioFormat { get; } } diff --git a/src/Custom/RealtimeConversation/Internal/InternalRealtimeResponseItem.cs b/src/Custom/RealtimeConversation/Internal/InternalRealtimeResponseItem.cs index 0679556f..6dd2e914 100644 --- a/src/Custom/RealtimeConversation/Internal/InternalRealtimeResponseItem.cs +++ b/src/Custom/RealtimeConversation/Internal/InternalRealtimeResponseItem.cs @@ -4,8 +4,8 @@ namespace OpenAI.RealtimeConversation; [Experimental("OPENAI002")] -[CodeGenModel("RealtimeResponseItem")] -internal partial class InternalRealtimeResponseItem +[CodeGenModel("RealtimeConversationResponseItem")] +internal partial class InternalRealtimeConversationResponseItem { public string ResponseId => (this as InternalRealtimeResponseMessageItem)?.ResponseId diff --git a/src/Custom/RealtimeConversation/Internal/InternalRealtimeResponseMessageItem.cs b/src/Custom/RealtimeConversation/Internal/InternalRealtimeResponseMessageItem.cs index a6934698..25dc0c53 100644 --- a/src/Custom/RealtimeConversation/Internal/InternalRealtimeResponseMessageItem.cs +++ b/src/Custom/RealtimeConversation/Internal/InternalRealtimeResponseMessageItem.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; namespace OpenAI.RealtimeConversation; @@ -6,6 +7,13 @@ namespace OpenAI.RealtimeConversation; [CodeGenModel("RealtimeResponseMessageItem")] internal partial class InternalRealtimeResponseMessageItem { + // CUSTOM: Use the available strong type for roles. + [CodeGenMember("Role")] public ConversationMessageRole Role { get; } + + // CUSTOM: Explicitly apply response model read-only. + + [CodeGenMember("Content")] + public IReadOnlyList Content { get; } } diff --git a/src/Custom/RealtimeConversation/RealtimeConversationSession.cs b/src/Custom/RealtimeConversation/RealtimeConversationSession.cs index 6ba3f6ab..31a4ef50 100644 --- a/src/Custom/RealtimeConversation/RealtimeConversationSession.cs +++ b/src/Custom/RealtimeConversation/RealtimeConversationSession.cs @@ -276,36 +276,33 @@ public virtual void InterruptResponse(CancellationToken cancellationToken = defa SendCommand(internalCommand, cancellationToken); } - public virtual async Task StartResponseAsync(CancellationToken cancellationToken = default) + public virtual async Task StartResponseAsync(ConversationResponseOptions options, CancellationToken cancellationToken = default) { - InternalRealtimeClientEventResponseCreateResponse internalOptions = new(); - InternalRealtimeClientEventResponseCreate internalCommand = new(internalOptions); + InternalRealtimeClientEventResponseCreate internalCommand = new( + kind: InternalRealtimeClientEventType.ResponseCreate, + eventId: null, + additionalBinaryDataProperties: null, + response: options); await SendCommandAsync(internalCommand, cancellationToken).ConfigureAwait(false); } - - public virtual void StartResponse(CancellationToken cancellationToken = default) + public virtual async Task StartResponseAsync(CancellationToken cancellationToken = default) { - InternalRealtimeClientEventResponseCreateResponse internalOptions = new(); - InternalRealtimeClientEventResponseCreate internalCommand = new(internalOptions); - SendCommand(internalCommand, cancellationToken); + await StartResponseAsync(new ConversationResponseOptions(), cancellationToken).ConfigureAwait(false); } - public virtual async Task StartResponseAsync(ConversationSessionOptions sessionOptionOverrides, CancellationToken cancellationToken = default) + public virtual void StartResponse(ConversationResponseOptions options, CancellationToken cancellationToken = default) { - Argument.AssertNotNull(sessionOptionOverrides, nameof(sessionOptionOverrides)); - InternalRealtimeClientEventResponseCreateResponse internalOptions - = InternalRealtimeClientEventResponseCreateResponse.FromSessionOptions(sessionOptionOverrides); - InternalRealtimeClientEventResponseCreate internalCommand = new(internalOptions); - await SendCommandAsync(internalCommand, cancellationToken).ConfigureAwait(false); + InternalRealtimeClientEventResponseCreate internalCommand = new( + kind: InternalRealtimeClientEventType.ResponseCreate, + eventId: null, + additionalBinaryDataProperties: null, + response: options); + SendCommand(internalCommand, cancellationToken); } - public virtual void StartResponse(ConversationSessionOptions sessionOptionOverrides, CancellationToken cancellationToken = default) + public void StartResponse(CancellationToken cancellationToken = default) { - Argument.AssertNotNull(sessionOptionOverrides, nameof(sessionOptionOverrides)); - InternalRealtimeClientEventResponseCreateResponse internalOptions - = InternalRealtimeClientEventResponseCreateResponse.FromSessionOptions(sessionOptionOverrides); - InternalRealtimeClientEventResponseCreate internalCommand = new(internalOptions); - SendCommand(internalCommand, cancellationToken); + StartResponse(new ConversationResponseOptions(), cancellationToken); } public virtual async Task CancelResponseAsync(CancellationToken cancellationToken = default) diff --git a/src/Custom/RealtimeConversation/ResponseConversationSelection.cs b/src/Custom/RealtimeConversation/ResponseConversationSelection.cs new file mode 100644 index 00000000..b2f77da7 --- /dev/null +++ b/src/Custom/RealtimeConversation/ResponseConversationSelection.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.ClientModel.Primitives; +using System.Text.Json; +using System.Diagnostics.CodeAnalysis; +using System.Linq; + +namespace OpenAI.RealtimeConversation; + +[Experimental("OPENAI002")] +[CodeGenModel("RealtimeResponseCreateParamsConversation")] +public readonly partial struct ResponseConversationSelection +{ +} diff --git a/src/Custom/RealtimeConversation/ResponseUpdates/ConversationItemCreatedUpdate.cs b/src/Custom/RealtimeConversation/ResponseUpdates/ConversationItemCreatedUpdate.cs index 9b98488e..ca560064 100644 --- a/src/Custom/RealtimeConversation/ResponseUpdates/ConversationItemCreatedUpdate.cs +++ b/src/Custom/RealtimeConversation/ResponseUpdates/ConversationItemCreatedUpdate.cs @@ -17,7 +17,7 @@ namespace OpenAI.RealtimeConversation; public partial class ConversationItemCreatedUpdate { [CodeGenMember("Item")] - private readonly InternalRealtimeResponseItem _internalItem; + private readonly InternalRealtimeConversationResponseItem _internalItem; public string ItemId => _internalItem.Id; diff --git a/src/Custom/RealtimeConversation/ResponseUpdates/ConversationItemStreamingFinishedUpdate.cs b/src/Custom/RealtimeConversation/ResponseUpdates/ConversationItemStreamingFinishedUpdate.cs index 86881012..4f68f7d9 100644 --- a/src/Custom/RealtimeConversation/ResponseUpdates/ConversationItemStreamingFinishedUpdate.cs +++ b/src/Custom/RealtimeConversation/ResponseUpdates/ConversationItemStreamingFinishedUpdate.cs @@ -15,7 +15,7 @@ namespace OpenAI.RealtimeConversation; public partial class ConversationItemStreamingFinishedUpdate { [CodeGenMember("Item")] - private readonly InternalRealtimeResponseItem _internalItem; + private readonly InternalRealtimeConversationResponseItem _internalItem; public string ItemId => _internalItem.Id; diff --git a/src/Custom/RealtimeConversation/ResponseUpdates/ConversationItemStreamingStartedUpdate.cs b/src/Custom/RealtimeConversation/ResponseUpdates/ConversationItemStreamingStartedUpdate.cs index d1d4b538..a5ce8974 100644 --- a/src/Custom/RealtimeConversation/ResponseUpdates/ConversationItemStreamingStartedUpdate.cs +++ b/src/Custom/RealtimeConversation/ResponseUpdates/ConversationItemStreamingStartedUpdate.cs @@ -14,7 +14,7 @@ namespace OpenAI.RealtimeConversation; public partial class ConversationItemStreamingStartedUpdate { [CodeGenMember("Item")] - private readonly InternalRealtimeResponseItem _internalItem; + private readonly InternalRealtimeConversationResponseItem _internalItem; public string ItemId => _internalItem.Id; diff --git a/src/Custom/RealtimeConversation/ResponseUpdates/ConversationResponseStartedUpdate.cs b/src/Custom/RealtimeConversation/ResponseUpdates/ConversationResponseStartedUpdate.cs index b0bb3a13..43ba27e8 100644 --- a/src/Custom/RealtimeConversation/ResponseUpdates/ConversationResponseStartedUpdate.cs +++ b/src/Custom/RealtimeConversation/ResponseUpdates/ConversationResponseStartedUpdate.cs @@ -19,7 +19,7 @@ public partial class ConversationResponseStartedUpdate public string ResponseId => _internalResponse.Id; - public ConversationStatus Status => _internalResponse.Status; + public ConversationStatus Status => _internalResponse.Status.Value; public ConversationStatusDetails StatusDetails => _internalResponse.StatusDetails; diff --git a/src/Generated/Models/AssistantChatMessage.Serialization.cs b/src/Generated/Models/AssistantChatMessage.Serialization.cs index dd656437..529601ef 100644 --- a/src/Generated/Models/AssistantChatMessage.Serialization.cs +++ b/src/Generated/Models/AssistantChatMessage.Serialization.cs @@ -60,6 +60,18 @@ protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWri writer.WriteNull("functionCall"u8); } } + if (Optional.IsDefined(OutputAudioReference) && _additionalBinaryDataProperties?.ContainsKey("audio") != true) + { + if (OutputAudioReference != null) + { + writer.WritePropertyName("audio"u8); + writer.WriteObjectValue(OutputAudioReference, options); + } + else + { + writer.WriteNull("audio"u8); + } + } } AssistantChatMessage IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (AssistantChatMessage)JsonModelCreateCore(ref reader, options); @@ -81,23 +93,24 @@ internal static AssistantChatMessage DeserializeAssistantChatMessage(JsonElement { return null; } - Chat.ChatMessageRole role = default; ChatMessageContent content = default; + Chat.ChatMessageRole role = default; IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); string refusal = default; string participantName = default; IList toolCalls = default; ChatFunctionCall functionCall = default; + ChatOutputAudioReference outputAudioReference = default; foreach (var prop in element.EnumerateObject()) { - if (prop.NameEquals("role"u8)) + if (prop.NameEquals("content"u8)) { - role = prop.Value.GetString().ToChatMessageRole(); + DeserializeContentValue(prop, ref content); continue; } - if (prop.NameEquals("content"u8)) + if (prop.NameEquals("role"u8)) { - DeserializeContentValue(prop, ref content); + role = prop.Value.GetString().ToChatMessageRole(); continue; } if (prop.NameEquals("refusal"u8)) @@ -139,6 +152,16 @@ internal static AssistantChatMessage DeserializeAssistantChatMessage(JsonElement functionCall = ChatFunctionCall.DeserializeChatFunctionCall(prop.Value, options); continue; } + if (prop.NameEquals("audio"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + outputAudioReference = null; + continue; + } + outputAudioReference = ChatOutputAudioReference.DeserializeChatOutputAudioReference(prop.Value, options); + continue; + } if (true) { additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); @@ -146,13 +169,14 @@ internal static AssistantChatMessage DeserializeAssistantChatMessage(JsonElement } // CUSTOM: Initialize Content collection property. return new AssistantChatMessage( - role, content ?? new ChatMessageContent(), + role, additionalBinaryDataProperties, refusal, participantName, toolCalls ?? new ChangeTrackingList(), - functionCall); + functionCall, + outputAudioReference); } BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); diff --git a/src/Generated/Models/AssistantChatMessage.cs b/src/Generated/Models/AssistantChatMessage.cs index e93ddae8..0fd14334 100644 --- a/src/Generated/Models/AssistantChatMessage.cs +++ b/src/Generated/Models/AssistantChatMessage.cs @@ -9,12 +9,13 @@ namespace OpenAI.Chat { public partial class AssistantChatMessage : ChatMessage { - internal AssistantChatMessage(Chat.ChatMessageRole role, ChatMessageContent content, IDictionary additionalBinaryDataProperties, string refusal, string participantName, IList toolCalls, ChatFunctionCall functionCall) : base(role, content, additionalBinaryDataProperties) + internal AssistantChatMessage(ChatMessageContent content, Chat.ChatMessageRole role, IDictionary additionalBinaryDataProperties, string refusal, string participantName, IList toolCalls, ChatFunctionCall functionCall, ChatOutputAudioReference outputAudioReference) : base(content, role, additionalBinaryDataProperties) { Refusal = refusal; ParticipantName = participantName; ToolCalls = toolCalls; FunctionCall = functionCall; + OutputAudioReference = outputAudioReference; } public string Refusal { get; set; } diff --git a/src/Generated/Models/AssistantCreationOptions.Serialization.cs b/src/Generated/Models/AssistantCreationOptions.Serialization.cs index b74e1cf0..a6c9bb9e 100644 --- a/src/Generated/Models/AssistantCreationOptions.Serialization.cs +++ b/src/Generated/Models/AssistantCreationOptions.Serialization.cs @@ -65,26 +65,19 @@ protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWrit } if (Optional.IsCollectionDefined(Metadata) && _additionalBinaryDataProperties?.ContainsKey("metadata") != true) { - if (Metadata != null) + writer.WritePropertyName("metadata"u8); + writer.WriteStartObject(); + foreach (var item in Metadata) { - writer.WritePropertyName("metadata"u8); - writer.WriteStartObject(); - foreach (var item in Metadata) + writer.WritePropertyName(item.Key); + if (item.Value == null) { - writer.WritePropertyName(item.Key); - if (item.Value == null) - { - writer.WriteNullValue(); - continue; - } - writer.WriteStringValue(item.Value); + writer.WriteNullValue(); + continue; } - writer.WriteEndObject(); - } - else - { - writer.WriteNull("metadata"u8); + writer.WriteStringValue(item.Value); } + writer.WriteEndObject(); } if (Optional.IsDefined(Temperature) && _additionalBinaryDataProperties?.ContainsKey("temperature") != true) { diff --git a/src/Generated/Models/AssistantCreationOptions.cs b/src/Generated/Models/AssistantCreationOptions.cs index ebc4e320..0a1f7c5d 100644 --- a/src/Generated/Models/AssistantCreationOptions.cs +++ b/src/Generated/Models/AssistantCreationOptions.cs @@ -32,7 +32,7 @@ internal AssistantCreationOptions(string name, string description, string instru public string Instructions { get; set; } - public IDictionary Metadata { get; set; } + public IDictionary Metadata { get; } public float? Temperature { get; set; } diff --git a/src/Generated/Models/AssistantModificationOptions.Serialization.cs b/src/Generated/Models/AssistantModificationOptions.Serialization.cs index d60696f6..7212963c 100644 --- a/src/Generated/Models/AssistantModificationOptions.Serialization.cs +++ b/src/Generated/Models/AssistantModificationOptions.Serialization.cs @@ -65,26 +65,19 @@ protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWrit } if (Optional.IsCollectionDefined(Metadata) && _additionalBinaryDataProperties?.ContainsKey("metadata") != true) { - if (Metadata != null) + writer.WritePropertyName("metadata"u8); + writer.WriteStartObject(); + foreach (var item in Metadata) { - writer.WritePropertyName("metadata"u8); - writer.WriteStartObject(); - foreach (var item in Metadata) + writer.WritePropertyName(item.Key); + if (item.Value == null) { - writer.WritePropertyName(item.Key); - if (item.Value == null) - { - writer.WriteNullValue(); - continue; - } - writer.WriteStringValue(item.Value); + writer.WriteNullValue(); + continue; } - writer.WriteEndObject(); - } - else - { - writer.WriteNull("metadata"u8); + writer.WriteStringValue(item.Value); } + writer.WriteEndObject(); } if (Optional.IsDefined(Temperature) && _additionalBinaryDataProperties?.ContainsKey("temperature") != true) { diff --git a/src/Generated/Models/AssistantModificationOptions.cs b/src/Generated/Models/AssistantModificationOptions.cs index 3019103f..c9d4cd4c 100644 --- a/src/Generated/Models/AssistantModificationOptions.cs +++ b/src/Generated/Models/AssistantModificationOptions.cs @@ -39,7 +39,7 @@ internal AssistantModificationOptions(string name, string description, string in public string Instructions { get; set; } - public IDictionary Metadata { get; set; } + public IDictionary Metadata { get; } public float? Temperature { get; set; } diff --git a/src/Generated/Models/ChatAudioOptions.Serialization.cs b/src/Generated/Models/ChatAudioOptions.Serialization.cs new file mode 100644 index 00000000..1b618609 --- /dev/null +++ b/src/Generated/Models/ChatAudioOptions.Serialization.cs @@ -0,0 +1,156 @@ +// + +#nullable disable + +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; +using OpenAI; + +namespace OpenAI.Chat +{ + public partial class ChatAudioOptions : IJsonModel + { + internal ChatAudioOptions() + { + } + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ChatAudioOptions)} does not support writing '{format}' format."); + } + if (_additionalBinaryDataProperties?.ContainsKey("voice") != true) + { + writer.WritePropertyName("voice"u8); + writer.WriteStringValue(OutputAudioVoice.ToString()); + } + if (_additionalBinaryDataProperties?.ContainsKey("format") != true) + { + writer.WritePropertyName("format"u8); + writer.WriteStringValue(OutputAudioFormat.ToString()); + } + if (true && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + if (ModelSerializationExtensions.IsSentinelValue(item.Value)) + { + continue; + } + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + ChatAudioOptions IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + protected virtual ChatAudioOptions JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ChatAudioOptions)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeChatAudioOptions(document.RootElement, options); + } + + internal static ChatAudioOptions DeserializeChatAudioOptions(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ChatOutputAudioVoice outputAudioVoice = default; + ChatOutputAudioFormat outputAudioFormat = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("voice"u8)) + { + outputAudioVoice = new ChatOutputAudioVoice(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("format"u8)) + { + outputAudioFormat = new ChatOutputAudioFormat(prop.Value.GetString()); + continue; + } + if (true) + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ChatAudioOptions(outputAudioVoice, outputAudioFormat, additionalBinaryDataProperties); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(ChatAudioOptions)} does not support writing '{options.Format}' format."); + } + } + + ChatAudioOptions IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + protected virtual ChatAudioOptions PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeChatAudioOptions(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ChatAudioOptions)} does not support reading '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + + public static implicit operator BinaryContent(ChatAudioOptions chatAudioOptions) + { + if (chatAudioOptions == null) + { + return null; + } + return BinaryContent.Create(chatAudioOptions, ModelSerializationExtensions.WireOptions); + } + + public static explicit operator ChatAudioOptions(ClientResult result) + { + using PipelineResponse response = result.GetRawResponse(); + using JsonDocument document = JsonDocument.Parse(response.Content); + return DeserializeChatAudioOptions(document.RootElement, ModelSerializationExtensions.WireOptions); + } + } +} diff --git a/src/Generated/Models/ChatAudioOptions.cs b/src/Generated/Models/ChatAudioOptions.cs new file mode 100644 index 00000000..18b018e2 --- /dev/null +++ b/src/Generated/Models/ChatAudioOptions.cs @@ -0,0 +1,33 @@ +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace OpenAI.Chat +{ + public partial class ChatAudioOptions + { + private protected IDictionary _additionalBinaryDataProperties; + + public ChatAudioOptions(ChatOutputAudioVoice outputAudioVoice, ChatOutputAudioFormat outputAudioFormat) + { + OutputAudioVoice = outputAudioVoice; + OutputAudioFormat = outputAudioFormat; + } + + internal ChatAudioOptions(ChatOutputAudioVoice outputAudioVoice, ChatOutputAudioFormat outputAudioFormat, IDictionary additionalBinaryDataProperties) + { + OutputAudioVoice = outputAudioVoice; + OutputAudioFormat = outputAudioFormat; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + internal IDictionary SerializedAdditionalRawData + { + get => _additionalBinaryDataProperties; + set => _additionalBinaryDataProperties = value; + } + } +} diff --git a/src/Generated/Models/ChatCompletionOptions.Serialization.cs b/src/Generated/Models/ChatCompletionOptions.Serialization.cs index 8f1a29ec..64308c95 100644 --- a/src/Generated/Models/ChatCompletionOptions.Serialization.cs +++ b/src/Generated/Models/ChatCompletionOptions.Serialization.cs @@ -252,26 +252,19 @@ protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWrit } if (Optional.IsCollectionDefined(Metadata) && _additionalBinaryDataProperties?.ContainsKey("metadata") != true) { - if (Metadata != null) + writer.WritePropertyName("metadata"u8); + writer.WriteStartObject(); + foreach (var item in Metadata) { - writer.WritePropertyName("metadata"u8); - writer.WriteStartObject(); - foreach (var item in Metadata) + writer.WritePropertyName(item.Key); + if (item.Value == null) { - writer.WritePropertyName(item.Key); - if (item.Value == null) - { - writer.WriteNullValue(); - continue; - } - writer.WriteStringValue(item.Value); + writer.WriteNullValue(); + continue; } - writer.WriteEndObject(); - } - else - { - writer.WriteNull("metadata"u8); + writer.WriteStringValue(item.Value); } + writer.WriteEndObject(); } if (Optional.IsDefined(StoredOutputEnabled) && _additionalBinaryDataProperties?.ContainsKey("store") != true) { @@ -285,6 +278,23 @@ protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWrit writer.WriteNull("store"u8); } } + if (Optional.IsDefined(ReasoningEffortLevel) && _additionalBinaryDataProperties?.ContainsKey("reasoning_effort") != true) + { + writer.WritePropertyName("reasoning_effort"u8); + writer.WriteStringValue(ReasoningEffortLevel.Value.ToString()); + } + if (Optional.IsDefined(OutputPrediction) && _additionalBinaryDataProperties?.ContainsKey("prediction") != true) + { + if (OutputPrediction != null) + { + writer.WritePropertyName("prediction"u8); + writer.WriteObjectValue(OutputPrediction, options); + } + else + { + writer.WriteNull("prediction"u8); + } + } if (Optional.IsDefined(_serviceTier) && _additionalBinaryDataProperties?.ContainsKey("service_tier") != true) { if (_serviceTier != null) @@ -297,6 +307,35 @@ protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWrit writer.WriteNull("serviceTier"u8); } } + if (Optional.IsCollectionDefined(_internalModalities) && _additionalBinaryDataProperties?.ContainsKey("modalities") != true) + { + if (_internalModalities != null) + { + writer.WritePropertyName("modalities"u8); + writer.WriteStartArray(); + foreach (InternalCreateChatCompletionRequestModality item in _internalModalities) + { + writer.WriteStringValue(item.ToString()); + } + writer.WriteEndArray(); + } + else + { + writer.WriteNull("modalities"u8); + } + } + if (Optional.IsDefined(_audioOptions) && _additionalBinaryDataProperties?.ContainsKey("audio") != true) + { + if (_audioOptions != null) + { + writer.WritePropertyName("audio"u8); + writer.WriteObjectValue(_audioOptions, options); + } + else + { + writer.WriteNull("audio"u8); + } + } if (true && _additionalBinaryDataProperties != null) { foreach (var item in _additionalBinaryDataProperties) @@ -362,7 +401,11 @@ internal static ChatCompletionOptions DeserializeChatCompletionOptions(JsonEleme IList functions = default; IDictionary metadata = default; bool? storedOutputEnabled = default; + ChatReasoningEffortLevel? reasoningEffortLevel = default; + ChatOutputPrediction outputPrediction = default; InternalCreateChatCompletionRequestServiceTier? serviceTier = default; + IList internalModalities = default; + ChatAudioOptions audioOptions = default; IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); foreach (var prop in element.EnumerateObject()) { @@ -611,6 +654,25 @@ internal static ChatCompletionOptions DeserializeChatCompletionOptions(JsonEleme storedOutputEnabled = prop.Value.GetBoolean(); continue; } + if (prop.NameEquals("reasoning_effort"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + reasoningEffortLevel = new ChatReasoningEffortLevel(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("prediction"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + outputPrediction = null; + continue; + } + outputPrediction = ChatOutputPrediction.DeserializeChatOutputPrediction(prop.Value, options); + continue; + } if (prop.NameEquals("service_tier"u8)) { if (prop.Value.ValueKind == JsonValueKind.Null) @@ -621,6 +683,30 @@ internal static ChatCompletionOptions DeserializeChatCompletionOptions(JsonEleme serviceTier = new InternalCreateChatCompletionRequestServiceTier(prop.Value.GetString()); continue; } + if (prop.NameEquals("modalities"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + List array = new List(); + foreach (var item in prop.Value.EnumerateArray()) + { + array.Add(new InternalCreateChatCompletionRequestModality(item.GetString())); + } + internalModalities = array; + continue; + } + if (prop.NameEquals("audio"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + audioOptions = null; + continue; + } + audioOptions = ChatAudioOptions.DeserializeChatAudioOptions(prop.Value, options); + continue; + } if (true) { additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); @@ -652,7 +738,11 @@ internal static ChatCompletionOptions DeserializeChatCompletionOptions(JsonEleme functions ?? new ChangeTrackingList(), metadata ?? new ChangeTrackingDictionary(), storedOutputEnabled, + reasoningEffortLevel, + outputPrediction, serviceTier, + internalModalities, + audioOptions, additionalBinaryDataProperties); } diff --git a/src/Generated/Models/ChatCompletionOptions.cs b/src/Generated/Models/ChatCompletionOptions.cs index 431b4bed..5dd47d2c 100644 --- a/src/Generated/Models/ChatCompletionOptions.cs +++ b/src/Generated/Models/ChatCompletionOptions.cs @@ -11,7 +11,7 @@ public partial class ChatCompletionOptions { private protected IDictionary _additionalBinaryDataProperties; - internal ChatCompletionOptions(float? frequencyPenalty, float? presencePenalty, ChatResponseFormat responseFormat, float? temperature, float? topP, IList tools, IList messages, InternalCreateChatCompletionRequestModel model, int? n, bool? stream, InternalChatCompletionStreamOptions streamOptions, bool? includeLogProbabilities, int? topLogProbabilityCount, IList stopSequences, IDictionary logitBiases, ChatToolChoice toolChoice, ChatFunctionChoice functionChoice, bool? allowParallelToolCalls, string endUserId, long? seed, int? deprecatedMaxTokens, int? maxOutputTokenCount, IList functions, IDictionary metadata, bool? storedOutputEnabled, InternalCreateChatCompletionRequestServiceTier? serviceTier, IDictionary additionalBinaryDataProperties) + internal ChatCompletionOptions(float? frequencyPenalty, float? presencePenalty, ChatResponseFormat responseFormat, float? temperature, float? topP, IList tools, IList messages, InternalCreateChatCompletionRequestModel model, int? n, bool? stream, InternalChatCompletionStreamOptions streamOptions, bool? includeLogProbabilities, int? topLogProbabilityCount, IList stopSequences, IDictionary logitBiases, ChatToolChoice toolChoice, ChatFunctionChoice functionChoice, bool? allowParallelToolCalls, string endUserId, long? seed, int? deprecatedMaxTokens, int? maxOutputTokenCount, IList functions, IDictionary metadata, bool? storedOutputEnabled, ChatReasoningEffortLevel? reasoningEffortLevel, ChatOutputPrediction outputPrediction, InternalCreateChatCompletionRequestServiceTier? serviceTier, IList internalModalities, ChatAudioOptions audioOptions, IDictionary additionalBinaryDataProperties) { FrequencyPenalty = frequencyPenalty; PresencePenalty = presencePenalty; @@ -38,7 +38,11 @@ internal ChatCompletionOptions(float? frequencyPenalty, float? presencePenalty, Functions = functions; Metadata = metadata; StoredOutputEnabled = storedOutputEnabled; + ReasoningEffortLevel = reasoningEffortLevel; + OutputPrediction = outputPrediction; _serviceTier = serviceTier; + _internalModalities = internalModalities; + _audioOptions = audioOptions; _additionalBinaryDataProperties = additionalBinaryDataProperties; } diff --git a/src/Generated/Models/ChatInputAudioFormat.cs b/src/Generated/Models/ChatInputAudioFormat.cs new file mode 100644 index 00000000..ab86472b --- /dev/null +++ b/src/Generated/Models/ChatInputAudioFormat.cs @@ -0,0 +1,44 @@ +// + +#nullable disable + +using System; +using System.ComponentModel; +using OpenAI; + +namespace OpenAI.Chat +{ + public readonly partial struct ChatInputAudioFormat : IEquatable + { + private readonly string _value; + private const string WavValue = "wav"; + private const string Mp3Value = "mp3"; + + public ChatInputAudioFormat(string value) + { + Argument.AssertNotNull(value, nameof(value)); + + _value = value; + } + + public static ChatInputAudioFormat Wav { get; } = new ChatInputAudioFormat(WavValue); + + public static ChatInputAudioFormat Mp3 { get; } = new ChatInputAudioFormat(Mp3Value); + + public static bool operator ==(ChatInputAudioFormat left, ChatInputAudioFormat right) => left.Equals(right); + + public static bool operator !=(ChatInputAudioFormat left, ChatInputAudioFormat right) => !left.Equals(right); + + public static implicit operator ChatInputAudioFormat(string value) => new ChatInputAudioFormat(value); + + [EditorBrowsable(EditorBrowsableState.Never)] + public override bool Equals(object obj) => obj is ChatInputAudioFormat other && Equals(other); + + public bool Equals(ChatInputAudioFormat 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; + } +} diff --git a/src/Generated/Models/ChatInputTokenUsageDetails.Serialization.cs b/src/Generated/Models/ChatInputTokenUsageDetails.Serialization.cs index 0fac3b93..8b5fb999 100644 --- a/src/Generated/Models/ChatInputTokenUsageDetails.Serialization.cs +++ b/src/Generated/Models/ChatInputTokenUsageDetails.Serialization.cs @@ -13,10 +13,6 @@ namespace OpenAI.Chat { public partial class ChatInputTokenUsageDetails : IJsonModel { - internal ChatInputTokenUsageDetails() - { - } - void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { writer.WriteStartObject(); @@ -88,11 +84,19 @@ internal static ChatInputTokenUsageDetails DeserializeChatInputTokenUsageDetails { if (prop.NameEquals("audio_tokens"u8)) { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } audioTokenCount = prop.Value.GetInt32(); continue; } if (prop.NameEquals("cached_tokens"u8)) { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } cachedTokenCount = prop.Value.GetInt32(); continue; } diff --git a/src/Generated/Models/ChatInputTokenUsageDetails.cs b/src/Generated/Models/ChatInputTokenUsageDetails.cs index 3fc955b5..1b1db2e2 100644 --- a/src/Generated/Models/ChatInputTokenUsageDetails.cs +++ b/src/Generated/Models/ChatInputTokenUsageDetails.cs @@ -11,10 +11,8 @@ public partial class ChatInputTokenUsageDetails { private protected IDictionary _additionalBinaryDataProperties; - internal ChatInputTokenUsageDetails(int audioTokenCount, int cachedTokenCount) + internal ChatInputTokenUsageDetails() { - AudioTokenCount = audioTokenCount; - CachedTokenCount = cachedTokenCount; } internal ChatInputTokenUsageDetails(int audioTokenCount, int cachedTokenCount, IDictionary additionalBinaryDataProperties) diff --git a/src/Generated/Models/ChatMessage.Serialization.cs b/src/Generated/Models/ChatMessage.Serialization.cs index b39d4ef3..3b134ad8 100644 --- a/src/Generated/Models/ChatMessage.Serialization.cs +++ b/src/Generated/Models/ChatMessage.Serialization.cs @@ -20,17 +20,17 @@ protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWrit { throw new FormatException($"The model {nameof(ChatMessage)} does not support writing '{format}' format."); } - if (_additionalBinaryDataProperties?.ContainsKey("role") != true) - { - writer.WritePropertyName("role"u8); - writer.WriteStringValue(Role.ToSerialString()); - } // CUSTOM: Check inner collection is defined. if (true && Optional.IsDefined(Content) && Content.IsInnerCollectionDefined() && _additionalBinaryDataProperties?.ContainsKey("content") != true) { writer.WritePropertyName("content"u8); this.SerializeContentValue(writer, options); } + if (_additionalBinaryDataProperties?.ContainsKey("role") != true) + { + writer.WritePropertyName("role"u8); + writer.WriteStringValue(Role.ToSerialString()); + } if (true && _additionalBinaryDataProperties != null) { foreach (var item in _additionalBinaryDataProperties) @@ -77,6 +77,8 @@ internal static ChatMessage DeserializeChatMessage(JsonElement element, ModelRea { case "system": return SystemChatMessage.DeserializeSystemChatMessage(element, options); + case "developer": + return DeveloperChatMessage.DeserializeDeveloperChatMessage(element, options); case "user": return UserChatMessage.DeserializeUserChatMessage(element, options); case "assistant": diff --git a/src/Generated/Models/ChatMessage.cs b/src/Generated/Models/ChatMessage.cs index 368ee1c8..89391cdf 100644 --- a/src/Generated/Models/ChatMessage.cs +++ b/src/Generated/Models/ChatMessage.cs @@ -11,10 +11,10 @@ public partial class ChatMessage { private protected IDictionary _additionalBinaryDataProperties; - internal ChatMessage(Chat.ChatMessageRole role, ChatMessageContent content, IDictionary additionalBinaryDataProperties) + internal ChatMessage(ChatMessageContent content, Chat.ChatMessageRole role, IDictionary additionalBinaryDataProperties) { - Role = role; Content = content; + Role = role; _additionalBinaryDataProperties = additionalBinaryDataProperties; } diff --git a/src/Generated/Models/ChatMessageRole.Serialization.cs b/src/Generated/Models/ChatMessageRole.Serialization.cs index 55d2b2ea..2063ddd7 100644 --- a/src/Generated/Models/ChatMessageRole.Serialization.cs +++ b/src/Generated/Models/ChatMessageRole.Serialization.cs @@ -11,6 +11,7 @@ internal static partial class ChatMessageRoleExtensions public static string ToSerialString(this Chat.ChatMessageRole value) => value switch { Chat.ChatMessageRole.System => "system", + Chat.ChatMessageRole.Developer => "developer", Chat.ChatMessageRole.User => "user", Chat.ChatMessageRole.Assistant => "assistant", Chat.ChatMessageRole.Tool => "tool", @@ -24,6 +25,10 @@ public static Chat.ChatMessageRole ToChatMessageRole(this string value) { return Chat.ChatMessageRole.System; } + if (StringComparer.OrdinalIgnoreCase.Equals(value, "developer")) + { + return Chat.ChatMessageRole.Developer; + } if (StringComparer.OrdinalIgnoreCase.Equals(value, "user")) { return Chat.ChatMessageRole.User; diff --git a/src/Generated/Models/ChatOutputAudio.Serialization.cs b/src/Generated/Models/ChatOutputAudio.Serialization.cs new file mode 100644 index 00000000..42f31f88 --- /dev/null +++ b/src/Generated/Models/ChatOutputAudio.Serialization.cs @@ -0,0 +1,178 @@ +// + +#nullable disable + +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; +using OpenAI; + +namespace OpenAI.Chat +{ + public partial class ChatOutputAudio : IJsonModel + { + internal ChatOutputAudio() + { + } + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ChatOutputAudio)} does not support writing '{format}' format."); + } + if (_additionalBinaryDataProperties?.ContainsKey("id") != true) + { + writer.WritePropertyName("id"u8); + writer.WriteStringValue(Id); + } + if (_additionalBinaryDataProperties?.ContainsKey("expires_at") != true) + { + writer.WritePropertyName("expires_at"u8); + writer.WriteNumberValue(ExpiresAt, "U"); + } + if (_additionalBinaryDataProperties?.ContainsKey("transcript") != true) + { + writer.WritePropertyName("transcript"u8); + writer.WriteStringValue(Transcript); + } + if (_additionalBinaryDataProperties?.ContainsKey("data") != true) + { + writer.WritePropertyName("data"u8); + writer.WriteBase64StringValue(AudioBytes.ToArray(), "D"); + } + if (true && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + if (ModelSerializationExtensions.IsSentinelValue(item.Value)) + { + continue; + } + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + ChatOutputAudio IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + protected virtual ChatOutputAudio JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ChatOutputAudio)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeChatOutputAudio(document.RootElement, options); + } + + internal static ChatOutputAudio DeserializeChatOutputAudio(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + string id = default; + DateTimeOffset expiresAt = default; + string transcript = default; + BinaryData audioBytes = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("id"u8)) + { + id = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("expires_at"u8)) + { + expiresAt = DateTimeOffset.FromUnixTimeSeconds(prop.Value.GetInt64()); + continue; + } + if (prop.NameEquals("transcript"u8)) + { + transcript = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("data"u8)) + { + audioBytes = BinaryData.FromBytes(prop.Value.GetBytesFromBase64("D")); + continue; + } + if (true) + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ChatOutputAudio(id, expiresAt, transcript, audioBytes, additionalBinaryDataProperties); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(ChatOutputAudio)} does not support writing '{options.Format}' format."); + } + } + + ChatOutputAudio IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + protected virtual ChatOutputAudio PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeChatOutputAudio(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ChatOutputAudio)} does not support reading '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + + public static implicit operator BinaryContent(ChatOutputAudio chatOutputAudio) + { + if (chatOutputAudio == null) + { + return null; + } + return BinaryContent.Create(chatOutputAudio, ModelSerializationExtensions.WireOptions); + } + + public static explicit operator ChatOutputAudio(ClientResult result) + { + using PipelineResponse response = result.GetRawResponse(); + using JsonDocument document = JsonDocument.Parse(response.Content); + return DeserializeChatOutputAudio(document.RootElement, ModelSerializationExtensions.WireOptions); + } + } +} diff --git a/src/Generated/Models/ChatOutputAudio.cs b/src/Generated/Models/ChatOutputAudio.cs new file mode 100644 index 00000000..cf03c955 --- /dev/null +++ b/src/Generated/Models/ChatOutputAudio.cs @@ -0,0 +1,43 @@ +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace OpenAI.Chat +{ + public partial class ChatOutputAudio + { + private protected IDictionary _additionalBinaryDataProperties; + + internal ChatOutputAudio(string id, DateTimeOffset expiresAt, string transcript, BinaryData audioBytes) + { + Id = id; + ExpiresAt = expiresAt; + Transcript = transcript; + AudioBytes = audioBytes; + } + + internal ChatOutputAudio(string id, DateTimeOffset expiresAt, string transcript, BinaryData audioBytes, IDictionary additionalBinaryDataProperties) + { + Id = id; + ExpiresAt = expiresAt; + Transcript = transcript; + AudioBytes = audioBytes; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + public string Id { get; } + + public DateTimeOffset ExpiresAt { get; } + + public string Transcript { get; } + + internal IDictionary SerializedAdditionalRawData + { + get => _additionalBinaryDataProperties; + set => _additionalBinaryDataProperties = value; + } + } +} diff --git a/src/Generated/Models/ChatOutputAudioFormat.cs b/src/Generated/Models/ChatOutputAudioFormat.cs new file mode 100644 index 00000000..bb9b9836 --- /dev/null +++ b/src/Generated/Models/ChatOutputAudioFormat.cs @@ -0,0 +1,53 @@ +// + +#nullable disable + +using System; +using System.ComponentModel; +using OpenAI; + +namespace OpenAI.Chat +{ + public readonly partial struct ChatOutputAudioFormat : IEquatable + { + private readonly string _value; + private const string WavValue = "wav"; + private const string Mp3Value = "mp3"; + private const string FlacValue = "flac"; + private const string OpusValue = "opus"; + private const string Pcm16Value = "pcm16"; + + public ChatOutputAudioFormat(string value) + { + Argument.AssertNotNull(value, nameof(value)); + + _value = value; + } + + public static ChatOutputAudioFormat Wav { get; } = new ChatOutputAudioFormat(WavValue); + + public static ChatOutputAudioFormat Mp3 { get; } = new ChatOutputAudioFormat(Mp3Value); + + public static ChatOutputAudioFormat Flac { get; } = new ChatOutputAudioFormat(FlacValue); + + public static ChatOutputAudioFormat Opus { get; } = new ChatOutputAudioFormat(OpusValue); + + public static ChatOutputAudioFormat Pcm16 { get; } = new ChatOutputAudioFormat(Pcm16Value); + + public static bool operator ==(ChatOutputAudioFormat left, ChatOutputAudioFormat right) => left.Equals(right); + + public static bool operator !=(ChatOutputAudioFormat left, ChatOutputAudioFormat right) => !left.Equals(right); + + public static implicit operator ChatOutputAudioFormat(string value) => new ChatOutputAudioFormat(value); + + [EditorBrowsable(EditorBrowsableState.Never)] + public override bool Equals(object obj) => obj is ChatOutputAudioFormat other && Equals(other); + + public bool Equals(ChatOutputAudioFormat 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; + } +} diff --git a/src/Generated/Models/ChatOutputAudioReference.Serialization.cs b/src/Generated/Models/ChatOutputAudioReference.Serialization.cs new file mode 100644 index 00000000..590c2dd8 --- /dev/null +++ b/src/Generated/Models/ChatOutputAudioReference.Serialization.cs @@ -0,0 +1,145 @@ +// + +#nullable disable + +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; +using OpenAI; + +namespace OpenAI.Chat +{ + public partial class ChatOutputAudioReference : IJsonModel + { + internal ChatOutputAudioReference() + { + } + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ChatOutputAudioReference)} does not support writing '{format}' format."); + } + if (_additionalBinaryDataProperties?.ContainsKey("id") != true) + { + writer.WritePropertyName("id"u8); + writer.WriteStringValue(Id); + } + if (true && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + if (ModelSerializationExtensions.IsSentinelValue(item.Value)) + { + continue; + } + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + ChatOutputAudioReference IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + protected virtual ChatOutputAudioReference JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ChatOutputAudioReference)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeChatOutputAudioReference(document.RootElement, options); + } + + internal static ChatOutputAudioReference DeserializeChatOutputAudioReference(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + string id = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("id"u8)) + { + id = prop.Value.GetString(); + continue; + } + if (true) + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ChatOutputAudioReference(id, additionalBinaryDataProperties); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(ChatOutputAudioReference)} does not support writing '{options.Format}' format."); + } + } + + ChatOutputAudioReference IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + protected virtual ChatOutputAudioReference PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeChatOutputAudioReference(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ChatOutputAudioReference)} does not support reading '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + + public static implicit operator BinaryContent(ChatOutputAudioReference chatOutputAudioReference) + { + if (chatOutputAudioReference == null) + { + return null; + } + return BinaryContent.Create(chatOutputAudioReference, ModelSerializationExtensions.WireOptions); + } + + public static explicit operator ChatOutputAudioReference(ClientResult result) + { + using PipelineResponse response = result.GetRawResponse(); + using JsonDocument document = JsonDocument.Parse(response.Content); + return DeserializeChatOutputAudioReference(document.RootElement, ModelSerializationExtensions.WireOptions); + } + } +} diff --git a/src/Generated/Models/InternalFunctionParameters.cs b/src/Generated/Models/ChatOutputAudioReference.cs similarity index 51% rename from src/Generated/Models/InternalFunctionParameters.cs rename to src/Generated/Models/ChatOutputAudioReference.cs index 67b1a19c..905a1247 100644 --- a/src/Generated/Models/InternalFunctionParameters.cs +++ b/src/Generated/Models/ChatOutputAudioReference.cs @@ -8,21 +8,24 @@ namespace OpenAI.Chat { - internal partial class InternalFunctionParameters + public partial class ChatOutputAudioReference { private protected IDictionary _additionalBinaryDataProperties; - public InternalFunctionParameters() + public ChatOutputAudioReference(string id) { - _additionalBinaryDataProperties = new ChangeTrackingDictionary(); + Argument.AssertNotNull(id, nameof(id)); + + Id = id; } - internal InternalFunctionParameters(IDictionary additionalProperties) + internal ChatOutputAudioReference(string id, IDictionary additionalBinaryDataProperties) { - _additionalBinaryDataProperties = additionalProperties; + Id = id; + _additionalBinaryDataProperties = additionalBinaryDataProperties; } - public IDictionary AdditionalProperties => _additionalBinaryDataProperties; + public string Id { get; } internal IDictionary SerializedAdditionalRawData { diff --git a/src/Generated/Models/ChatOutputAudioVoice.cs b/src/Generated/Models/ChatOutputAudioVoice.cs new file mode 100644 index 00000000..fdaf1c90 --- /dev/null +++ b/src/Generated/Models/ChatOutputAudioVoice.cs @@ -0,0 +1,62 @@ +// + +#nullable disable + +using System; +using System.ComponentModel; +using OpenAI; + +namespace OpenAI.Chat +{ + public readonly partial struct ChatOutputAudioVoice : IEquatable + { + private readonly string _value; + private const string AlloyValue = "alloy"; + private const string AshValue = "ash"; + private const string BalladValue = "ballad"; + private const string CoralValue = "coral"; + private const string EchoValue = "echo"; + private const string SageValue = "sage"; + private const string ShimmerValue = "shimmer"; + private const string VerseValue = "verse"; + + public ChatOutputAudioVoice(string value) + { + Argument.AssertNotNull(value, nameof(value)); + + _value = value; + } + + public static ChatOutputAudioVoice Alloy { get; } = new ChatOutputAudioVoice(AlloyValue); + + public static ChatOutputAudioVoice Ash { get; } = new ChatOutputAudioVoice(AshValue); + + public static ChatOutputAudioVoice Ballad { get; } = new ChatOutputAudioVoice(BalladValue); + + public static ChatOutputAudioVoice Coral { get; } = new ChatOutputAudioVoice(CoralValue); + + public static ChatOutputAudioVoice Echo { get; } = new ChatOutputAudioVoice(EchoValue); + + public static ChatOutputAudioVoice Sage { get; } = new ChatOutputAudioVoice(SageValue); + + public static ChatOutputAudioVoice Shimmer { get; } = new ChatOutputAudioVoice(ShimmerValue); + + public static ChatOutputAudioVoice Verse { get; } = new ChatOutputAudioVoice(VerseValue); + + public static bool operator ==(ChatOutputAudioVoice left, ChatOutputAudioVoice right) => left.Equals(right); + + public static bool operator !=(ChatOutputAudioVoice left, ChatOutputAudioVoice right) => !left.Equals(right); + + public static implicit operator ChatOutputAudioVoice(string value) => new ChatOutputAudioVoice(value); + + [EditorBrowsable(EditorBrowsableState.Never)] + public override bool Equals(object obj) => obj is ChatOutputAudioVoice other && Equals(other); + + public bool Equals(ChatOutputAudioVoice 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; + } +} diff --git a/src/Generated/Models/ChatOutputPrediction.Serialization.cs b/src/Generated/Models/ChatOutputPrediction.Serialization.cs new file mode 100644 index 00000000..ec8e32b7 --- /dev/null +++ b/src/Generated/Models/ChatOutputPrediction.Serialization.cs @@ -0,0 +1,139 @@ +// + +#nullable disable + +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Text.Json; +using OpenAI; + +namespace OpenAI.Chat +{ + [PersistableModelProxy(typeof(InternalUnknownChatOutputPrediction))] + public partial class ChatOutputPrediction : IJsonModel + { + internal ChatOutputPrediction() + { + } + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ChatOutputPrediction)} does not support writing '{format}' format."); + } + if (_additionalBinaryDataProperties?.ContainsKey("type") != true) + { + writer.WritePropertyName("type"u8); + writer.WriteStringValue(Type.ToString()); + } + if (true && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + if (ModelSerializationExtensions.IsSentinelValue(item.Value)) + { + continue; + } + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + ChatOutputPrediction IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + protected virtual ChatOutputPrediction JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ChatOutputPrediction)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeChatOutputPrediction(document.RootElement, options); + } + + internal static ChatOutputPrediction DeserializeChatOutputPrediction(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + if (element.TryGetProperty("type"u8, out JsonElement discriminator)) + { + switch (discriminator.GetString()) + { + case "content": + return InternalChatOutputPredictionContent.DeserializeInternalChatOutputPredictionContent(element, options); + } + } + return InternalUnknownChatOutputPrediction.DeserializeInternalUnknownChatOutputPrediction(element, options); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(ChatOutputPrediction)} does not support writing '{options.Format}' format."); + } + } + + ChatOutputPrediction IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + protected virtual ChatOutputPrediction PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeChatOutputPrediction(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ChatOutputPrediction)} does not support reading '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + + public static implicit operator BinaryContent(ChatOutputPrediction chatOutputPrediction) + { + if (chatOutputPrediction == null) + { + return null; + } + return BinaryContent.Create(chatOutputPrediction, ModelSerializationExtensions.WireOptions); + } + + public static explicit operator ChatOutputPrediction(ClientResult result) + { + using PipelineResponse response = result.GetRawResponse(); + using JsonDocument document = JsonDocument.Parse(response.Content); + return DeserializeChatOutputPrediction(document.RootElement, ModelSerializationExtensions.WireOptions); + } + } +} diff --git a/src/Generated/Models/ChatOutputPrediction.cs b/src/Generated/Models/ChatOutputPrediction.cs new file mode 100644 index 00000000..380f12d3 --- /dev/null +++ b/src/Generated/Models/ChatOutputPrediction.cs @@ -0,0 +1,33 @@ +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace OpenAI.Chat +{ + public partial class ChatOutputPrediction + { + private protected IDictionary _additionalBinaryDataProperties; + + private protected ChatOutputPrediction(InternalChatOutputPredictionKind @type) + { + Type = @type; + } + + internal ChatOutputPrediction(InternalChatOutputPredictionKind @type, IDictionary additionalBinaryDataProperties) + { + Type = @type; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + internal InternalChatOutputPredictionKind Type { get; set; } + + internal IDictionary SerializedAdditionalRawData + { + get => _additionalBinaryDataProperties; + set => _additionalBinaryDataProperties = value; + } + } +} diff --git a/src/Generated/Models/ChatOutputTokenUsageDetails.Serialization.cs b/src/Generated/Models/ChatOutputTokenUsageDetails.Serialization.cs index f6c672ea..12d22dfe 100644 --- a/src/Generated/Models/ChatOutputTokenUsageDetails.Serialization.cs +++ b/src/Generated/Models/ChatOutputTokenUsageDetails.Serialization.cs @@ -13,10 +13,6 @@ namespace OpenAI.Chat { public partial class ChatOutputTokenUsageDetails : IJsonModel { - internal ChatOutputTokenUsageDetails() - { - } - void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { writer.WriteStartObject(); @@ -41,6 +37,16 @@ protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWrit writer.WritePropertyName("audio_tokens"u8); writer.WriteNumberValue(AudioTokenCount); } + if (_additionalBinaryDataProperties?.ContainsKey("accepted_prediction_tokens") != true) + { + writer.WritePropertyName("accepted_prediction_tokens"u8); + writer.WriteNumberValue(AcceptedPredictionTokenCount); + } + if (_additionalBinaryDataProperties?.ContainsKey("rejected_prediction_tokens") != true) + { + writer.WritePropertyName("rejected_prediction_tokens"u8); + writer.WriteNumberValue(RejectedPredictionTokenCount); + } if (true && _additionalBinaryDataProperties != null) { foreach (var item in _additionalBinaryDataProperties) @@ -83,25 +89,53 @@ internal static ChatOutputTokenUsageDetails DeserializeChatOutputTokenUsageDetai } int reasoningTokenCount = default; int audioTokenCount = default; + int acceptedPredictionTokenCount = default; + int rejectedPredictionTokenCount = default; IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); foreach (var prop in element.EnumerateObject()) { if (prop.NameEquals("reasoning_tokens"u8)) { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } reasoningTokenCount = prop.Value.GetInt32(); continue; } if (prop.NameEquals("audio_tokens"u8)) { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } audioTokenCount = prop.Value.GetInt32(); continue; } + if (prop.NameEquals("accepted_prediction_tokens"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + acceptedPredictionTokenCount = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("rejected_prediction_tokens"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + rejectedPredictionTokenCount = prop.Value.GetInt32(); + continue; + } if (true) { additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); } } - return new ChatOutputTokenUsageDetails(reasoningTokenCount, audioTokenCount, additionalBinaryDataProperties); + return new ChatOutputTokenUsageDetails(reasoningTokenCount, audioTokenCount, acceptedPredictionTokenCount, rejectedPredictionTokenCount, additionalBinaryDataProperties); } BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); diff --git a/src/Generated/Models/ChatOutputTokenUsageDetails.cs b/src/Generated/Models/ChatOutputTokenUsageDetails.cs index d6a3d468..15e3f963 100644 --- a/src/Generated/Models/ChatOutputTokenUsageDetails.cs +++ b/src/Generated/Models/ChatOutputTokenUsageDetails.cs @@ -11,16 +11,16 @@ public partial class ChatOutputTokenUsageDetails { private protected IDictionary _additionalBinaryDataProperties; - internal ChatOutputTokenUsageDetails(int reasoningTokenCount, int audioTokenCount) + internal ChatOutputTokenUsageDetails() { - ReasoningTokenCount = reasoningTokenCount; - AudioTokenCount = audioTokenCount; } - internal ChatOutputTokenUsageDetails(int reasoningTokenCount, int audioTokenCount, IDictionary additionalBinaryDataProperties) + internal ChatOutputTokenUsageDetails(int reasoningTokenCount, int audioTokenCount, int acceptedPredictionTokenCount, int rejectedPredictionTokenCount, IDictionary additionalBinaryDataProperties) { ReasoningTokenCount = reasoningTokenCount; AudioTokenCount = audioTokenCount; + AcceptedPredictionTokenCount = acceptedPredictionTokenCount; + RejectedPredictionTokenCount = rejectedPredictionTokenCount; _additionalBinaryDataProperties = additionalBinaryDataProperties; } diff --git a/src/Generated/Models/ChatReasoningEffortLevel.cs b/src/Generated/Models/ChatReasoningEffortLevel.cs new file mode 100644 index 00000000..4055fb2e --- /dev/null +++ b/src/Generated/Models/ChatReasoningEffortLevel.cs @@ -0,0 +1,47 @@ +// + +#nullable disable + +using System; +using System.ComponentModel; +using OpenAI; + +namespace OpenAI.Chat +{ + public readonly partial struct ChatReasoningEffortLevel : IEquatable + { + private readonly string _value; + private const string LowValue = "low"; + private const string MediumValue = "medium"; + private const string HighValue = "high"; + + public ChatReasoningEffortLevel(string value) + { + Argument.AssertNotNull(value, nameof(value)); + + _value = value; + } + + public static ChatReasoningEffortLevel Low { get; } = new ChatReasoningEffortLevel(LowValue); + + public static ChatReasoningEffortLevel Medium { get; } = new ChatReasoningEffortLevel(MediumValue); + + public static ChatReasoningEffortLevel High { get; } = new ChatReasoningEffortLevel(HighValue); + + public static bool operator ==(ChatReasoningEffortLevel left, ChatReasoningEffortLevel right) => left.Equals(right); + + public static bool operator !=(ChatReasoningEffortLevel left, ChatReasoningEffortLevel right) => !left.Equals(right); + + public static implicit operator ChatReasoningEffortLevel(string value) => new ChatReasoningEffortLevel(value); + + [EditorBrowsable(EditorBrowsableState.Never)] + public override bool Equals(object obj) => obj is ChatReasoningEffortLevel other && Equals(other); + + public bool Equals(ChatReasoningEffortLevel 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; + } +} diff --git a/src/Generated/Models/ConversationIncompleteReason.cs b/src/Generated/Models/ConversationIncompleteReason.cs new file mode 100644 index 00000000..16e7c9a9 --- /dev/null +++ b/src/Generated/Models/ConversationIncompleteReason.cs @@ -0,0 +1,50 @@ +// + +#nullable disable + +using System; +using System.ComponentModel; +using OpenAI; + +namespace OpenAI.RealtimeConversation +{ + public readonly partial struct ConversationIncompleteReason : IEquatable + { + private readonly string _value; + private const string TurnDetectedValue = "turn_detected"; + private const string ClientCancelledValue = "client_cancelled"; + private const string MaxOutputTokensValue = "max_output_tokens"; + private const string ContentFilterValue = "content_filter"; + + public ConversationIncompleteReason(string value) + { + Argument.AssertNotNull(value, nameof(value)); + + _value = value; + } + + public static ConversationIncompleteReason TurnDetected { get; } = new ConversationIncompleteReason(TurnDetectedValue); + + public static ConversationIncompleteReason ClientCancelled { get; } = new ConversationIncompleteReason(ClientCancelledValue); + + public static ConversationIncompleteReason MaxOutputTokens { get; } = new ConversationIncompleteReason(MaxOutputTokensValue); + + public static ConversationIncompleteReason ContentFilter { get; } = new ConversationIncompleteReason(ContentFilterValue); + + public static bool operator ==(ConversationIncompleteReason left, ConversationIncompleteReason right) => left.Equals(right); + + public static bool operator !=(ConversationIncompleteReason left, ConversationIncompleteReason right) => !left.Equals(right); + + public static implicit operator ConversationIncompleteReason(string value) => new ConversationIncompleteReason(value); + + [EditorBrowsable(EditorBrowsableState.Never)] + public override bool Equals(object obj) => obj is ConversationIncompleteReason other && Equals(other); + + public bool Equals(ConversationIncompleteReason 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; + } +} diff --git a/src/Generated/Models/ConversationInputTokenUsageDetails.Serialization.cs b/src/Generated/Models/ConversationInputTokenUsageDetails.Serialization.cs index ca18ed51..f5902b67 100644 --- a/src/Generated/Models/ConversationInputTokenUsageDetails.Serialization.cs +++ b/src/Generated/Models/ConversationInputTokenUsageDetails.Serialization.cs @@ -13,10 +13,6 @@ namespace OpenAI.RealtimeConversation { public partial class ConversationInputTokenUsageDetails : IJsonModel { - internal ConversationInputTokenUsageDetails() - { - } - void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { writer.WriteStartObject(); @@ -31,20 +27,20 @@ protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWrit { throw new FormatException($"The model {nameof(ConversationInputTokenUsageDetails)} does not support writing '{format}' format."); } + if (_additionalBinaryDataProperties?.ContainsKey("audio_tokens") != true) + { + writer.WritePropertyName("audio_tokens"u8); + writer.WriteNumberValue(AudioTokenCount); + } if (_additionalBinaryDataProperties?.ContainsKey("cached_tokens") != true) { writer.WritePropertyName("cached_tokens"u8); - writer.WriteNumberValue(CachedTokens); + writer.WriteNumberValue(CachedTokenCount); } if (_additionalBinaryDataProperties?.ContainsKey("text_tokens") != true) { writer.WritePropertyName("text_tokens"u8); - writer.WriteNumberValue(TextTokens); - } - if (_additionalBinaryDataProperties?.ContainsKey("audio_tokens") != true) - { - writer.WritePropertyName("audio_tokens"u8); - writer.WriteNumberValue(AudioTokens); + writer.WriteNumberValue(TextTokenCount); } if (true && _additionalBinaryDataProperties != null) { @@ -86,25 +82,37 @@ internal static ConversationInputTokenUsageDetails DeserializeConversationInputT { return null; } - int cachedTokens = default; - int textTokens = default; - int audioTokens = default; + int audioTokenCount = default; + int cachedTokenCount = default; + int textTokenCount = default; IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); foreach (var prop in element.EnumerateObject()) { - if (prop.NameEquals("cached_tokens"u8)) + if (prop.NameEquals("audio_tokens"u8)) { - cachedTokens = prop.Value.GetInt32(); + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + audioTokenCount = prop.Value.GetInt32(); continue; } - if (prop.NameEquals("text_tokens"u8)) + if (prop.NameEquals("cached_tokens"u8)) { - textTokens = prop.Value.GetInt32(); + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + cachedTokenCount = prop.Value.GetInt32(); continue; } - if (prop.NameEquals("audio_tokens"u8)) + if (prop.NameEquals("text_tokens"u8)) { - audioTokens = prop.Value.GetInt32(); + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + textTokenCount = prop.Value.GetInt32(); continue; } if (true) @@ -112,7 +120,7 @@ internal static ConversationInputTokenUsageDetails DeserializeConversationInputT additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); } } - return new ConversationInputTokenUsageDetails(cachedTokens, textTokens, audioTokens, additionalBinaryDataProperties); + return new ConversationInputTokenUsageDetails(audioTokenCount, cachedTokenCount, textTokenCount, additionalBinaryDataProperties); } BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); diff --git a/src/Generated/Models/ConversationInputTokenUsageDetails.cs b/src/Generated/Models/ConversationInputTokenUsageDetails.cs index d22b0020..277871f6 100644 --- a/src/Generated/Models/ConversationInputTokenUsageDetails.cs +++ b/src/Generated/Models/ConversationInputTokenUsageDetails.cs @@ -11,27 +11,18 @@ public partial class ConversationInputTokenUsageDetails { private protected IDictionary _additionalBinaryDataProperties; - internal ConversationInputTokenUsageDetails(int cachedTokens, int textTokens, int audioTokens) + internal ConversationInputTokenUsageDetails() { - CachedTokens = cachedTokens; - TextTokens = textTokens; - AudioTokens = audioTokens; } - internal ConversationInputTokenUsageDetails(int cachedTokens, int textTokens, int audioTokens, IDictionary additionalBinaryDataProperties) + internal ConversationInputTokenUsageDetails(int audioTokenCount, int cachedTokenCount, int textTokenCount, IDictionary additionalBinaryDataProperties) { - CachedTokens = cachedTokens; - TextTokens = textTokens; - AudioTokens = audioTokens; + AudioTokenCount = audioTokenCount; + CachedTokenCount = cachedTokenCount; + TextTokenCount = textTokenCount; _additionalBinaryDataProperties = additionalBinaryDataProperties; } - public int CachedTokens { get; } - - public int TextTokens { get; } - - public int AudioTokens { get; } - internal IDictionary SerializedAdditionalRawData { get => _additionalBinaryDataProperties; diff --git a/src/Generated/Models/ConversationItemCreatedUpdate.Serialization.cs b/src/Generated/Models/ConversationItemCreatedUpdate.Serialization.cs index 57384093..62b71004 100644 --- a/src/Generated/Models/ConversationItemCreatedUpdate.Serialization.cs +++ b/src/Generated/Models/ConversationItemCreatedUpdate.Serialization.cs @@ -40,7 +40,7 @@ protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWri if (_additionalBinaryDataProperties?.ContainsKey("item") != true) { writer.WritePropertyName("item"u8); - writer.WriteObjectValue(_internalItem, options); + writer.WriteObjectValue(_internalItem, options); } } @@ -67,7 +67,7 @@ internal static ConversationItemCreatedUpdate DeserializeConversationItemCreated RealtimeConversation.ConversationUpdateKind kind = default; IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); string previousItemId = default; - InternalRealtimeResponseItem internalItem = default; + InternalRealtimeConversationResponseItem internalItem = default; foreach (var prop in element.EnumerateObject()) { if (prop.NameEquals("event_id"u8)) @@ -87,7 +87,7 @@ internal static ConversationItemCreatedUpdate DeserializeConversationItemCreated } if (prop.NameEquals("item"u8)) { - internalItem = InternalRealtimeResponseItem.DeserializeInternalRealtimeResponseItem(prop.Value, options); + internalItem = InternalRealtimeConversationResponseItem.DeserializeInternalRealtimeConversationResponseItem(prop.Value, options); continue; } if (true) diff --git a/src/Generated/Models/ConversationItemCreatedUpdate.cs b/src/Generated/Models/ConversationItemCreatedUpdate.cs index ea9d33b3..23da0c64 100644 --- a/src/Generated/Models/ConversationItemCreatedUpdate.cs +++ b/src/Generated/Models/ConversationItemCreatedUpdate.cs @@ -9,13 +9,13 @@ namespace OpenAI.RealtimeConversation { public partial class ConversationItemCreatedUpdate : ConversationUpdate { - internal ConversationItemCreatedUpdate(string eventId, string previousItemId, InternalRealtimeResponseItem internalItem) : base(eventId, RealtimeConversation.ConversationUpdateKind.ItemCreated) + internal ConversationItemCreatedUpdate(string eventId, string previousItemId, InternalRealtimeConversationResponseItem internalItem) : base(eventId, RealtimeConversation.ConversationUpdateKind.ItemCreated) { PreviousItemId = previousItemId; _internalItem = internalItem; } - internal ConversationItemCreatedUpdate(string eventId, RealtimeConversation.ConversationUpdateKind kind, IDictionary additionalBinaryDataProperties, string previousItemId, InternalRealtimeResponseItem internalItem) : base(eventId, kind, additionalBinaryDataProperties) + internal ConversationItemCreatedUpdate(string eventId, RealtimeConversation.ConversationUpdateKind kind, IDictionary additionalBinaryDataProperties, string previousItemId, InternalRealtimeConversationResponseItem internalItem) : base(eventId, kind, additionalBinaryDataProperties) { PreviousItemId = previousItemId; _internalItem = internalItem; diff --git a/src/Generated/Models/ConversationItemStreamingFinishedUpdate.Serialization.cs b/src/Generated/Models/ConversationItemStreamingFinishedUpdate.Serialization.cs index 2fc54519..6709cf10 100644 --- a/src/Generated/Models/ConversationItemStreamingFinishedUpdate.Serialization.cs +++ b/src/Generated/Models/ConversationItemStreamingFinishedUpdate.Serialization.cs @@ -45,7 +45,7 @@ protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWri if (_additionalBinaryDataProperties?.ContainsKey("item") != true) { writer.WritePropertyName("item"u8); - writer.WriteObjectValue(_internalItem, options); + writer.WriteObjectValue(_internalItem, options); } } @@ -73,7 +73,7 @@ internal static ConversationItemStreamingFinishedUpdate DeserializeConversationI IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); string responseId = default; int outputIndex = default; - InternalRealtimeResponseItem internalItem = default; + InternalRealtimeConversationResponseItem internalItem = default; foreach (var prop in element.EnumerateObject()) { if (prop.NameEquals("event_id"u8)) @@ -98,7 +98,7 @@ internal static ConversationItemStreamingFinishedUpdate DeserializeConversationI } if (prop.NameEquals("item"u8)) { - internalItem = InternalRealtimeResponseItem.DeserializeInternalRealtimeResponseItem(prop.Value, options); + internalItem = InternalRealtimeConversationResponseItem.DeserializeInternalRealtimeConversationResponseItem(prop.Value, options); continue; } if (true) diff --git a/src/Generated/Models/ConversationItemStreamingFinishedUpdate.cs b/src/Generated/Models/ConversationItemStreamingFinishedUpdate.cs index a178fe40..ab9cf68c 100644 --- a/src/Generated/Models/ConversationItemStreamingFinishedUpdate.cs +++ b/src/Generated/Models/ConversationItemStreamingFinishedUpdate.cs @@ -9,14 +9,14 @@ namespace OpenAI.RealtimeConversation { public partial class ConversationItemStreamingFinishedUpdate : ConversationUpdate { - internal ConversationItemStreamingFinishedUpdate(string eventId, string responseId, int outputIndex, InternalRealtimeResponseItem internalItem) : base(eventId, RealtimeConversation.ConversationUpdateKind.ItemStreamingFinished) + internal ConversationItemStreamingFinishedUpdate(string eventId, string responseId, int outputIndex, InternalRealtimeConversationResponseItem internalItem) : base(eventId, RealtimeConversation.ConversationUpdateKind.ItemStreamingFinished) { ResponseId = responseId; OutputIndex = outputIndex; _internalItem = internalItem; } - internal ConversationItemStreamingFinishedUpdate(string eventId, RealtimeConversation.ConversationUpdateKind kind, IDictionary additionalBinaryDataProperties, string responseId, int outputIndex, InternalRealtimeResponseItem internalItem) : base(eventId, kind, additionalBinaryDataProperties) + internal ConversationItemStreamingFinishedUpdate(string eventId, RealtimeConversation.ConversationUpdateKind kind, IDictionary additionalBinaryDataProperties, string responseId, int outputIndex, InternalRealtimeConversationResponseItem internalItem) : base(eventId, kind, additionalBinaryDataProperties) { ResponseId = responseId; OutputIndex = outputIndex; diff --git a/src/Generated/Models/ConversationItemStreamingStartedUpdate.Serialization.cs b/src/Generated/Models/ConversationItemStreamingStartedUpdate.Serialization.cs index e0e22703..61d947d1 100644 --- a/src/Generated/Models/ConversationItemStreamingStartedUpdate.Serialization.cs +++ b/src/Generated/Models/ConversationItemStreamingStartedUpdate.Serialization.cs @@ -45,7 +45,7 @@ protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWri if (_additionalBinaryDataProperties?.ContainsKey("item") != true) { writer.WritePropertyName("item"u8); - writer.WriteObjectValue(_internalItem, options); + writer.WriteObjectValue(_internalItem, options); } } @@ -73,7 +73,7 @@ internal static ConversationItemStreamingStartedUpdate DeserializeConversationIt IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); string responseId = default; int itemIndex = default; - InternalRealtimeResponseItem internalItem = default; + InternalRealtimeConversationResponseItem internalItem = default; foreach (var prop in element.EnumerateObject()) { if (prop.NameEquals("event_id"u8)) @@ -98,7 +98,7 @@ internal static ConversationItemStreamingStartedUpdate DeserializeConversationIt } if (prop.NameEquals("item"u8)) { - internalItem = InternalRealtimeResponseItem.DeserializeInternalRealtimeResponseItem(prop.Value, options); + internalItem = InternalRealtimeConversationResponseItem.DeserializeInternalRealtimeConversationResponseItem(prop.Value, options); continue; } if (true) diff --git a/src/Generated/Models/ConversationItemStreamingStartedUpdate.cs b/src/Generated/Models/ConversationItemStreamingStartedUpdate.cs index 227fad3f..ddb0b6e6 100644 --- a/src/Generated/Models/ConversationItemStreamingStartedUpdate.cs +++ b/src/Generated/Models/ConversationItemStreamingStartedUpdate.cs @@ -9,14 +9,14 @@ namespace OpenAI.RealtimeConversation { public partial class ConversationItemStreamingStartedUpdate : ConversationUpdate { - internal ConversationItemStreamingStartedUpdate(string eventId, string responseId, int itemIndex, InternalRealtimeResponseItem internalItem) : base(eventId, RealtimeConversation.ConversationUpdateKind.ItemStreamingStarted) + internal ConversationItemStreamingStartedUpdate(string eventId, string responseId, int itemIndex, InternalRealtimeConversationResponseItem internalItem) : base(eventId, RealtimeConversation.ConversationUpdateKind.ItemStreamingStarted) { ResponseId = responseId; ItemIndex = itemIndex; _internalItem = internalItem; } - internal ConversationItemStreamingStartedUpdate(string eventId, RealtimeConversation.ConversationUpdateKind kind, IDictionary additionalBinaryDataProperties, string responseId, int itemIndex, InternalRealtimeResponseItem internalItem) : base(eventId, kind, additionalBinaryDataProperties) + internal ConversationItemStreamingStartedUpdate(string eventId, RealtimeConversation.ConversationUpdateKind kind, IDictionary additionalBinaryDataProperties, string responseId, int itemIndex, InternalRealtimeConversationResponseItem internalItem) : base(eventId, kind, additionalBinaryDataProperties) { ResponseId = responseId; ItemIndex = itemIndex; diff --git a/src/Generated/Models/ConversationOutputTokenUsageDetails.Serialization.cs b/src/Generated/Models/ConversationOutputTokenUsageDetails.Serialization.cs index 35403bdb..9661ae7f 100644 --- a/src/Generated/Models/ConversationOutputTokenUsageDetails.Serialization.cs +++ b/src/Generated/Models/ConversationOutputTokenUsageDetails.Serialization.cs @@ -13,10 +13,6 @@ namespace OpenAI.RealtimeConversation { public partial class ConversationOutputTokenUsageDetails : IJsonModel { - internal ConversationOutputTokenUsageDetails() - { - } - void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { writer.WriteStartObject(); @@ -34,12 +30,12 @@ protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWrit if (_additionalBinaryDataProperties?.ContainsKey("text_tokens") != true) { writer.WritePropertyName("text_tokens"u8); - writer.WriteNumberValue(TextTokens); + writer.WriteNumberValue(TextTokenCount); } if (_additionalBinaryDataProperties?.ContainsKey("audio_tokens") != true) { writer.WritePropertyName("audio_tokens"u8); - writer.WriteNumberValue(AudioTokens); + writer.WriteNumberValue(AudioTokenCount); } if (true && _additionalBinaryDataProperties != null) { @@ -81,19 +77,27 @@ internal static ConversationOutputTokenUsageDetails DeserializeConversationOutpu { return null; } - int textTokens = default; - int audioTokens = default; + int textTokenCount = default; + int audioTokenCount = default; IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); foreach (var prop in element.EnumerateObject()) { if (prop.NameEquals("text_tokens"u8)) { - textTokens = prop.Value.GetInt32(); + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + textTokenCount = prop.Value.GetInt32(); continue; } if (prop.NameEquals("audio_tokens"u8)) { - audioTokens = prop.Value.GetInt32(); + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + audioTokenCount = prop.Value.GetInt32(); continue; } if (true) @@ -101,7 +105,7 @@ internal static ConversationOutputTokenUsageDetails DeserializeConversationOutpu additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); } } - return new ConversationOutputTokenUsageDetails(textTokens, audioTokens, additionalBinaryDataProperties); + return new ConversationOutputTokenUsageDetails(textTokenCount, audioTokenCount, additionalBinaryDataProperties); } BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); diff --git a/src/Generated/Models/ConversationOutputTokenUsageDetails.cs b/src/Generated/Models/ConversationOutputTokenUsageDetails.cs index 0a424ead..0fa593dc 100644 --- a/src/Generated/Models/ConversationOutputTokenUsageDetails.cs +++ b/src/Generated/Models/ConversationOutputTokenUsageDetails.cs @@ -11,23 +11,17 @@ public partial class ConversationOutputTokenUsageDetails { private protected IDictionary _additionalBinaryDataProperties; - internal ConversationOutputTokenUsageDetails(int textTokens, int audioTokens) + internal ConversationOutputTokenUsageDetails() { - TextTokens = textTokens; - AudioTokens = audioTokens; } - internal ConversationOutputTokenUsageDetails(int textTokens, int audioTokens, IDictionary additionalBinaryDataProperties) + internal ConversationOutputTokenUsageDetails(int textTokenCount, int audioTokenCount, IDictionary additionalBinaryDataProperties) { - TextTokens = textTokens; - AudioTokens = audioTokens; + TextTokenCount = textTokenCount; + AudioTokenCount = audioTokenCount; _additionalBinaryDataProperties = additionalBinaryDataProperties; } - public int TextTokens { get; } - - public int AudioTokens { get; } - internal IDictionary SerializedAdditionalRawData { get => _additionalBinaryDataProperties; diff --git a/src/Generated/Models/ConversationResponseOptions.Serialization.cs b/src/Generated/Models/ConversationResponseOptions.Serialization.cs new file mode 100644 index 00000000..e7772a67 --- /dev/null +++ b/src/Generated/Models/ConversationResponseOptions.Serialization.cs @@ -0,0 +1,363 @@ +// + +#nullable disable + +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; +using OpenAI; + +namespace OpenAI.RealtimeConversation +{ + public partial class ConversationResponseOptions : IJsonModel + { + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ConversationResponseOptions)} does not support writing '{format}' format."); + } + if (Optional.IsDefined(Instructions) && _additionalBinaryDataProperties?.ContainsKey("instructions") != true) + { + writer.WritePropertyName("instructions"u8); + writer.WriteStringValue(Instructions); + } + if (Optional.IsDefined(Voice) && _additionalBinaryDataProperties?.ContainsKey("voice") != true) + { + writer.WritePropertyName("voice"u8); + writer.WriteStringValue(Voice.Value.ToString()); + } + if (Optional.IsDefined(OutputAudioFormat) && _additionalBinaryDataProperties?.ContainsKey("output_audio_format") != true) + { + writer.WritePropertyName("output_audio_format"u8); + writer.WriteStringValue(OutputAudioFormat.Value.ToString()); + } + if (Optional.IsCollectionDefined(Tools) && _additionalBinaryDataProperties?.ContainsKey("tools") != true) + { + writer.WritePropertyName("tools"u8); + writer.WriteStartArray(); + foreach (ConversationTool item in Tools) + { + writer.WriteObjectValue(item, options); + } + writer.WriteEndArray(); + } + if (Optional.IsDefined(Temperature) && _additionalBinaryDataProperties?.ContainsKey("temperature") != true) + { + writer.WritePropertyName("temperature"u8); + writer.WriteNumberValue(Temperature.Value); + } + if (Optional.IsCollectionDefined(Metadata) && _additionalBinaryDataProperties?.ContainsKey("metadata") != true) + { + writer.WritePropertyName("metadata"u8); + writer.WriteStartObject(); + foreach (var item in Metadata) + { + writer.WritePropertyName(item.Key); + if (item.Value == null) + { + writer.WriteNullValue(); + continue; + } + writer.WriteStringValue(item.Value); + } + writer.WriteEndObject(); + } + if (Optional.IsDefined(ConversationSelection) && _additionalBinaryDataProperties?.ContainsKey("conversation") != true) + { + writer.WritePropertyName("conversation"u8); + writer.WriteStringValue(ConversationSelection.Value.ToString()); + } + if (Optional.IsDefined(MaxOutputTokens) && _additionalBinaryDataProperties?.ContainsKey("max_output_tokens") != true) + { + writer.WritePropertyName("max_output_tokens"u8); + writer.WriteObjectValue(MaxOutputTokens, options); + } + if (Optional.IsCollectionDefined(OverrideItems) && _additionalBinaryDataProperties?.ContainsKey("input") != true) + { + writer.WritePropertyName("input"u8); + writer.WriteStartArray(); + foreach (ConversationItem item in OverrideItems) + { + writer.WriteObjectValue(item, options); + } + writer.WriteEndArray(); + } + if (Optional.IsCollectionDefined(_internalModalities) && _additionalBinaryDataProperties?.ContainsKey("modalities") != true) + { + writer.WritePropertyName("modalities"u8); + writer.WriteStartArray(); + foreach (InternalRealtimeRequestSessionModality item in _internalModalities) + { + writer.WriteStringValue(item.ToString()); + } + writer.WriteEndArray(); + } + if (Optional.IsDefined(_internalToolChoice) && _additionalBinaryDataProperties?.ContainsKey("tool_choice") != true) + { + writer.WritePropertyName("tool_choice"u8); +#if NET6_0_OR_GREATER + writer.WriteRawValue(_internalToolChoice); +#else + using (JsonDocument document = JsonDocument.Parse(_internalToolChoice)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + if (true && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + if (ModelSerializationExtensions.IsSentinelValue(item.Value)) + { + continue; + } + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + ConversationResponseOptions IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + protected virtual ConversationResponseOptions JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ConversationResponseOptions)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeConversationResponseOptions(document.RootElement, options); + } + + internal static ConversationResponseOptions DeserializeConversationResponseOptions(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + string instructions = default; + ConversationVoice? voice = default; + ConversationAudioFormat? outputAudioFormat = default; + IList tools = default; + float? temperature = default; + IDictionary metadata = default; + ResponseConversationSelection? conversationSelection = default; + RealtimeConversation.ConversationMaxTokensChoice maxOutputTokens = default; + IList overrideItems = default; + IList internalModalities = default; + BinaryData internalToolChoice = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("instructions"u8)) + { + instructions = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("voice"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + voice = new ConversationVoice(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("output_audio_format"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + outputAudioFormat = new ConversationAudioFormat(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("tools"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + List array = new List(); + foreach (var item in prop.Value.EnumerateArray()) + { + array.Add(ConversationTool.DeserializeConversationTool(item, options)); + } + tools = array; + continue; + } + if (prop.NameEquals("temperature"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + temperature = prop.Value.GetSingle(); + continue; + } + if (prop.NameEquals("metadata"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + Dictionary dictionary = new Dictionary(); + foreach (var prop0 in prop.Value.EnumerateObject()) + { + if (prop0.Value.ValueKind == JsonValueKind.Null) + { + dictionary.Add(prop0.Name, null); + } + else + { + dictionary.Add(prop0.Name, prop0.Value.GetString()); + } + } + metadata = dictionary; + continue; + } + if (prop.NameEquals("conversation"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + conversationSelection = new ResponseConversationSelection(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("max_output_tokens"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + maxOutputTokens = RealtimeConversation.ConversationMaxTokensChoice.DeserializeConversationMaxTokensChoice(prop.Value, options); + continue; + } + if (prop.NameEquals("input"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + List array = new List(); + foreach (var item in prop.Value.EnumerateArray()) + { + array.Add(ConversationItem.DeserializeConversationItem(item, options)); + } + overrideItems = array; + continue; + } + if (prop.NameEquals("modalities"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + List array = new List(); + foreach (var item in prop.Value.EnumerateArray()) + { + array.Add(new InternalRealtimeRequestSessionModality(item.GetString())); + } + internalModalities = array; + continue; + } + if (prop.NameEquals("tool_choice"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + internalToolChoice = BinaryData.FromString(prop.Value.GetRawText()); + continue; + } + if (true) + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ConversationResponseOptions( + instructions, + voice, + outputAudioFormat, + tools ?? new ChangeTrackingList(), + temperature, + metadata ?? new ChangeTrackingDictionary(), + conversationSelection, + maxOutputTokens, + overrideItems ?? new ChangeTrackingList(), + internalModalities, + internalToolChoice, + additionalBinaryDataProperties); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(ConversationResponseOptions)} does not support writing '{options.Format}' format."); + } + } + + ConversationResponseOptions IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + protected virtual ConversationResponseOptions PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeConversationResponseOptions(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ConversationResponseOptions)} does not support reading '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + + public static implicit operator BinaryContent(ConversationResponseOptions conversationResponseOptions) + { + if (conversationResponseOptions == null) + { + return null; + } + return BinaryContent.Create(conversationResponseOptions, ModelSerializationExtensions.WireOptions); + } + + public static explicit operator ConversationResponseOptions(ClientResult result) + { + using PipelineResponse response = result.GetRawResponse(); + using JsonDocument document = JsonDocument.Parse(response.Content); + return DeserializeConversationResponseOptions(document.RootElement, ModelSerializationExtensions.WireOptions); + } + } +} diff --git a/src/Generated/Models/ConversationResponseOptions.cs b/src/Generated/Models/ConversationResponseOptions.cs new file mode 100644 index 00000000..bf44530b --- /dev/null +++ b/src/Generated/Models/ConversationResponseOptions.cs @@ -0,0 +1,57 @@ +// + +#nullable disable + +using System; +using System.Collections.Generic; +using OpenAI; + +namespace OpenAI.RealtimeConversation +{ + public partial class ConversationResponseOptions + { + private protected IDictionary _additionalBinaryDataProperties; + + public ConversationResponseOptions() + { + Tools = new ChangeTrackingList(); + Metadata = new ChangeTrackingDictionary(); + OverrideItems = new ChangeTrackingList(); + _internalModalities = new ChangeTrackingList(); + } + + internal ConversationResponseOptions(string instructions, ConversationVoice? voice, ConversationAudioFormat? outputAudioFormat, IList tools, float? temperature, IDictionary metadata, ResponseConversationSelection? conversationSelection, RealtimeConversation.ConversationMaxTokensChoice maxOutputTokens, IList overrideItems, IList internalModalities, BinaryData internalToolChoice, IDictionary additionalBinaryDataProperties) + { + Instructions = instructions; + Voice = voice; + OutputAudioFormat = outputAudioFormat; + Tools = tools; + Temperature = temperature; + Metadata = metadata; + ConversationSelection = conversationSelection; + MaxOutputTokens = maxOutputTokens; + OverrideItems = overrideItems; + _internalModalities = internalModalities; + _internalToolChoice = internalToolChoice; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + public string Instructions { get; set; } + + public ConversationVoice? Voice { get; set; } + + public ConversationAudioFormat? OutputAudioFormat { get; set; } + + public IList Tools { get; } + + public float? Temperature { get; set; } + + public IDictionary Metadata { get; } + + internal IDictionary SerializedAdditionalRawData + { + get => _additionalBinaryDataProperties; + set => _additionalBinaryDataProperties = value; + } + } +} diff --git a/src/Generated/Models/ConversationSessionOptions.Serialization.cs b/src/Generated/Models/ConversationSessionOptions.Serialization.cs index 4a25c88a..b02b97b3 100644 --- a/src/Generated/Models/ConversationSessionOptions.Serialization.cs +++ b/src/Generated/Models/ConversationSessionOptions.Serialization.cs @@ -62,6 +62,11 @@ protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWrit writer.WritePropertyName("temperature"u8); writer.WriteNumberValue(Temperature.Value); } + if (Optional.IsDefined(Model) && _additionalBinaryDataProperties?.ContainsKey("model") != true) + { + writer.WritePropertyName("model"u8); + writer.WriteStringValue(Model.Value.ToString()); + } if (Optional.IsDefined(TurnDetectionOptions) && _additionalBinaryDataProperties?.ContainsKey("turn_detection") != true) { if (TurnDetectionOptions != null) @@ -166,6 +171,7 @@ internal static ConversationSessionOptions DeserializeConversationSessionOptions ConversationAudioFormat? outputAudioFormat = default; IList tools = default; float? temperature = default; + InternalRealtimeRequestSessionModel? model = default; ConversationTurnDetectionOptions turnDetectionOptions = default; ConversationInputTranscriptionOptions inputTranscriptionOptions = default; IList internalModalities = default; @@ -229,6 +235,15 @@ internal static ConversationSessionOptions DeserializeConversationSessionOptions temperature = prop.Value.GetSingle(); continue; } + if (prop.NameEquals("model"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + model = new InternalRealtimeRequestSessionModel(prop.Value.GetString()); + continue; + } if (prop.NameEquals("turn_detection"u8)) { if (prop.Value.ValueKind == JsonValueKind.Null) @@ -293,6 +308,7 @@ internal static ConversationSessionOptions DeserializeConversationSessionOptions outputAudioFormat, tools ?? new ChangeTrackingList(), temperature, + model, turnDetectionOptions, inputTranscriptionOptions, internalModalities, diff --git a/src/Generated/Models/ConversationSessionOptions.cs b/src/Generated/Models/ConversationSessionOptions.cs index 7cf4e0ef..7bdfebf0 100644 --- a/src/Generated/Models/ConversationSessionOptions.cs +++ b/src/Generated/Models/ConversationSessionOptions.cs @@ -18,7 +18,7 @@ public ConversationSessionOptions() _internalModalities = new ChangeTrackingList(); } - internal ConversationSessionOptions(string instructions, ConversationVoice? voice, ConversationAudioFormat? inputAudioFormat, ConversationAudioFormat? outputAudioFormat, IList tools, float? temperature, ConversationTurnDetectionOptions turnDetectionOptions, ConversationInputTranscriptionOptions inputTranscriptionOptions, IList internalModalities, BinaryData internalToolChoice, BinaryData maxResponseOutputTokens, IDictionary additionalBinaryDataProperties) + internal ConversationSessionOptions(string instructions, ConversationVoice? voice, ConversationAudioFormat? inputAudioFormat, ConversationAudioFormat? outputAudioFormat, IList tools, float? temperature, InternalRealtimeRequestSessionModel? model, ConversationTurnDetectionOptions turnDetectionOptions, ConversationInputTranscriptionOptions inputTranscriptionOptions, IList internalModalities, BinaryData internalToolChoice, BinaryData maxResponseOutputTokens, IDictionary additionalBinaryDataProperties) { Instructions = instructions; Voice = voice; @@ -26,6 +26,7 @@ internal ConversationSessionOptions(string instructions, ConversationVoice? voic OutputAudioFormat = outputAudioFormat; Tools = tools; Temperature = temperature; + Model = model; TurnDetectionOptions = turnDetectionOptions; InputTranscriptionOptions = inputTranscriptionOptions; _internalModalities = internalModalities; diff --git a/src/Generated/Models/ConversationStatus.cs b/src/Generated/Models/ConversationStatus.cs index d08d9ebb..23700eb5 100644 --- a/src/Generated/Models/ConversationStatus.cs +++ b/src/Generated/Models/ConversationStatus.cs @@ -11,11 +11,10 @@ namespace OpenAI.RealtimeConversation public readonly partial struct ConversationStatus : IEquatable { private readonly string _value; - private const string InProgressValue = "in_progress"; private const string CompletedValue = "completed"; private const string CancelledValue = "cancelled"; - private const string IncompleteValue = "incomplete"; private const string FailedValue = "failed"; + private const string IncompleteValue = "incomplete"; public ConversationStatus(string value) { @@ -24,16 +23,14 @@ public ConversationStatus(string value) _value = value; } - public static ConversationStatus InProgress { get; } = new ConversationStatus(InProgressValue); - public static ConversationStatus Completed { get; } = new ConversationStatus(CompletedValue); public static ConversationStatus Cancelled { get; } = new ConversationStatus(CancelledValue); - public static ConversationStatus Incomplete { get; } = new ConversationStatus(IncompleteValue); - public static ConversationStatus Failed { get; } = new ConversationStatus(FailedValue); + public static ConversationStatus Incomplete { get; } = new ConversationStatus(IncompleteValue); + public static bool operator ==(ConversationStatus left, ConversationStatus right) => left.Equals(right); public static bool operator !=(ConversationStatus left, ConversationStatus right) => !left.Equals(right); diff --git a/src/Generated/Models/ConversationStatusDetails.Serialization.cs b/src/Generated/Models/ConversationStatusDetails.Serialization.cs index 7aabd501..7a9aaff7 100644 --- a/src/Generated/Models/ConversationStatusDetails.Serialization.cs +++ b/src/Generated/Models/ConversationStatusDetails.Serialization.cs @@ -5,18 +5,14 @@ using System; using System.ClientModel; using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using OpenAI; namespace OpenAI.RealtimeConversation { - [PersistableModelProxy(typeof(UnknownRealtimeResponseStatusDetails))] - public abstract partial class ConversationStatusDetails : IJsonModel + public partial class ConversationStatusDetails : IJsonModel { - internal ConversationStatusDetails() - { - } - void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { writer.WriteStartObject(); @@ -36,6 +32,16 @@ protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWrit writer.WritePropertyName("type"u8); writer.WriteStringValue(StatusKind.ToString()); } + if (Optional.IsDefined(IncompleteReason) && _additionalBinaryDataProperties?.ContainsKey("reason") != true) + { + writer.WritePropertyName("reason"u8); + writer.WriteStringValue(IncompleteReason.Value.ToString()); + } + if (Optional.IsDefined(Error) && _additionalBinaryDataProperties?.ContainsKey("error") != true) + { + writer.WritePropertyName("error"u8); + writer.WriteObjectValue(Error, options); + } if (true && _additionalBinaryDataProperties != null) { foreach (var item in _additionalBinaryDataProperties) @@ -76,7 +82,45 @@ internal static ConversationStatusDetails DeserializeConversationStatusDetails(J { return null; } - return UnknownRealtimeResponseStatusDetails.DeserializeUnknownRealtimeResponseStatusDetails(element, options); + ConversationStatus statusKind = default; + ConversationIncompleteReason? incompleteReason = default; + InternalRealtimeResponseStatusDetailsError error = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + statusKind = new ConversationStatus(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("reason"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + incompleteReason = new ConversationIncompleteReason(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("error"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + error = InternalRealtimeResponseStatusDetailsError.DeserializeInternalRealtimeResponseStatusDetailsError(prop.Value, options); + continue; + } + if (true) + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ConversationStatusDetails(statusKind, incompleteReason, error, additionalBinaryDataProperties); } BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); diff --git a/src/Generated/Models/ConversationStatusDetails.cs b/src/Generated/Models/ConversationStatusDetails.cs index 1b560fe8..53a06b7f 100644 --- a/src/Generated/Models/ConversationStatusDetails.cs +++ b/src/Generated/Models/ConversationStatusDetails.cs @@ -7,18 +7,19 @@ namespace OpenAI.RealtimeConversation { - public abstract partial class ConversationStatusDetails + public partial class ConversationStatusDetails { private protected IDictionary _additionalBinaryDataProperties; - private protected ConversationStatusDetails(ConversationStatus statusKind) + internal ConversationStatusDetails() { - StatusKind = statusKind; } - internal ConversationStatusDetails(ConversationStatus statusKind, IDictionary additionalBinaryDataProperties) + internal ConversationStatusDetails(ConversationStatus statusKind, ConversationIncompleteReason? incompleteReason, InternalRealtimeResponseStatusDetailsError error, IDictionary additionalBinaryDataProperties) { StatusKind = statusKind; + IncompleteReason = incompleteReason; + Error = error; _additionalBinaryDataProperties = additionalBinaryDataProperties; } diff --git a/src/Generated/Models/ConversationTokenUsage.Serialization.cs b/src/Generated/Models/ConversationTokenUsage.Serialization.cs index 04a8e335..e7c45e9e 100644 --- a/src/Generated/Models/ConversationTokenUsage.Serialization.cs +++ b/src/Generated/Models/ConversationTokenUsage.Serialization.cs @@ -13,10 +13,6 @@ namespace OpenAI.RealtimeConversation { public partial class ConversationTokenUsage : IJsonModel { - internal ConversationTokenUsage() - { - } - void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { writer.WriteStartObject(); @@ -31,30 +27,30 @@ protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWrit { throw new FormatException($"The model {nameof(ConversationTokenUsage)} does not support writing '{format}' format."); } - if (_additionalBinaryDataProperties?.ContainsKey("total_tokens") != true) + if (Optional.IsDefined(InputTokenDetails) && _additionalBinaryDataProperties?.ContainsKey("input_token_details") != true) { - writer.WritePropertyName("total_tokens"u8); - writer.WriteNumberValue(TotalTokens); + writer.WritePropertyName("input_token_details"u8); + writer.WriteObjectValue(InputTokenDetails, options); + } + if (Optional.IsDefined(OutputTokenDetails) && _additionalBinaryDataProperties?.ContainsKey("output_token_details") != true) + { + writer.WritePropertyName("output_token_details"u8); + writer.WriteObjectValue(OutputTokenDetails, options); } if (_additionalBinaryDataProperties?.ContainsKey("input_tokens") != true) { writer.WritePropertyName("input_tokens"u8); - writer.WriteNumberValue(InputTokens); + writer.WriteNumberValue(InputTokenCount); } if (_additionalBinaryDataProperties?.ContainsKey("output_tokens") != true) { writer.WritePropertyName("output_tokens"u8); - writer.WriteNumberValue(OutputTokens); - } - if (_additionalBinaryDataProperties?.ContainsKey("input_token_details") != true) - { - writer.WritePropertyName("input_token_details"u8); - writer.WriteObjectValue(InputTokenDetails, options); + writer.WriteNumberValue(OutputTokenCount); } - if (_additionalBinaryDataProperties?.ContainsKey("output_token_details") != true) + if (_additionalBinaryDataProperties?.ContainsKey("total_tokens") != true) { - writer.WritePropertyName("output_token_details"u8); - writer.WriteObjectValue(OutputTokenDetails, options); + writer.WritePropertyName("total_tokens"u8); + writer.WriteNumberValue(TotalTokenCount); } if (true && _additionalBinaryDataProperties != null) { @@ -96,37 +92,57 @@ internal static ConversationTokenUsage DeserializeConversationTokenUsage(JsonEle { return null; } - int totalTokens = default; - int inputTokens = default; - int outputTokens = default; ConversationInputTokenUsageDetails inputTokenDetails = default; ConversationOutputTokenUsageDetails outputTokenDetails = default; + int inputTokenCount = default; + int outputTokenCount = default; + int totalTokenCount = default; IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); foreach (var prop in element.EnumerateObject()) { - if (prop.NameEquals("total_tokens"u8)) + if (prop.NameEquals("input_token_details"u8)) { - totalTokens = prop.Value.GetInt32(); + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + inputTokenDetails = ConversationInputTokenUsageDetails.DeserializeConversationInputTokenUsageDetails(prop.Value, options); continue; } - if (prop.NameEquals("input_tokens"u8)) + if (prop.NameEquals("output_token_details"u8)) { - inputTokens = prop.Value.GetInt32(); + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + outputTokenDetails = ConversationOutputTokenUsageDetails.DeserializeConversationOutputTokenUsageDetails(prop.Value, options); continue; } - if (prop.NameEquals("output_tokens"u8)) + if (prop.NameEquals("input_tokens"u8)) { - outputTokens = prop.Value.GetInt32(); + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + inputTokenCount = prop.Value.GetInt32(); continue; } - if (prop.NameEquals("input_token_details"u8)) + if (prop.NameEquals("output_tokens"u8)) { - inputTokenDetails = ConversationInputTokenUsageDetails.DeserializeConversationInputTokenUsageDetails(prop.Value, options); + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + outputTokenCount = prop.Value.GetInt32(); continue; } - if (prop.NameEquals("output_token_details"u8)) + if (prop.NameEquals("total_tokens"u8)) { - outputTokenDetails = ConversationOutputTokenUsageDetails.DeserializeConversationOutputTokenUsageDetails(prop.Value, options); + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + totalTokenCount = prop.Value.GetInt32(); continue; } if (true) @@ -135,11 +151,11 @@ internal static ConversationTokenUsage DeserializeConversationTokenUsage(JsonEle } } return new ConversationTokenUsage( - totalTokens, - inputTokens, - outputTokens, inputTokenDetails, outputTokenDetails, + inputTokenCount, + outputTokenCount, + totalTokenCount, additionalBinaryDataProperties); } diff --git a/src/Generated/Models/ConversationTokenUsage.cs b/src/Generated/Models/ConversationTokenUsage.cs index edc12d4e..4ea2214f 100644 --- a/src/Generated/Models/ConversationTokenUsage.cs +++ b/src/Generated/Models/ConversationTokenUsage.cs @@ -11,31 +11,20 @@ public partial class ConversationTokenUsage { private protected IDictionary _additionalBinaryDataProperties; - internal ConversationTokenUsage(int totalTokens, int inputTokens, int outputTokens, ConversationInputTokenUsageDetails inputTokenDetails, ConversationOutputTokenUsageDetails outputTokenDetails) + internal ConversationTokenUsage() { - TotalTokens = totalTokens; - InputTokens = inputTokens; - OutputTokens = outputTokens; - InputTokenDetails = inputTokenDetails; - OutputTokenDetails = outputTokenDetails; } - internal ConversationTokenUsage(int totalTokens, int inputTokens, int outputTokens, ConversationInputTokenUsageDetails inputTokenDetails, ConversationOutputTokenUsageDetails outputTokenDetails, IDictionary additionalBinaryDataProperties) + internal ConversationTokenUsage(ConversationInputTokenUsageDetails inputTokenDetails, ConversationOutputTokenUsageDetails outputTokenDetails, int inputTokenCount, int outputTokenCount, int totalTokenCount, IDictionary additionalBinaryDataProperties) { - TotalTokens = totalTokens; - InputTokens = inputTokens; - OutputTokens = outputTokens; InputTokenDetails = inputTokenDetails; OutputTokenDetails = outputTokenDetails; + InputTokenCount = inputTokenCount; + OutputTokenCount = outputTokenCount; + TotalTokenCount = totalTokenCount; _additionalBinaryDataProperties = additionalBinaryDataProperties; } - public int TotalTokens { get; } - - public int InputTokens { get; } - - public int OutputTokens { get; } - public ConversationInputTokenUsageDetails InputTokenDetails { get; } public ConversationOutputTokenUsageDetails OutputTokenDetails { get; } diff --git a/src/Generated/Models/ConversationVoice.cs b/src/Generated/Models/ConversationVoice.cs index 20419d71..5ee367c7 100644 --- a/src/Generated/Models/ConversationVoice.cs +++ b/src/Generated/Models/ConversationVoice.cs @@ -12,8 +12,13 @@ namespace OpenAI.RealtimeConversation { private readonly string _value; private const string AlloyValue = "alloy"; - private const string ShimmerValue = "shimmer"; + private const string AshValue = "ash"; + private const string BalladValue = "ballad"; + private const string CoralValue = "coral"; private const string EchoValue = "echo"; + private const string SageValue = "sage"; + private const string ShimmerValue = "shimmer"; + private const string VerseValue = "verse"; public ConversationVoice(string value) { @@ -24,10 +29,20 @@ public ConversationVoice(string value) public static ConversationVoice Alloy { get; } = new ConversationVoice(AlloyValue); - public static ConversationVoice Shimmer { get; } = new ConversationVoice(ShimmerValue); + public static ConversationVoice Ash { get; } = new ConversationVoice(AshValue); + + public static ConversationVoice Ballad { get; } = new ConversationVoice(BalladValue); + + public static ConversationVoice Coral { get; } = new ConversationVoice(CoralValue); public static ConversationVoice Echo { get; } = new ConversationVoice(EchoValue); + public static ConversationVoice Sage { get; } = new ConversationVoice(SageValue); + + public static ConversationVoice Shimmer { get; } = new ConversationVoice(ShimmerValue); + + public static ConversationVoice Verse { get; } = new ConversationVoice(VerseValue); + public static bool operator ==(ConversationVoice left, ConversationVoice right) => left.Equals(right); public static bool operator !=(ConversationVoice left, ConversationVoice right) => !left.Equals(right); diff --git a/src/Generated/Models/DeveloperChatMessage.Serialization.cs b/src/Generated/Models/DeveloperChatMessage.Serialization.cs new file mode 100644 index 00000000..9fa96048 --- /dev/null +++ b/src/Generated/Models/DeveloperChatMessage.Serialization.cs @@ -0,0 +1,128 @@ +// + +#nullable disable + +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; +using OpenAI; + +namespace OpenAI.Chat +{ + public partial class DeveloperChatMessage : IJsonModel + { + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(DeveloperChatMessage)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + if (Optional.IsDefined(ParticipantName) && _additionalBinaryDataProperties?.ContainsKey("name") != true) + { + writer.WritePropertyName("name"u8); + writer.WriteStringValue(ParticipantName); + } + } + + DeveloperChatMessage IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (DeveloperChatMessage)JsonModelCreateCore(ref reader, options); + + protected override ChatMessage JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(DeveloperChatMessage)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeDeveloperChatMessage(document.RootElement, options); + } + + internal static DeveloperChatMessage DeserializeDeveloperChatMessage(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ChatMessageContent content = default; + Chat.ChatMessageRole role = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + string participantName = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("content"u8)) + { + DeserializeContentValue(prop, ref content); + continue; + } + if (prop.NameEquals("role"u8)) + { + role = prop.Value.GetString().ToChatMessageRole(); + continue; + } + if (prop.NameEquals("name"u8)) + { + participantName = prop.Value.GetString(); + continue; + } + if (true) + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new DeveloperChatMessage(content, role, additionalBinaryDataProperties, participantName); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(DeveloperChatMessage)} does not support writing '{options.Format}' format."); + } + } + + DeveloperChatMessage IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (DeveloperChatMessage)PersistableModelCreateCore(data, options); + + protected override ChatMessage PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeDeveloperChatMessage(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(DeveloperChatMessage)} does not support reading '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + + public static implicit operator BinaryContent(DeveloperChatMessage developerChatMessage) + { + if (developerChatMessage == null) + { + return null; + } + return BinaryContent.Create(developerChatMessage, ModelSerializationExtensions.WireOptions); + } + + public static explicit operator DeveloperChatMessage(ClientResult result) + { + using PipelineResponse response = result.GetRawResponse(); + using JsonDocument document = JsonDocument.Parse(response.Content); + return DeserializeDeveloperChatMessage(document.RootElement, ModelSerializationExtensions.WireOptions); + } + } +} diff --git a/src/Generated/Models/DeveloperChatMessage.cs b/src/Generated/Models/DeveloperChatMessage.cs new file mode 100644 index 00000000..b391b289 --- /dev/null +++ b/src/Generated/Models/DeveloperChatMessage.cs @@ -0,0 +1,17 @@ +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace OpenAI.Chat +{ + public partial class DeveloperChatMessage : ChatMessage + { + internal DeveloperChatMessage(ChatMessageContent content, Chat.ChatMessageRole role, IDictionary additionalBinaryDataProperties, string participantName) : base(content, role, additionalBinaryDataProperties) + { + ParticipantName = participantName; + } + } +} diff --git a/src/Generated/Models/FineTuningJob.Serialization.cs b/src/Generated/Models/FineTuningJob.Serialization.cs index 68aff942..69d786bf 100644 --- a/src/Generated/Models/FineTuningJob.Serialization.cs +++ b/src/Generated/Models/FineTuningJob.Serialization.cs @@ -192,6 +192,11 @@ protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWrit writer.WriteNull("estimatedFinish"u8); } } + if (Optional.IsDefined(Method) && _additionalBinaryDataProperties?.ContainsKey("method") != true) + { + writer.WritePropertyName("method"u8); + writer.WriteObjectValue(Method, options); + } if (true && _additionalBinaryDataProperties != null) { foreach (var item in _additionalBinaryDataProperties) @@ -250,6 +255,7 @@ internal static FineTuningJob DeserializeFineTuningJob(JsonElement element, Mode IList integrations = default; int seed = default; DateTimeOffset? estimatedFinish = default; + InternalTodoFineTuneMethod @method = default; IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); foreach (var prop in element.EnumerateObject()) { @@ -399,6 +405,15 @@ internal static FineTuningJob DeserializeFineTuningJob(JsonElement element, Mode estimatedFinish = DateTimeOffset.FromUnixTimeSeconds(prop.Value.GetInt64()); continue; } + if (prop.NameEquals("method"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + @method = InternalTodoFineTuneMethod.DeserializeInternalTodoFineTuneMethod(prop.Value, options); + continue; + } if (true) { additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); @@ -423,6 +438,7 @@ internal static FineTuningJob DeserializeFineTuningJob(JsonElement element, Mode integrations ?? new ChangeTrackingList(), seed, estimatedFinish, + @method, additionalBinaryDataProperties); } diff --git a/src/Generated/Models/FineTuningJob.cs b/src/Generated/Models/FineTuningJob.cs index cd864953..7c29b6d6 100644 --- a/src/Generated/Models/FineTuningJob.cs +++ b/src/Generated/Models/FineTuningJob.cs @@ -32,7 +32,7 @@ internal FineTuningJob(string id, DateTimeOffset createdAt, FineTuningJobError e Seed = seed; } - internal FineTuningJob(string userProvidedSuffix, string id, DateTimeOffset createdAt, FineTuningJobError error, string fineTunedModel, DateTimeOffset? finishedAt, FineTuningJobHyperparameters hyperparameters, string model, InternalFineTuningJobObject @object, string organizationId, IList resultFiles, FineTuningJobStatus status, int? trainedTokens, string trainingFile, string validationFile, IList integrations, int seed, DateTimeOffset? estimatedFinish, IDictionary additionalBinaryDataProperties) + internal FineTuningJob(string userProvidedSuffix, string id, DateTimeOffset createdAt, FineTuningJobError error, string fineTunedModel, DateTimeOffset? finishedAt, FineTuningJobHyperparameters hyperparameters, string model, InternalFineTuningJobObject @object, string organizationId, IList resultFiles, FineTuningJobStatus status, int? trainedTokens, string trainingFile, string validationFile, IList integrations, int seed, DateTimeOffset? estimatedFinish, InternalTodoFineTuneMethod @method, IDictionary additionalBinaryDataProperties) { UserProvidedSuffix = userProvidedSuffix; Id = id; @@ -52,6 +52,7 @@ internal FineTuningJob(string userProvidedSuffix, string id, DateTimeOffset crea Integrations = integrations; Seed = seed; EstimatedFinish = estimatedFinish; + Method = @method; _additionalBinaryDataProperties = additionalBinaryDataProperties; } @@ -91,6 +92,8 @@ internal FineTuningJob(string userProvidedSuffix, string id, DateTimeOffset crea public DateTimeOffset? EstimatedFinish { get; } + public InternalTodoFineTuneMethod Method { get; } + internal IDictionary SerializedAdditionalRawData { get => _additionalBinaryDataProperties; diff --git a/src/Generated/Models/FineTuningJobEvent.Serialization.cs b/src/Generated/Models/FineTuningJobEvent.Serialization.cs index 2c3beecb..ea048b30 100644 --- a/src/Generated/Models/FineTuningJobEvent.Serialization.cs +++ b/src/Generated/Models/FineTuningJobEvent.Serialization.cs @@ -31,6 +31,11 @@ protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWrit { throw new FormatException($"The model {nameof(FineTuningJobEvent)} does not support writing '{format}' format."); } + if (_additionalBinaryDataProperties?.ContainsKey("object") != true) + { + writer.WritePropertyName("object"u8); + writer.WriteStringValue(Object.ToString()); + } if (_additionalBinaryDataProperties?.ContainsKey("id") != true) { writer.WritePropertyName("id"u8); @@ -51,10 +56,22 @@ protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWrit writer.WritePropertyName("message"u8); writer.WriteStringValue(Message); } - if (_additionalBinaryDataProperties?.ContainsKey("object") != true) + if (Optional.IsDefined(Type) && _additionalBinaryDataProperties?.ContainsKey("type") != true) { - writer.WritePropertyName("object"u8); - writer.WriteStringValue(Object.ToString()); + writer.WritePropertyName("type"u8); + writer.WriteStringValue(Type.Value.ToString()); + } + if (Optional.IsDefined(Data) && _additionalBinaryDataProperties?.ContainsKey("data") != true) + { + writer.WritePropertyName("data"u8); +#if NET6_0_OR_GREATER + writer.WriteRawValue(Data); +#else + using (JsonDocument document = JsonDocument.Parse(Data)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif } if (true && _additionalBinaryDataProperties != null) { @@ -96,14 +113,21 @@ internal static FineTuningJobEvent DeserializeFineTuningJobEvent(JsonElement ele { return null; } + InternalFineTuningJobEventObject @object = default; string id = default; DateTimeOffset createdAt = default; FineTuning.FineTuningJobEventLevel level = default; string message = default; - InternalFineTuningJobEventObject @object = default; + InternalFineTuningJobEventType? @type = default; + BinaryData data = default; IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); foreach (var prop in element.EnumerateObject()) { + if (prop.NameEquals("object"u8)) + { + @object = new InternalFineTuningJobEventObject(prop.Value.GetString()); + continue; + } if (prop.NameEquals("id"u8)) { id = prop.Value.GetString(); @@ -124,9 +148,22 @@ internal static FineTuningJobEvent DeserializeFineTuningJobEvent(JsonElement ele message = prop.Value.GetString(); continue; } - if (prop.NameEquals("object"u8)) + if (prop.NameEquals("type"u8)) { - @object = new InternalFineTuningJobEventObject(prop.Value.GetString()); + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + @type = new InternalFineTuningJobEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("data"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + data = BinaryData.FromString(prop.Value.GetRawText()); continue; } if (true) @@ -135,11 +172,13 @@ internal static FineTuningJobEvent DeserializeFineTuningJobEvent(JsonElement ele } } return new FineTuningJobEvent( + @object, id, createdAt, level, message, - @object, + @type, + data, additionalBinaryDataProperties); } diff --git a/src/Generated/Models/FineTuningJobEvent.cs b/src/Generated/Models/FineTuningJobEvent.cs index 223fb400..0830a329 100644 --- a/src/Generated/Models/FineTuningJobEvent.cs +++ b/src/Generated/Models/FineTuningJobEvent.cs @@ -19,16 +19,20 @@ internal FineTuningJobEvent(string id, DateTimeOffset createdAt, FineTuning.Fine Message = message; } - internal FineTuningJobEvent(string id, DateTimeOffset createdAt, FineTuning.FineTuningJobEventLevel level, string message, InternalFineTuningJobEventObject @object, IDictionary additionalBinaryDataProperties) + internal FineTuningJobEvent(InternalFineTuningJobEventObject @object, string id, DateTimeOffset createdAt, FineTuning.FineTuningJobEventLevel level, string message, InternalFineTuningJobEventType? @type, BinaryData data, IDictionary additionalBinaryDataProperties) { + Object = @object; Id = id; CreatedAt = createdAt; Level = level; Message = message; - Object = @object; + Type = @type; + Data = data; _additionalBinaryDataProperties = additionalBinaryDataProperties; } + public InternalFineTuningJobEventObject Object { get; } = "fine_tuning.job.event"; + public string Id { get; } public DateTimeOffset CreatedAt { get; } @@ -37,7 +41,9 @@ internal FineTuningJobEvent(string id, DateTimeOffset createdAt, FineTuning.Fine public string Message { get; } - public InternalFineTuningJobEventObject Object { get; } = "fine_tuning.job.event"; + public InternalFineTuningJobEventType? Type { get; } + + public BinaryData Data { get; } internal IDictionary SerializedAdditionalRawData { diff --git a/src/Generated/Models/FineTuningJobHyperparameters.Serialization.cs b/src/Generated/Models/FineTuningJobHyperparameters.Serialization.cs index abe7ba36..4b059813 100644 --- a/src/Generated/Models/FineTuningJobHyperparameters.Serialization.cs +++ b/src/Generated/Models/FineTuningJobHyperparameters.Serialization.cs @@ -31,7 +31,7 @@ private void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions { throw new FormatException($"The model {nameof(FineTuningJobHyperparameters)} does not support writing '{format}' format."); } - if (_additionalBinaryDataProperties?.ContainsKey("n_epochs") != true) + if (Optional.IsDefined(NEpochs) && _additionalBinaryDataProperties?.ContainsKey("n_epochs") != true) { writer.WritePropertyName("n_epochs"u8); #if NET6_0_OR_GREATER @@ -43,7 +43,7 @@ private void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions } #endif } - if (_additionalBinaryDataProperties?.ContainsKey("batch_size") != true) + if (Optional.IsDefined(BatchSize) && _additionalBinaryDataProperties?.ContainsKey("batch_size") != true) { writer.WritePropertyName("batch_size"u8); #if NET6_0_OR_GREATER @@ -55,7 +55,7 @@ private void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions } #endif } - if (_additionalBinaryDataProperties?.ContainsKey("learning_rate_multiplier") != true) + if (Optional.IsDefined(LearningRateMultiplier) && _additionalBinaryDataProperties?.ContainsKey("learning_rate_multiplier") != true) { writer.WritePropertyName("learning_rate_multiplier"u8); #if NET6_0_OR_GREATER @@ -115,16 +115,28 @@ internal static FineTuningJobHyperparameters DeserializeFineTuningJobHyperparame { if (prop.NameEquals("n_epochs"u8)) { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } nEpochs = BinaryData.FromString(prop.Value.GetRawText()); continue; } if (prop.NameEquals("batch_size"u8)) { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } batchSize = BinaryData.FromString(prop.Value.GetRawText()); continue; } if (prop.NameEquals("learning_rate_multiplier"u8)) { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } learningRateMultiplier = BinaryData.FromString(prop.Value.GetRawText()); continue; } diff --git a/src/Generated/Models/FineTuningJobHyperparametersBatchSizeChoiceEnum.cs b/src/Generated/Models/FineTuningJobHyperparametersBatchSizeChoiceEnum.cs deleted file mode 100644 index e5ad18b8..00000000 --- a/src/Generated/Models/FineTuningJobHyperparametersBatchSizeChoiceEnum.cs +++ /dev/null @@ -1,41 +0,0 @@ -// - -#nullable disable - -using System; -using System.ComponentModel; -using OpenAI; - -namespace OpenAI.FineTuning -{ - internal readonly partial struct FineTuningJobHyperparametersBatchSizeChoiceEnum : IEquatable - { - private readonly string _value; - private const string AutoValue = "auto"; - - public FineTuningJobHyperparametersBatchSizeChoiceEnum(string value) - { - Argument.AssertNotNull(value, nameof(value)); - - _value = value; - } - - public static FineTuningJobHyperparametersBatchSizeChoiceEnum Auto { get; } = new FineTuningJobHyperparametersBatchSizeChoiceEnum(AutoValue); - - public static bool operator ==(FineTuningJobHyperparametersBatchSizeChoiceEnum left, FineTuningJobHyperparametersBatchSizeChoiceEnum right) => left.Equals(right); - - public static bool operator !=(FineTuningJobHyperparametersBatchSizeChoiceEnum left, FineTuningJobHyperparametersBatchSizeChoiceEnum right) => !left.Equals(right); - - public static implicit operator FineTuningJobHyperparametersBatchSizeChoiceEnum(string value) => new FineTuningJobHyperparametersBatchSizeChoiceEnum(value); - - [EditorBrowsable(EditorBrowsableState.Never)] - public override bool Equals(object obj) => obj is FineTuningJobHyperparametersBatchSizeChoiceEnum other && Equals(other); - - public bool Equals(FineTuningJobHyperparametersBatchSizeChoiceEnum 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; - } -} diff --git a/src/Generated/Models/FineTuningJobHyperparametersLearningRateMultiplierChoiceEnum.cs b/src/Generated/Models/FineTuningJobHyperparametersLearningRateMultiplierChoiceEnum.cs deleted file mode 100644 index 87c2d5e3..00000000 --- a/src/Generated/Models/FineTuningJobHyperparametersLearningRateMultiplierChoiceEnum.cs +++ /dev/null @@ -1,41 +0,0 @@ -// - -#nullable disable - -using System; -using System.ComponentModel; -using OpenAI; - -namespace OpenAI.FineTuning -{ - internal readonly partial struct FineTuningJobHyperparametersLearningRateMultiplierChoiceEnum : IEquatable - { - private readonly string _value; - private const string AutoValue = "auto"; - - public FineTuningJobHyperparametersLearningRateMultiplierChoiceEnum(string value) - { - Argument.AssertNotNull(value, nameof(value)); - - _value = value; - } - - public static FineTuningJobHyperparametersLearningRateMultiplierChoiceEnum Auto { get; } = new FineTuningJobHyperparametersLearningRateMultiplierChoiceEnum(AutoValue); - - public static bool operator ==(FineTuningJobHyperparametersLearningRateMultiplierChoiceEnum left, FineTuningJobHyperparametersLearningRateMultiplierChoiceEnum right) => left.Equals(right); - - public static bool operator !=(FineTuningJobHyperparametersLearningRateMultiplierChoiceEnum left, FineTuningJobHyperparametersLearningRateMultiplierChoiceEnum right) => !left.Equals(right); - - public static implicit operator FineTuningJobHyperparametersLearningRateMultiplierChoiceEnum(string value) => new FineTuningJobHyperparametersLearningRateMultiplierChoiceEnum(value); - - [EditorBrowsable(EditorBrowsableState.Never)] - public override bool Equals(object obj) => obj is FineTuningJobHyperparametersLearningRateMultiplierChoiceEnum other && Equals(other); - - public bool Equals(FineTuningJobHyperparametersLearningRateMultiplierChoiceEnum 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; - } -} diff --git a/src/Generated/Models/FineTuningJobHyperparametersNEpochsChoiceEnum.cs b/src/Generated/Models/FineTuningJobHyperparametersNEpochsChoiceEnum.cs deleted file mode 100644 index f4b40d5f..00000000 --- a/src/Generated/Models/FineTuningJobHyperparametersNEpochsChoiceEnum.cs +++ /dev/null @@ -1,41 +0,0 @@ -// - -#nullable disable - -using System; -using System.ComponentModel; -using OpenAI; - -namespace OpenAI.FineTuning -{ - internal readonly partial struct FineTuningJobHyperparametersNEpochsChoiceEnum : IEquatable - { - private readonly string _value; - private const string AutoValue = "auto"; - - public FineTuningJobHyperparametersNEpochsChoiceEnum(string value) - { - Argument.AssertNotNull(value, nameof(value)); - - _value = value; - } - - public static FineTuningJobHyperparametersNEpochsChoiceEnum Auto { get; } = new FineTuningJobHyperparametersNEpochsChoiceEnum(AutoValue); - - public static bool operator ==(FineTuningJobHyperparametersNEpochsChoiceEnum left, FineTuningJobHyperparametersNEpochsChoiceEnum right) => left.Equals(right); - - public static bool operator !=(FineTuningJobHyperparametersNEpochsChoiceEnum left, FineTuningJobHyperparametersNEpochsChoiceEnum right) => !left.Equals(right); - - public static implicit operator FineTuningJobHyperparametersNEpochsChoiceEnum(string value) => new FineTuningJobHyperparametersNEpochsChoiceEnum(value); - - [EditorBrowsable(EditorBrowsableState.Never)] - public override bool Equals(object obj) => obj is FineTuningJobHyperparametersNEpochsChoiceEnum other && Equals(other); - - public bool Equals(FineTuningJobHyperparametersNEpochsChoiceEnum 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; - } -} diff --git a/src/Generated/Models/FineTuningOptions.Serialization.cs b/src/Generated/Models/FineTuningOptions.Serialization.cs index eeaf45f5..461e0d5c 100644 --- a/src/Generated/Models/FineTuningOptions.Serialization.cs +++ b/src/Generated/Models/FineTuningOptions.Serialization.cs @@ -99,6 +99,11 @@ protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWrit writer.WriteNull("seed"u8); } } + if (Optional.IsDefined(Method) && _additionalBinaryDataProperties?.ContainsKey("method") != true) + { + writer.WritePropertyName("method"u8); + writer.WriteObjectValue(Method, options); + } if (true && _additionalBinaryDataProperties != null) { foreach (var item in _additionalBinaryDataProperties) @@ -146,6 +151,7 @@ internal static FineTuningOptions DeserializeFineTuningOptions(JsonElement eleme string validationFile = default; IList integrations = default; int? seed = default; + InternalTodoFineTuneMethod @method = default; IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); foreach (var prop in element.EnumerateObject()) { @@ -212,6 +218,15 @@ internal static FineTuningOptions DeserializeFineTuningOptions(JsonElement eleme seed = prop.Value.GetInt32(); continue; } + if (prop.NameEquals("method"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + @method = InternalTodoFineTuneMethod.DeserializeInternalTodoFineTuneMethod(prop.Value, options); + continue; + } if (true) { additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); @@ -225,6 +240,7 @@ internal static FineTuningOptions DeserializeFineTuningOptions(JsonElement eleme validationFile, integrations ?? new ChangeTrackingList(), seed, + @method, additionalBinaryDataProperties); } diff --git a/src/Generated/Models/FineTuningOptions.cs b/src/Generated/Models/FineTuningOptions.cs index 1fece15c..d3b1e74f 100644 --- a/src/Generated/Models/FineTuningOptions.cs +++ b/src/Generated/Models/FineTuningOptions.cs @@ -21,7 +21,7 @@ public FineTuningOptions(InternalCreateFineTuningJobRequestModel model, string t Integrations = new ChangeTrackingList(); } - internal FineTuningOptions(InternalCreateFineTuningJobRequestModel model, string trainingFile, HyperparameterOptions hyperparameters, string suffix, string validationFile, IList integrations, int? seed, IDictionary additionalBinaryDataProperties) + internal FineTuningOptions(InternalCreateFineTuningJobRequestModel model, string trainingFile, HyperparameterOptions hyperparameters, string suffix, string validationFile, IList integrations, int? seed, InternalTodoFineTuneMethod @method, IDictionary additionalBinaryDataProperties) { Model = model; TrainingFile = trainingFile; @@ -30,6 +30,7 @@ internal FineTuningOptions(InternalCreateFineTuningJobRequestModel model, string ValidationFile = validationFile; Integrations = integrations; Seed = seed; + Method = @method; _additionalBinaryDataProperties = additionalBinaryDataProperties; } @@ -47,6 +48,8 @@ internal FineTuningOptions(InternalCreateFineTuningJobRequestModel model, string public int? Seed { get; set; } + public InternalTodoFineTuneMethod Method { get; set; } + internal IDictionary SerializedAdditionalRawData { get => _additionalBinaryDataProperties; diff --git a/src/Generated/Models/FunctionChatMessage.Serialization.cs b/src/Generated/Models/FunctionChatMessage.Serialization.cs index 0c452e99..ae92c684 100644 --- a/src/Generated/Models/FunctionChatMessage.Serialization.cs +++ b/src/Generated/Models/FunctionChatMessage.Serialization.cs @@ -51,20 +51,20 @@ internal static FunctionChatMessage DeserializeFunctionChatMessage(JsonElement e { return null; } - Chat.ChatMessageRole role = default; ChatMessageContent content = default; + Chat.ChatMessageRole role = default; IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); string functionName = default; foreach (var prop in element.EnumerateObject()) { - if (prop.NameEquals("role"u8)) + if (prop.NameEquals("content"u8)) { - role = prop.Value.GetString().ToChatMessageRole(); + DeserializeContentValue(prop, ref content); continue; } - if (prop.NameEquals("content"u8)) + if (prop.NameEquals("role"u8)) { - DeserializeContentValue(prop, ref content); + role = prop.Value.GetString().ToChatMessageRole(); continue; } if (prop.NameEquals("name"u8)) @@ -78,7 +78,7 @@ internal static FunctionChatMessage DeserializeFunctionChatMessage(JsonElement e } } // CUSTOM: Initialize Content collection property. - return new FunctionChatMessage(role, content ?? new ChatMessageContent(), additionalBinaryDataProperties, functionName); + return new FunctionChatMessage(content ?? new ChatMessageContent(), role, additionalBinaryDataProperties, functionName); } BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); diff --git a/src/Generated/Models/FunctionChatMessage.cs b/src/Generated/Models/FunctionChatMessage.cs index 688e7abc..4fa37e08 100644 --- a/src/Generated/Models/FunctionChatMessage.cs +++ b/src/Generated/Models/FunctionChatMessage.cs @@ -9,7 +9,7 @@ namespace OpenAI.Chat { public partial class FunctionChatMessage : ChatMessage { - internal FunctionChatMessage(Chat.ChatMessageRole role, ChatMessageContent content, IDictionary additionalBinaryDataProperties, string functionName) : base(role, content, additionalBinaryDataProperties) + internal FunctionChatMessage(ChatMessageContent content, Chat.ChatMessageRole role, IDictionary additionalBinaryDataProperties, string functionName) : base(content, role, additionalBinaryDataProperties) { FunctionName = functionName; } diff --git a/src/Generated/Models/GeneratedSpeechVoice.cs b/src/Generated/Models/GeneratedSpeechVoice.cs index 7f18f9ee..d224a73e 100644 --- a/src/Generated/Models/GeneratedSpeechVoice.cs +++ b/src/Generated/Models/GeneratedSpeechVoice.cs @@ -12,10 +12,13 @@ namespace OpenAI.Audio { private readonly string _value; private const string AlloyValue = "alloy"; + private const string AshValue = "ash"; + private const string CoralValue = "coral"; private const string EchoValue = "echo"; private const string FableValue = "fable"; private const string OnyxValue = "onyx"; private const string NovaValue = "nova"; + private const string SageValue = "sage"; private const string ShimmerValue = "shimmer"; public GeneratedSpeechVoice(string value) @@ -27,6 +30,10 @@ public GeneratedSpeechVoice(string value) public static GeneratedSpeechVoice Alloy { get; } = new GeneratedSpeechVoice(AlloyValue); + public static GeneratedSpeechVoice Ash { get; } = new GeneratedSpeechVoice(AshValue); + + public static GeneratedSpeechVoice Coral { get; } = new GeneratedSpeechVoice(CoralValue); + public static GeneratedSpeechVoice Echo { get; } = new GeneratedSpeechVoice(EchoValue); public static GeneratedSpeechVoice Fable { get; } = new GeneratedSpeechVoice(FableValue); @@ -35,6 +42,8 @@ public GeneratedSpeechVoice(string value) public static GeneratedSpeechVoice Nova { get; } = new GeneratedSpeechVoice(NovaValue); + public static GeneratedSpeechVoice Sage { get; } = new GeneratedSpeechVoice(SageValue); + public static GeneratedSpeechVoice Shimmer { get; } = new GeneratedSpeechVoice(ShimmerValue); public static bool operator ==(GeneratedSpeechVoice left, GeneratedSpeechVoice right) => left.Equals(right); diff --git a/src/Generated/Models/HyperparameterBatchSize.cs b/src/Generated/Models/HyperparameterBatchSize.cs deleted file mode 100644 index b223df72..00000000 --- a/src/Generated/Models/HyperparameterBatchSize.cs +++ /dev/null @@ -1,41 +0,0 @@ -// - -#nullable disable - -using System; -using System.ComponentModel; -using OpenAI; - -namespace OpenAI.FineTuning -{ - internal readonly partial struct HyperparameterBatchSize : IEquatable - { - private readonly string _value; - private const string AutoValue = "auto"; - - public HyperparameterBatchSize(string value) - { - Argument.AssertNotNull(value, nameof(value)); - - _value = value; - } - - public static HyperparameterBatchSize Auto { get; } = new HyperparameterBatchSize(AutoValue); - - public static bool operator ==(HyperparameterBatchSize left, HyperparameterBatchSize right) => left.Equals(right); - - public static bool operator !=(HyperparameterBatchSize left, HyperparameterBatchSize right) => !left.Equals(right); - - public static implicit operator HyperparameterBatchSize(string value) => new HyperparameterBatchSize(value); - - [EditorBrowsable(EditorBrowsableState.Never)] - public override bool Equals(object obj) => obj is HyperparameterBatchSize other && Equals(other); - - public bool Equals(HyperparameterBatchSize 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; - } -} diff --git a/src/Generated/Models/HyperparameterCycleCount.cs b/src/Generated/Models/HyperparameterCycleCount.cs deleted file mode 100644 index 12306c29..00000000 --- a/src/Generated/Models/HyperparameterCycleCount.cs +++ /dev/null @@ -1,41 +0,0 @@ -// - -#nullable disable - -using System; -using System.ComponentModel; -using OpenAI; - -namespace OpenAI.FineTuning -{ - internal readonly partial struct HyperparameterCycleCount : IEquatable - { - private readonly string _value; - private const string AutoValue = "auto"; - - public HyperparameterCycleCount(string value) - { - Argument.AssertNotNull(value, nameof(value)); - - _value = value; - } - - public static HyperparameterCycleCount Auto { get; } = new HyperparameterCycleCount(AutoValue); - - public static bool operator ==(HyperparameterCycleCount left, HyperparameterCycleCount right) => left.Equals(right); - - public static bool operator !=(HyperparameterCycleCount left, HyperparameterCycleCount right) => !left.Equals(right); - - public static implicit operator HyperparameterCycleCount(string value) => new HyperparameterCycleCount(value); - - [EditorBrowsable(EditorBrowsableState.Never)] - public override bool Equals(object obj) => obj is HyperparameterCycleCount other && Equals(other); - - public bool Equals(HyperparameterCycleCount 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; - } -} diff --git a/src/Generated/Models/HyperparameterLearningRate.cs b/src/Generated/Models/HyperparameterLearningRate.cs deleted file mode 100644 index 58643912..00000000 --- a/src/Generated/Models/HyperparameterLearningRate.cs +++ /dev/null @@ -1,41 +0,0 @@ -// - -#nullable disable - -using System; -using System.ComponentModel; -using OpenAI; - -namespace OpenAI.FineTuning -{ - internal readonly partial struct HyperparameterLearningRate : IEquatable - { - private readonly string _value; - private const string AutoValue = "auto"; - - public HyperparameterLearningRate(string value) - { - Argument.AssertNotNull(value, nameof(value)); - - _value = value; - } - - public static HyperparameterLearningRate Auto { get; } = new HyperparameterLearningRate(AutoValue); - - public static bool operator ==(HyperparameterLearningRate left, HyperparameterLearningRate right) => left.Equals(right); - - public static bool operator !=(HyperparameterLearningRate left, HyperparameterLearningRate right) => !left.Equals(right); - - public static implicit operator HyperparameterLearningRate(string value) => new HyperparameterLearningRate(value); - - [EditorBrowsable(EditorBrowsableState.Never)] - public override bool Equals(object obj) => obj is HyperparameterLearningRate other && Equals(other); - - public bool Equals(HyperparameterLearningRate 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; - } -} diff --git a/src/Generated/Models/HyperparameterOptions.Serialization.cs b/src/Generated/Models/HyperparameterOptions.Serialization.cs index 1e3d8a42..5b9bc3c2 100644 --- a/src/Generated/Models/HyperparameterOptions.Serialization.cs +++ b/src/Generated/Models/HyperparameterOptions.Serialization.cs @@ -27,18 +27,6 @@ protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWrit { throw new FormatException($"The model {nameof(HyperparameterOptions)} does not support writing '{format}' format."); } - if (Optional.IsDefined(NEpochs) && _additionalBinaryDataProperties?.ContainsKey("n_epochs") != true) - { - writer.WritePropertyName("n_epochs"u8); -#if NET6_0_OR_GREATER - writer.WriteRawValue(NEpochs); -#else - using (JsonDocument document = JsonDocument.Parse(NEpochs)) - { - JsonSerializer.Serialize(writer, document.RootElement); - } -#endif - } if (Optional.IsDefined(BatchSize) && _additionalBinaryDataProperties?.ContainsKey("batch_size") != true) { writer.WritePropertyName("batch_size"u8); @@ -61,6 +49,18 @@ protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWrit { JsonSerializer.Serialize(writer, document.RootElement); } +#endif + } + if (Optional.IsDefined(NEpochs) && _additionalBinaryDataProperties?.ContainsKey("n_epochs") != true) + { + writer.WritePropertyName("n_epochs"u8); +#if NET6_0_OR_GREATER + writer.WriteRawValue(NEpochs); +#else + using (JsonDocument document = JsonDocument.Parse(NEpochs)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } #endif } if (true && _additionalBinaryDataProperties != null) @@ -103,37 +103,37 @@ internal static HyperparameterOptions DeserializeHyperparameterOptions(JsonEleme { return null; } - BinaryData nEpochs = default; BinaryData batchSize = default; BinaryData learningRateMultiplier = default; + BinaryData nEpochs = default; IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); foreach (var prop in element.EnumerateObject()) { - if (prop.NameEquals("n_epochs"u8)) + if (prop.NameEquals("batch_size"u8)) { if (prop.Value.ValueKind == JsonValueKind.Null) { continue; } - nEpochs = BinaryData.FromString(prop.Value.GetRawText()); + batchSize = BinaryData.FromString(prop.Value.GetRawText()); continue; } - if (prop.NameEquals("batch_size"u8)) + if (prop.NameEquals("learning_rate_multiplier"u8)) { if (prop.Value.ValueKind == JsonValueKind.Null) { continue; } - batchSize = BinaryData.FromString(prop.Value.GetRawText()); + learningRateMultiplier = BinaryData.FromString(prop.Value.GetRawText()); continue; } - if (prop.NameEquals("learning_rate_multiplier"u8)) + if (prop.NameEquals("n_epochs"u8)) { if (prop.Value.ValueKind == JsonValueKind.Null) { continue; } - learningRateMultiplier = BinaryData.FromString(prop.Value.GetRawText()); + nEpochs = BinaryData.FromString(prop.Value.GetRawText()); continue; } if (true) @@ -141,7 +141,7 @@ internal static HyperparameterOptions DeserializeHyperparameterOptions(JsonEleme additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); } } - return new HyperparameterOptions(nEpochs, batchSize, learningRateMultiplier, additionalBinaryDataProperties); + return new HyperparameterOptions(batchSize, learningRateMultiplier, nEpochs, additionalBinaryDataProperties); } BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); diff --git a/src/Generated/Models/HyperparameterOptions.cs b/src/Generated/Models/HyperparameterOptions.cs index bf3cd076..7f736391 100644 --- a/src/Generated/Models/HyperparameterOptions.cs +++ b/src/Generated/Models/HyperparameterOptions.cs @@ -15,20 +15,20 @@ public HyperparameterOptions() { } - internal HyperparameterOptions(BinaryData nEpochs, BinaryData batchSize, BinaryData learningRateMultiplier, IDictionary additionalBinaryDataProperties) + internal HyperparameterOptions(BinaryData batchSize, BinaryData learningRateMultiplier, BinaryData nEpochs, IDictionary additionalBinaryDataProperties) { - NEpochs = nEpochs; BatchSize = batchSize; LearningRateMultiplier = learningRateMultiplier; + NEpochs = nEpochs; _additionalBinaryDataProperties = additionalBinaryDataProperties; } - public BinaryData NEpochs { get; set; } - public BinaryData BatchSize { get; set; } public BinaryData LearningRateMultiplier { get; set; } + public BinaryData NEpochs { get; set; } + internal IDictionary SerializedAdditionalRawData { get => _additionalBinaryDataProperties; diff --git a/src/Generated/Models/InternalBatchJob.Serialization.cs b/src/Generated/Models/InternalBatchJob.Serialization.cs index ee8c9a1b..99da02c4 100644 --- a/src/Generated/Models/InternalBatchJob.Serialization.cs +++ b/src/Generated/Models/InternalBatchJob.Serialization.cs @@ -126,9 +126,9 @@ protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWrit writer.WritePropertyName("request_counts"u8); writer.WriteObjectValue(RequestCounts, options); } - if (Optional.IsCollectionDefined(Metadata) && _additionalBinaryDataProperties?.ContainsKey("metadata") != true) + if (_additionalBinaryDataProperties?.ContainsKey("metadata") != true) { - if (Metadata != null) + if (Metadata != null && Optional.IsCollectionDefined(Metadata)) { writer.WritePropertyName("metadata"u8); writer.WriteStartObject(); @@ -351,6 +351,7 @@ internal static InternalBatchJob DeserializeInternalBatchJob(JsonElement element { if (prop.Value.ValueKind == JsonValueKind.Null) { + metadata = new ChangeTrackingDictionary(); continue; } Dictionary dictionary = new Dictionary(); @@ -393,7 +394,7 @@ internal static InternalBatchJob DeserializeInternalBatchJob(JsonElement element cancellingAt, cancelledAt, requestCounts, - metadata ?? new ChangeTrackingDictionary(), + metadata, additionalBinaryDataProperties); } diff --git a/src/Generated/Models/InternalBatchJob.cs b/src/Generated/Models/InternalBatchJob.cs index 0654bf9a..fcffc3b5 100644 --- a/src/Generated/Models/InternalBatchJob.cs +++ b/src/Generated/Models/InternalBatchJob.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; -using OpenAI; namespace OpenAI.Batch { @@ -12,7 +11,7 @@ internal partial class InternalBatchJob { private protected IDictionary _additionalBinaryDataProperties; - internal InternalBatchJob(string id, string endpoint, string inputFileId, string completionWindow, InternalBatchStatus status, DateTimeOffset createdAt) + internal InternalBatchJob(string id, string endpoint, string inputFileId, string completionWindow, InternalBatchStatus status, DateTimeOffset createdAt, IDictionary metadata) { Id = id; Endpoint = endpoint; @@ -20,7 +19,7 @@ internal InternalBatchJob(string id, string endpoint, string inputFileId, string CompletionWindow = completionWindow; Status = status; CreatedAt = createdAt; - Metadata = new ChangeTrackingDictionary(); + Metadata = metadata; } internal InternalBatchJob(string id, InternalBatchObject @object, string endpoint, InternalBatchErrors errors, string inputFileId, string completionWindow, InternalBatchStatus status, string outputFileId, string errorFileId, DateTimeOffset createdAt, DateTimeOffset? inProgressAt, DateTimeOffset? expiresAt, DateTimeOffset? finalizingAt, DateTimeOffset? completedAt, DateTimeOffset? failedAt, DateTimeOffset? expiredAt, DateTimeOffset? cancellingAt, DateTimeOffset? cancelledAt, InternalBatchRequestCounts requestCounts, IDictionary metadata, IDictionary additionalBinaryDataProperties) diff --git a/src/Generated/Models/InternalChatCompletionRequestMessageContentPartAudio.Serialization.cs b/src/Generated/Models/InternalChatCompletionRequestMessageContentPartAudio.Serialization.cs new file mode 100644 index 00000000..4066d42a --- /dev/null +++ b/src/Generated/Models/InternalChatCompletionRequestMessageContentPartAudio.Serialization.cs @@ -0,0 +1,156 @@ +// + +#nullable disable + +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; +using OpenAI; + +namespace OpenAI.Chat +{ + internal partial class InternalChatCompletionRequestMessageContentPartAudio : IJsonModel + { + internal InternalChatCompletionRequestMessageContentPartAudio() + { + } + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(InternalChatCompletionRequestMessageContentPartAudio)} does not support writing '{format}' format."); + } + if (_additionalBinaryDataProperties?.ContainsKey("type") != true) + { + writer.WritePropertyName("type"u8); + writer.WriteStringValue(Type.ToString()); + } + if (_additionalBinaryDataProperties?.ContainsKey("input_audio") != true) + { + writer.WritePropertyName("input_audio"u8); + writer.WriteObjectValue(InputAudio, options); + } + if (true && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + if (ModelSerializationExtensions.IsSentinelValue(item.Value)) + { + continue; + } + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + InternalChatCompletionRequestMessageContentPartAudio IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + protected virtual InternalChatCompletionRequestMessageContentPartAudio JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(InternalChatCompletionRequestMessageContentPartAudio)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeInternalChatCompletionRequestMessageContentPartAudio(document.RootElement, options); + } + + internal static InternalChatCompletionRequestMessageContentPartAudio DeserializeInternalChatCompletionRequestMessageContentPartAudio(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + InternalChatCompletionRequestMessageContentPartAudioType @type = default; + InternalChatCompletionRequestMessageContentPartAudioInputAudio inputAudio = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new InternalChatCompletionRequestMessageContentPartAudioType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("input_audio"u8)) + { + inputAudio = InternalChatCompletionRequestMessageContentPartAudioInputAudio.DeserializeInternalChatCompletionRequestMessageContentPartAudioInputAudio(prop.Value, options); + continue; + } + if (true) + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new InternalChatCompletionRequestMessageContentPartAudio(@type, inputAudio, additionalBinaryDataProperties); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(InternalChatCompletionRequestMessageContentPartAudio)} does not support writing '{options.Format}' format."); + } + } + + InternalChatCompletionRequestMessageContentPartAudio IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + protected virtual InternalChatCompletionRequestMessageContentPartAudio PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeInternalChatCompletionRequestMessageContentPartAudio(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(InternalChatCompletionRequestMessageContentPartAudio)} does not support reading '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + + public static implicit operator BinaryContent(InternalChatCompletionRequestMessageContentPartAudio internalChatCompletionRequestMessageContentPartAudio) + { + if (internalChatCompletionRequestMessageContentPartAudio == null) + { + return null; + } + return BinaryContent.Create(internalChatCompletionRequestMessageContentPartAudio, ModelSerializationExtensions.WireOptions); + } + + public static explicit operator InternalChatCompletionRequestMessageContentPartAudio(ClientResult result) + { + using PipelineResponse response = result.GetRawResponse(); + using JsonDocument document = JsonDocument.Parse(response.Content); + return DeserializeInternalChatCompletionRequestMessageContentPartAudio(document.RootElement, ModelSerializationExtensions.WireOptions); + } + } +} diff --git a/src/Generated/Models/InternalChatCompletionRequestMessageContentPartAudio.cs b/src/Generated/Models/InternalChatCompletionRequestMessageContentPartAudio.cs new file mode 100644 index 00000000..c1d6b3ed --- /dev/null +++ b/src/Generated/Models/InternalChatCompletionRequestMessageContentPartAudio.cs @@ -0,0 +1,39 @@ +// + +#nullable disable + +using System; +using System.Collections.Generic; +using OpenAI; + +namespace OpenAI.Chat +{ + internal partial class InternalChatCompletionRequestMessageContentPartAudio + { + private protected IDictionary _additionalBinaryDataProperties; + + public InternalChatCompletionRequestMessageContentPartAudio(InternalChatCompletionRequestMessageContentPartAudioInputAudio inputAudio) + { + Argument.AssertNotNull(inputAudio, nameof(inputAudio)); + + InputAudio = inputAudio; + } + + internal InternalChatCompletionRequestMessageContentPartAudio(InternalChatCompletionRequestMessageContentPartAudioType @type, InternalChatCompletionRequestMessageContentPartAudioInputAudio inputAudio, IDictionary additionalBinaryDataProperties) + { + Type = @type; + InputAudio = inputAudio; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + public InternalChatCompletionRequestMessageContentPartAudioType Type { get; } = "input_audio"; + + public InternalChatCompletionRequestMessageContentPartAudioInputAudio InputAudio { get; } + + internal IDictionary SerializedAdditionalRawData + { + get => _additionalBinaryDataProperties; + set => _additionalBinaryDataProperties = value; + } + } +} diff --git a/src/Generated/Models/InternalChatCompletionRequestMessageContentPartAudioInputAudio.Serialization.cs b/src/Generated/Models/InternalChatCompletionRequestMessageContentPartAudioInputAudio.Serialization.cs new file mode 100644 index 00000000..99ed0481 --- /dev/null +++ b/src/Generated/Models/InternalChatCompletionRequestMessageContentPartAudioInputAudio.Serialization.cs @@ -0,0 +1,156 @@ +// + +#nullable disable + +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; +using OpenAI; + +namespace OpenAI.Chat +{ + internal partial class InternalChatCompletionRequestMessageContentPartAudioInputAudio : IJsonModel + { + internal InternalChatCompletionRequestMessageContentPartAudioInputAudio() + { + } + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(InternalChatCompletionRequestMessageContentPartAudioInputAudio)} does not support writing '{format}' format."); + } + if (_additionalBinaryDataProperties?.ContainsKey("data") != true) + { + writer.WritePropertyName("data"u8); + writer.WriteBase64StringValue(Data.ToArray(), "D"); + } + if (_additionalBinaryDataProperties?.ContainsKey("format") != true) + { + writer.WritePropertyName("format"u8); + writer.WriteStringValue(Format.ToString()); + } + if (true && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + if (ModelSerializationExtensions.IsSentinelValue(item.Value)) + { + continue; + } + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + InternalChatCompletionRequestMessageContentPartAudioInputAudio IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + protected virtual InternalChatCompletionRequestMessageContentPartAudioInputAudio JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(InternalChatCompletionRequestMessageContentPartAudioInputAudio)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeInternalChatCompletionRequestMessageContentPartAudioInputAudio(document.RootElement, options); + } + + internal static InternalChatCompletionRequestMessageContentPartAudioInputAudio DeserializeInternalChatCompletionRequestMessageContentPartAudioInputAudio(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + BinaryData data = default; + ChatInputAudioFormat format = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("data"u8)) + { + data = BinaryData.FromBytes(prop.Value.GetBytesFromBase64("D")); + continue; + } + if (prop.NameEquals("format"u8)) + { + format = new ChatInputAudioFormat(prop.Value.GetString()); + continue; + } + if (true) + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new InternalChatCompletionRequestMessageContentPartAudioInputAudio(data, format, additionalBinaryDataProperties); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(InternalChatCompletionRequestMessageContentPartAudioInputAudio)} does not support writing '{options.Format}' format."); + } + } + + InternalChatCompletionRequestMessageContentPartAudioInputAudio IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + protected virtual InternalChatCompletionRequestMessageContentPartAudioInputAudio PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeInternalChatCompletionRequestMessageContentPartAudioInputAudio(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(InternalChatCompletionRequestMessageContentPartAudioInputAudio)} does not support reading '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + + public static implicit operator BinaryContent(InternalChatCompletionRequestMessageContentPartAudioInputAudio internalChatCompletionRequestMessageContentPartAudioInputAudio) + { + if (internalChatCompletionRequestMessageContentPartAudioInputAudio == null) + { + return null; + } + return BinaryContent.Create(internalChatCompletionRequestMessageContentPartAudioInputAudio, ModelSerializationExtensions.WireOptions); + } + + public static explicit operator InternalChatCompletionRequestMessageContentPartAudioInputAudio(ClientResult result) + { + using PipelineResponse response = result.GetRawResponse(); + using JsonDocument document = JsonDocument.Parse(response.Content); + return DeserializeInternalChatCompletionRequestMessageContentPartAudioInputAudio(document.RootElement, ModelSerializationExtensions.WireOptions); + } + } +} diff --git a/src/Generated/Models/InternalChatCompletionRequestMessageContentPartAudioInputAudio.cs b/src/Generated/Models/InternalChatCompletionRequestMessageContentPartAudioInputAudio.cs new file mode 100644 index 00000000..f490ce01 --- /dev/null +++ b/src/Generated/Models/InternalChatCompletionRequestMessageContentPartAudioInputAudio.cs @@ -0,0 +1,40 @@ +// + +#nullable disable + +using System; +using System.Collections.Generic; +using OpenAI; + +namespace OpenAI.Chat +{ + internal partial class InternalChatCompletionRequestMessageContentPartAudioInputAudio + { + private protected IDictionary _additionalBinaryDataProperties; + + public InternalChatCompletionRequestMessageContentPartAudioInputAudio(BinaryData data, ChatInputAudioFormat format) + { + Argument.AssertNotNull(data, nameof(data)); + + Data = data; + Format = format; + } + + internal InternalChatCompletionRequestMessageContentPartAudioInputAudio(BinaryData data, ChatInputAudioFormat format, IDictionary additionalBinaryDataProperties) + { + Data = data; + Format = format; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + public BinaryData Data { get; } + + public ChatInputAudioFormat Format { get; } + + internal IDictionary SerializedAdditionalRawData + { + get => _additionalBinaryDataProperties; + set => _additionalBinaryDataProperties = value; + } + } +} diff --git a/src/Generated/Models/InternalChatCompletionRequestMessageContentPartAudioType.cs b/src/Generated/Models/InternalChatCompletionRequestMessageContentPartAudioType.cs new file mode 100644 index 00000000..e7d2eb1b --- /dev/null +++ b/src/Generated/Models/InternalChatCompletionRequestMessageContentPartAudioType.cs @@ -0,0 +1,41 @@ +// + +#nullable disable + +using System; +using System.ComponentModel; +using OpenAI; + +namespace OpenAI.Chat +{ + internal readonly partial struct InternalChatCompletionRequestMessageContentPartAudioType : IEquatable + { + private readonly string _value; + private const string InputAudioValue = "input_audio"; + + public InternalChatCompletionRequestMessageContentPartAudioType(string value) + { + Argument.AssertNotNull(value, nameof(value)); + + _value = value; + } + + public static InternalChatCompletionRequestMessageContentPartAudioType InputAudio { get; } = new InternalChatCompletionRequestMessageContentPartAudioType(InputAudioValue); + + public static bool operator ==(InternalChatCompletionRequestMessageContentPartAudioType left, InternalChatCompletionRequestMessageContentPartAudioType right) => left.Equals(right); + + public static bool operator !=(InternalChatCompletionRequestMessageContentPartAudioType left, InternalChatCompletionRequestMessageContentPartAudioType right) => !left.Equals(right); + + public static implicit operator InternalChatCompletionRequestMessageContentPartAudioType(string value) => new InternalChatCompletionRequestMessageContentPartAudioType(value); + + [EditorBrowsable(EditorBrowsableState.Never)] + public override bool Equals(object obj) => obj is InternalChatCompletionRequestMessageContentPartAudioType other && Equals(other); + + public bool Equals(InternalChatCompletionRequestMessageContentPartAudioType 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; + } +} diff --git a/src/Generated/Models/InternalChatCompletionResponseMessage.Serialization.cs b/src/Generated/Models/InternalChatCompletionResponseMessage.Serialization.cs index 9f3af8c1..d9e55f61 100644 --- a/src/Generated/Models/InternalChatCompletionResponseMessage.Serialization.cs +++ b/src/Generated/Models/InternalChatCompletionResponseMessage.Serialization.cs @@ -53,6 +53,18 @@ protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWrit } writer.WriteEndArray(); } + if (Optional.IsDefined(Audio) && _additionalBinaryDataProperties?.ContainsKey("audio") != true) + { + if (Audio != null) + { + writer.WritePropertyName("audio"u8); + writer.WriteObjectValue(Audio, options); + } + else + { + writer.WriteNull("audio"u8); + } + } if (_additionalBinaryDataProperties?.ContainsKey("role") != true) { writer.WritePropertyName("role"u8); @@ -117,6 +129,7 @@ internal static InternalChatCompletionResponseMessage DeserializeInternalChatCom } string refusal = default; IReadOnlyList toolCalls = default; + ChatOutputAudio audio = default; Chat.ChatMessageRole role = default; ChatMessageContent content = default; ChatFunctionCall functionCall = default; @@ -147,6 +160,16 @@ internal static InternalChatCompletionResponseMessage DeserializeInternalChatCom toolCalls = array; continue; } + if (prop.NameEquals("audio"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + audio = null; + continue; + } + audio = ChatOutputAudio.DeserializeChatOutputAudio(prop.Value, options); + continue; + } if (prop.NameEquals("role"u8)) { role = prop.Value.GetString().ToChatMessageRole(); @@ -175,6 +198,7 @@ internal static InternalChatCompletionResponseMessage DeserializeInternalChatCom return new InternalChatCompletionResponseMessage( refusal, toolCalls ?? new ChangeTrackingList(), + audio, role, content ?? new ChatMessageContent(), functionCall, diff --git a/src/Generated/Models/InternalChatCompletionResponseMessage.cs b/src/Generated/Models/InternalChatCompletionResponseMessage.cs index 97b36241..7b8f87e6 100644 --- a/src/Generated/Models/InternalChatCompletionResponseMessage.cs +++ b/src/Generated/Models/InternalChatCompletionResponseMessage.cs @@ -19,10 +19,11 @@ internal InternalChatCompletionResponseMessage(string refusal, ChatMessageConten Content = content; } - internal InternalChatCompletionResponseMessage(string refusal, IReadOnlyList toolCalls, Chat.ChatMessageRole role, ChatMessageContent content, ChatFunctionCall functionCall, IDictionary additionalBinaryDataProperties) + internal InternalChatCompletionResponseMessage(string refusal, IReadOnlyList toolCalls, ChatOutputAudio audio, Chat.ChatMessageRole role, ChatMessageContent content, ChatFunctionCall functionCall, IDictionary additionalBinaryDataProperties) { Refusal = refusal; ToolCalls = toolCalls; + Audio = audio; Role = role; Content = content; FunctionCall = functionCall; @@ -33,6 +34,8 @@ internal InternalChatCompletionResponseMessage(string refusal, IReadOnlyList ToolCalls { get; } + public ChatOutputAudio Audio { get; } + internal IDictionary SerializedAdditionalRawData { get => _additionalBinaryDataProperties; diff --git a/src/Generated/Models/InternalChatCompletionStreamResponseDelta.Serialization.cs b/src/Generated/Models/InternalChatCompletionStreamResponseDelta.Serialization.cs index e67571f7..de9f8afc 100644 --- a/src/Generated/Models/InternalChatCompletionStreamResponseDelta.Serialization.cs +++ b/src/Generated/Models/InternalChatCompletionStreamResponseDelta.Serialization.cs @@ -27,6 +27,11 @@ protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWrit { throw new FormatException($"The model {nameof(InternalChatCompletionStreamResponseDelta)} does not support writing '{format}' format."); } + if (Optional.IsDefined(Audio) && _additionalBinaryDataProperties?.ContainsKey("audio") != true) + { + writer.WritePropertyName("audio"u8); + writer.WriteObjectValue(Audio, options); + } if (Optional.IsDefined(FunctionCall) && _additionalBinaryDataProperties?.ContainsKey("function_call") != true) { writer.WritePropertyName("function_call"u8); @@ -112,6 +117,7 @@ internal static InternalChatCompletionStreamResponseDelta DeserializeInternalCha { return null; } + StreamingChatOutputAudioUpdate audio = default; StreamingChatFunctionCallUpdate functionCall = default; IReadOnlyList toolCalls = default; string refusal = default; @@ -120,6 +126,15 @@ internal static InternalChatCompletionStreamResponseDelta DeserializeInternalCha IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); foreach (var prop in element.EnumerateObject()) { + if (prop.NameEquals("audio"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + audio = StreamingChatOutputAudioUpdate.DeserializeStreamingChatOutputAudioUpdate(prop.Value, options); + continue; + } if (prop.NameEquals("function_call"u8)) { if (prop.Value.ValueKind == JsonValueKind.Null) @@ -174,6 +189,7 @@ internal static InternalChatCompletionStreamResponseDelta DeserializeInternalCha } // CUSTOM: Initialize Content collection property. return new InternalChatCompletionStreamResponseDelta( + audio, functionCall, toolCalls ?? new ChangeTrackingList(), refusal, diff --git a/src/Generated/Models/InternalChatCompletionStreamResponseDelta.cs b/src/Generated/Models/InternalChatCompletionStreamResponseDelta.cs index dba391ea..1cdd4603 100644 --- a/src/Generated/Models/InternalChatCompletionStreamResponseDelta.cs +++ b/src/Generated/Models/InternalChatCompletionStreamResponseDelta.cs @@ -11,8 +11,9 @@ internal partial class InternalChatCompletionStreamResponseDelta { private protected IDictionary _additionalBinaryDataProperties; - internal InternalChatCompletionStreamResponseDelta(StreamingChatFunctionCallUpdate functionCall, IReadOnlyList toolCalls, string refusal, Chat.ChatMessageRole? role, ChatMessageContent content, IDictionary additionalBinaryDataProperties) + internal InternalChatCompletionStreamResponseDelta(StreamingChatOutputAudioUpdate audio, StreamingChatFunctionCallUpdate functionCall, IReadOnlyList toolCalls, string refusal, Chat.ChatMessageRole? role, ChatMessageContent content, IDictionary additionalBinaryDataProperties) { + Audio = audio; FunctionCall = functionCall; ToolCalls = toolCalls; Refusal = refusal; @@ -21,6 +22,8 @@ internal InternalChatCompletionStreamResponseDelta(StreamingChatFunctionCallUpda _additionalBinaryDataProperties = additionalBinaryDataProperties; } + public StreamingChatOutputAudioUpdate Audio { get; } + public StreamingChatFunctionCallUpdate FunctionCall { get; } public IReadOnlyList ToolCalls { get; } diff --git a/src/Generated/Models/InternalChatOutputPredictionContent.Serialization.cs b/src/Generated/Models/InternalChatOutputPredictionContent.Serialization.cs new file mode 100644 index 00000000..b8739641 --- /dev/null +++ b/src/Generated/Models/InternalChatOutputPredictionContent.Serialization.cs @@ -0,0 +1,134 @@ +// + +#nullable disable + +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; +using OpenAI; + +namespace OpenAI.Chat +{ + internal partial class InternalChatOutputPredictionContent : IJsonModel + { + internal InternalChatOutputPredictionContent() + { + } + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(InternalChatOutputPredictionContent)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + // CUSTOM: Check inner collection is defined. + if (Content.IsInnerCollectionDefined() && _additionalBinaryDataProperties?.ContainsKey("content") != true) + { + writer.WritePropertyName("content"u8); + this.SerializeContentValue(writer, options); + } + } + + InternalChatOutputPredictionContent IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (InternalChatOutputPredictionContent)JsonModelCreateCore(ref reader, options); + + protected override ChatOutputPrediction JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(InternalChatOutputPredictionContent)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeInternalChatOutputPredictionContent(document.RootElement, options); + } + + internal static InternalChatOutputPredictionContent DeserializeInternalChatOutputPredictionContent(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + InternalChatOutputPredictionKind @type = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + ChatMessageContent content = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new InternalChatOutputPredictionKind(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("content"u8)) + { + DeserializeContentValue(prop, ref content); + continue; + } + if (true) + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new InternalChatOutputPredictionContent(@type, additionalBinaryDataProperties, content); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(InternalChatOutputPredictionContent)} does not support writing '{options.Format}' format."); + } + } + + InternalChatOutputPredictionContent IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (InternalChatOutputPredictionContent)PersistableModelCreateCore(data, options); + + protected override ChatOutputPrediction PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeInternalChatOutputPredictionContent(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(InternalChatOutputPredictionContent)} does not support reading '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + + public static implicit operator BinaryContent(InternalChatOutputPredictionContent internalChatOutputPredictionContent) + { + if (internalChatOutputPredictionContent == null) + { + return null; + } + return BinaryContent.Create(internalChatOutputPredictionContent, ModelSerializationExtensions.WireOptions); + } + + public static explicit operator InternalChatOutputPredictionContent(ClientResult result) + { + using PipelineResponse response = result.GetRawResponse(); + using JsonDocument document = JsonDocument.Parse(response.Content); + return DeserializeInternalChatOutputPredictionContent(document.RootElement, ModelSerializationExtensions.WireOptions); + } + } +} diff --git a/src/Generated/Models/InternalChatOutputPredictionContent.cs b/src/Generated/Models/InternalChatOutputPredictionContent.cs new file mode 100644 index 00000000..e23a7c12 --- /dev/null +++ b/src/Generated/Models/InternalChatOutputPredictionContent.cs @@ -0,0 +1,25 @@ +// + +#nullable disable + +using System; +using System.Collections.Generic; +using OpenAI; + +namespace OpenAI.Chat +{ + internal partial class InternalChatOutputPredictionContent : ChatOutputPrediction + { + public InternalChatOutputPredictionContent(ChatMessageContent content) : base(InternalChatOutputPredictionKind.StaticContent) + { + Argument.AssertNotNull(content, nameof(content)); + + Content = content; + } + + internal InternalChatOutputPredictionContent(InternalChatOutputPredictionKind @type, IDictionary additionalBinaryDataProperties, ChatMessageContent content) : base(@type, additionalBinaryDataProperties) + { + Content = content; + } + } +} diff --git a/src/Generated/Models/InternalChatOutputPredictionKind.cs b/src/Generated/Models/InternalChatOutputPredictionKind.cs new file mode 100644 index 00000000..051d77c6 --- /dev/null +++ b/src/Generated/Models/InternalChatOutputPredictionKind.cs @@ -0,0 +1,39 @@ +// + +#nullable disable + +using System; +using System.ComponentModel; +using OpenAI; + +namespace OpenAI.Chat +{ + internal readonly partial struct InternalChatOutputPredictionKind : IEquatable + { + private readonly string _value; + private const string ContentValue = "content"; + + public InternalChatOutputPredictionKind(string value) + { + Argument.AssertNotNull(value, nameof(value)); + + _value = value; + } + + public static bool operator ==(InternalChatOutputPredictionKind left, InternalChatOutputPredictionKind right) => left.Equals(right); + + public static bool operator !=(InternalChatOutputPredictionKind left, InternalChatOutputPredictionKind right) => !left.Equals(right); + + public static implicit operator InternalChatOutputPredictionKind(string value) => new InternalChatOutputPredictionKind(value); + + [EditorBrowsable(EditorBrowsableState.Never)] + public override bool Equals(object obj) => obj is InternalChatOutputPredictionKind other && Equals(other); + + public bool Equals(InternalChatOutputPredictionKind 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; + } +} diff --git a/src/Generated/Models/InternalCreateAssistantRequestModel.cs b/src/Generated/Models/InternalCreateAssistantRequestModel.cs index b92d51fc..409d1456 100644 --- a/src/Generated/Models/InternalCreateAssistantRequestModel.cs +++ b/src/Generated/Models/InternalCreateAssistantRequestModel.cs @@ -12,6 +12,7 @@ namespace OpenAI.Assistants { private readonly string _value; private const string Gpt4oValue = "gpt-4o"; + private const string Gpt4o20241120Value = "gpt-4o-2024-11-20"; private const string Gpt4o20240806Value = "gpt-4o-2024-08-06"; private const string Gpt4o20240513Value = "gpt-4o-2024-05-13"; private const string Gpt4oMiniValue = "gpt-4o-mini"; @@ -44,6 +45,8 @@ public InternalCreateAssistantRequestModel(string value) public static InternalCreateAssistantRequestModel Gpt4o { get; } = new InternalCreateAssistantRequestModel(Gpt4oValue); + public static InternalCreateAssistantRequestModel Gpt4o20241120 { get; } = new InternalCreateAssistantRequestModel(Gpt4o20241120Value); + public static InternalCreateAssistantRequestModel Gpt4o20240806 { get; } = new InternalCreateAssistantRequestModel(Gpt4o20240806Value); public static InternalCreateAssistantRequestModel Gpt4o20240513 { get; } = new InternalCreateAssistantRequestModel(Gpt4o20240513Value); diff --git a/src/Generated/Models/InternalCreateBatchRequest.Serialization.cs b/src/Generated/Models/InternalCreateBatchRequest.Serialization.cs index a9487ca5..5dc6f5e4 100644 --- a/src/Generated/Models/InternalCreateBatchRequest.Serialization.cs +++ b/src/Generated/Models/InternalCreateBatchRequest.Serialization.cs @@ -48,26 +48,19 @@ protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWrit } if (Optional.IsCollectionDefined(Metadata) && _additionalBinaryDataProperties?.ContainsKey("metadata") != true) { - if (Metadata != null) + writer.WritePropertyName("metadata"u8); + writer.WriteStartObject(); + foreach (var item in Metadata) { - writer.WritePropertyName("metadata"u8); - writer.WriteStartObject(); - foreach (var item in Metadata) + writer.WritePropertyName(item.Key); + if (item.Value == null) { - writer.WritePropertyName(item.Key); - if (item.Value == null) - { - writer.WriteNullValue(); - continue; - } - writer.WriteStringValue(item.Value); + writer.WriteNullValue(); + continue; } - writer.WriteEndObject(); - } - else - { - writer.WriteNull("metadata"u8); + writer.WriteStringValue(item.Value); } + writer.WriteEndObject(); } if (true && _additionalBinaryDataProperties != null) { diff --git a/src/Generated/Models/InternalCreateChatCompletionRequestModality.cs b/src/Generated/Models/InternalCreateChatCompletionRequestModality.cs new file mode 100644 index 00000000..a0cb97dc --- /dev/null +++ b/src/Generated/Models/InternalCreateChatCompletionRequestModality.cs @@ -0,0 +1,44 @@ +// + +#nullable disable + +using System; +using System.ComponentModel; +using OpenAI; + +namespace OpenAI.Chat +{ + internal readonly partial struct InternalCreateChatCompletionRequestModality : IEquatable + { + private readonly string _value; + private const string TextValue = "text"; + private const string AudioValue = "audio"; + + public InternalCreateChatCompletionRequestModality(string value) + { + Argument.AssertNotNull(value, nameof(value)); + + _value = value; + } + + public static InternalCreateChatCompletionRequestModality Text { get; } = new InternalCreateChatCompletionRequestModality(TextValue); + + public static InternalCreateChatCompletionRequestModality Audio { get; } = new InternalCreateChatCompletionRequestModality(AudioValue); + + public static bool operator ==(InternalCreateChatCompletionRequestModality left, InternalCreateChatCompletionRequestModality right) => left.Equals(right); + + public static bool operator !=(InternalCreateChatCompletionRequestModality left, InternalCreateChatCompletionRequestModality right) => !left.Equals(right); + + public static implicit operator InternalCreateChatCompletionRequestModality(string value) => new InternalCreateChatCompletionRequestModality(value); + + [EditorBrowsable(EditorBrowsableState.Never)] + public override bool Equals(object obj) => obj is InternalCreateChatCompletionRequestModality other && Equals(other); + + public bool Equals(InternalCreateChatCompletionRequestModality 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; + } +} diff --git a/src/Generated/Models/InternalCreateChatCompletionRequestModel.cs b/src/Generated/Models/InternalCreateChatCompletionRequestModel.cs index f8e62d27..cf542074 100644 --- a/src/Generated/Models/InternalCreateChatCompletionRequestModel.cs +++ b/src/Generated/Models/InternalCreateChatCompletionRequestModel.cs @@ -11,15 +11,23 @@ namespace OpenAI.Chat internal readonly partial struct InternalCreateChatCompletionRequestModel : IEquatable { private readonly string _value; + private const string O3MiniValue = "o3-mini"; + private const string O3Mini20250131Value = "o3-mini-2025-01-31"; + private const string O1Value = "o1"; + private const string O120241217Value = "o1-2024-12-17"; private const string O1PreviewValue = "o1-preview"; private const string O1Preview20240912Value = "o1-preview-2024-09-12"; private const string O1MiniValue = "o1-mini"; private const string O1Mini20240912Value = "o1-mini-2024-09-12"; private const string Gpt4oValue = "gpt-4o"; + private const string Gpt4o20241120Value = "gpt-4o-2024-11-20"; private const string Gpt4o20240806Value = "gpt-4o-2024-08-06"; private const string Gpt4o20240513Value = "gpt-4o-2024-05-13"; - private const string Gpt4oRealtimePreviewValue = "gpt-4o-realtime-preview"; - private const string Gpt4oRealtimePreview20241001Value = "gpt-4o-realtime-preview-2024-10-01"; + private const string Gpt4oAudioPreviewValue = "gpt-4o-audio-preview"; + private const string Gpt4oAudioPreview20241001Value = "gpt-4o-audio-preview-2024-10-01"; + private const string Gpt4oAudioPreview20241217Value = "gpt-4o-audio-preview-2024-12-17"; + private const string Gpt4oMiniAudioPreviewValue = "gpt-4o-mini-audio-preview"; + private const string Gpt4oMiniAudioPreview20241217Value = "gpt-4o-mini-audio-preview-2024-12-17"; private const string Chatgpt4oLatestValue = "chatgpt-4o-latest"; private const string Gpt4oMiniValue = "gpt-4o-mini"; private const string Gpt4oMini20240718Value = "gpt-4o-mini-2024-07-18"; @@ -50,6 +58,14 @@ public InternalCreateChatCompletionRequestModel(string value) _value = value; } + public static InternalCreateChatCompletionRequestModel O3Mini { get; } = new InternalCreateChatCompletionRequestModel(O3MiniValue); + + public static InternalCreateChatCompletionRequestModel O3Mini20250131 { get; } = new InternalCreateChatCompletionRequestModel(O3Mini20250131Value); + + public static InternalCreateChatCompletionRequestModel O1 { get; } = new InternalCreateChatCompletionRequestModel(O1Value); + + public static InternalCreateChatCompletionRequestModel O120241217 { get; } = new InternalCreateChatCompletionRequestModel(O120241217Value); + public static InternalCreateChatCompletionRequestModel O1Preview { get; } = new InternalCreateChatCompletionRequestModel(O1PreviewValue); public static InternalCreateChatCompletionRequestModel O1Preview20240912 { get; } = new InternalCreateChatCompletionRequestModel(O1Preview20240912Value); @@ -60,13 +76,21 @@ public InternalCreateChatCompletionRequestModel(string value) public static InternalCreateChatCompletionRequestModel Gpt4o { get; } = new InternalCreateChatCompletionRequestModel(Gpt4oValue); + public static InternalCreateChatCompletionRequestModel Gpt4o20241120 { get; } = new InternalCreateChatCompletionRequestModel(Gpt4o20241120Value); + public static InternalCreateChatCompletionRequestModel Gpt4o20240806 { get; } = new InternalCreateChatCompletionRequestModel(Gpt4o20240806Value); public static InternalCreateChatCompletionRequestModel Gpt4o20240513 { get; } = new InternalCreateChatCompletionRequestModel(Gpt4o20240513Value); - public static InternalCreateChatCompletionRequestModel Gpt4oRealtimePreview { get; } = new InternalCreateChatCompletionRequestModel(Gpt4oRealtimePreviewValue); + public static InternalCreateChatCompletionRequestModel Gpt4oAudioPreview { get; } = new InternalCreateChatCompletionRequestModel(Gpt4oAudioPreviewValue); + + public static InternalCreateChatCompletionRequestModel Gpt4oAudioPreview20241001 { get; } = new InternalCreateChatCompletionRequestModel(Gpt4oAudioPreview20241001Value); + + public static InternalCreateChatCompletionRequestModel Gpt4oAudioPreview20241217 { get; } = new InternalCreateChatCompletionRequestModel(Gpt4oAudioPreview20241217Value); + + public static InternalCreateChatCompletionRequestModel Gpt4oMiniAudioPreview { get; } = new InternalCreateChatCompletionRequestModel(Gpt4oMiniAudioPreviewValue); - public static InternalCreateChatCompletionRequestModel Gpt4oRealtimePreview20241001 { get; } = new InternalCreateChatCompletionRequestModel(Gpt4oRealtimePreview20241001Value); + public static InternalCreateChatCompletionRequestModel Gpt4oMiniAudioPreview20241217 { get; } = new InternalCreateChatCompletionRequestModel(Gpt4oMiniAudioPreview20241217Value); public static InternalCreateChatCompletionRequestModel Chatgpt4oLatest { get; } = new InternalCreateChatCompletionRequestModel(Chatgpt4oLatestValue); diff --git a/src/Generated/Models/InternalCreateRunRequestModel.cs b/src/Generated/Models/InternalCreateRunRequestModel.cs index 71afae71..7d3b0dbf 100644 --- a/src/Generated/Models/InternalCreateRunRequestModel.cs +++ b/src/Generated/Models/InternalCreateRunRequestModel.cs @@ -12,6 +12,7 @@ namespace OpenAI.Assistants { private readonly string _value; private const string Gpt4oValue = "gpt-4o"; + private const string Gpt4o20241120Value = "gpt-4o-2024-11-20"; private const string Gpt4o20240806Value = "gpt-4o-2024-08-06"; private const string Gpt4o20240513Value = "gpt-4o-2024-05-13"; private const string Gpt4oMiniValue = "gpt-4o-mini"; @@ -44,6 +45,8 @@ public InternalCreateRunRequestModel(string value) public static InternalCreateRunRequestModel Gpt4o { get; } = new InternalCreateRunRequestModel(Gpt4oValue); + public static InternalCreateRunRequestModel Gpt4o20241120 { get; } = new InternalCreateRunRequestModel(Gpt4o20241120Value); + public static InternalCreateRunRequestModel Gpt4o20240806 { get; } = new InternalCreateRunRequestModel(Gpt4o20240806Value); public static InternalCreateRunRequestModel Gpt4o20240513 { get; } = new InternalCreateRunRequestModel(Gpt4o20240513Value); diff --git a/src/Generated/Models/InternalCreateThreadAndRunRequest.Serialization.cs b/src/Generated/Models/InternalCreateThreadAndRunRequest.Serialization.cs index 471899a6..8a98c842 100644 --- a/src/Generated/Models/InternalCreateThreadAndRunRequest.Serialization.cs +++ b/src/Generated/Models/InternalCreateThreadAndRunRequest.Serialization.cs @@ -72,26 +72,19 @@ protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWrit } if (Optional.IsCollectionDefined(Metadata) && _additionalBinaryDataProperties?.ContainsKey("metadata") != true) { - if (Metadata != null) + writer.WritePropertyName("metadata"u8); + writer.WriteStartObject(); + foreach (var item in Metadata) { - writer.WritePropertyName("metadata"u8); - writer.WriteStartObject(); - foreach (var item in Metadata) + writer.WritePropertyName(item.Key); + if (item.Value == null) { - writer.WritePropertyName(item.Key); - if (item.Value == null) - { - writer.WriteNullValue(); - continue; - } - writer.WriteStringValue(item.Value); + writer.WriteNullValue(); + continue; } - writer.WriteEndObject(); - } - else - { - writer.WriteNull("metadata"u8); + writer.WriteStringValue(item.Value); } + writer.WriteEndObject(); } if (Optional.IsDefined(Temperature) && _additionalBinaryDataProperties?.ContainsKey("temperature") != true) { diff --git a/src/Generated/Models/InternalCreateThreadAndRunRequest.cs b/src/Generated/Models/InternalCreateThreadAndRunRequest.cs index 77bb26a6..237c224c 100644 --- a/src/Generated/Models/InternalCreateThreadAndRunRequest.cs +++ b/src/Generated/Models/InternalCreateThreadAndRunRequest.cs @@ -50,7 +50,7 @@ internal InternalCreateThreadAndRunRequest(string assistantId, ThreadCreationOpt public IList Tools { get; set; } - public IDictionary Metadata { get; set; } + public IDictionary Metadata { get; } public float? Temperature { get; set; } diff --git a/src/Generated/Models/InternalCreateThreadAndRunRequestModel.cs b/src/Generated/Models/InternalCreateThreadAndRunRequestModel.cs index 35e576c4..d04dc122 100644 --- a/src/Generated/Models/InternalCreateThreadAndRunRequestModel.cs +++ b/src/Generated/Models/InternalCreateThreadAndRunRequestModel.cs @@ -12,6 +12,7 @@ namespace OpenAI.Assistants { private readonly string _value; private const string Gpt4oValue = "gpt-4o"; + private const string Gpt4o20241120Value = "gpt-4o-2024-11-20"; private const string Gpt4o20240806Value = "gpt-4o-2024-08-06"; private const string Gpt4o20240513Value = "gpt-4o-2024-05-13"; private const string Gpt4oMiniValue = "gpt-4o-mini"; @@ -44,6 +45,8 @@ public InternalCreateThreadAndRunRequestModel(string value) public static InternalCreateThreadAndRunRequestModel Gpt4o { get; } = new InternalCreateThreadAndRunRequestModel(Gpt4oValue); + public static InternalCreateThreadAndRunRequestModel Gpt4o20241120 { get; } = new InternalCreateThreadAndRunRequestModel(Gpt4o20241120Value); + public static InternalCreateThreadAndRunRequestModel Gpt4o20240806 { get; } = new InternalCreateThreadAndRunRequestModel(Gpt4o20240806Value); public static InternalCreateThreadAndRunRequestModel Gpt4o20240513 { get; } = new InternalCreateThreadAndRunRequestModel(Gpt4o20240513Value); diff --git a/src/Generated/Models/InternalFineTuneChatCompletionRequestAssistantMessage.Serialization.cs b/src/Generated/Models/InternalFineTuneChatCompletionRequestAssistantMessage.Serialization.cs index 98cf117e..0003c9a5 100644 --- a/src/Generated/Models/InternalFineTuneChatCompletionRequestAssistantMessage.Serialization.cs +++ b/src/Generated/Models/InternalFineTuneChatCompletionRequestAssistantMessage.Serialization.cs @@ -50,23 +50,24 @@ internal static InternalFineTuneChatCompletionRequestAssistantMessage Deserializ { return null; } - Chat.ChatMessageRole role = default; ChatMessageContent content = default; + Chat.ChatMessageRole role = default; IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); string refusal = default; string participantName = default; IList toolCalls = default; ChatFunctionCall functionCall = default; + ChatOutputAudioReference outputAudioReference = default; foreach (var prop in element.EnumerateObject()) { - if (prop.NameEquals("role"u8)) + if (prop.NameEquals("content"u8)) { - role = prop.Value.GetString().ToChatMessageRole(); + DeserializeContentValue(prop, ref content); continue; } - if (prop.NameEquals("content"u8)) + if (prop.NameEquals("role"u8)) { - DeserializeContentValue(prop, ref content); + role = prop.Value.GetString().ToChatMessageRole(); continue; } if (prop.NameEquals("refusal"u8)) @@ -108,6 +109,16 @@ internal static InternalFineTuneChatCompletionRequestAssistantMessage Deserializ functionCall = ChatFunctionCall.DeserializeChatFunctionCall(prop.Value, options); continue; } + if (prop.NameEquals("audio"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + outputAudioReference = null; + continue; + } + outputAudioReference = ChatOutputAudioReference.DeserializeChatOutputAudioReference(prop.Value, options); + continue; + } if (true) { additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); @@ -115,13 +126,14 @@ internal static InternalFineTuneChatCompletionRequestAssistantMessage Deserializ } // CUSTOM: Initialize Content collection property. return new InternalFineTuneChatCompletionRequestAssistantMessage( - role, content ?? new ChatMessageContent(), + role, additionalBinaryDataProperties, refusal, participantName, toolCalls ?? new ChangeTrackingList(), - functionCall); + functionCall, + outputAudioReference); } BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); diff --git a/src/Generated/Models/InternalFineTuneChatCompletionRequestAssistantMessage.cs b/src/Generated/Models/InternalFineTuneChatCompletionRequestAssistantMessage.cs index 868aa7ef..0df80d87 100644 --- a/src/Generated/Models/InternalFineTuneChatCompletionRequestAssistantMessage.cs +++ b/src/Generated/Models/InternalFineTuneChatCompletionRequestAssistantMessage.cs @@ -14,7 +14,7 @@ public InternalFineTuneChatCompletionRequestAssistantMessage() { } - internal InternalFineTuneChatCompletionRequestAssistantMessage(Chat.ChatMessageRole role, ChatMessageContent content, IDictionary additionalBinaryDataProperties, string refusal, string participantName, IList toolCalls, ChatFunctionCall functionCall) : base(role, content, additionalBinaryDataProperties, refusal, participantName, toolCalls, functionCall) + internal InternalFineTuneChatCompletionRequestAssistantMessage(ChatMessageContent content, Chat.ChatMessageRole role, IDictionary additionalBinaryDataProperties, string refusal, string participantName, IList toolCalls, ChatFunctionCall functionCall, ChatOutputAudioReference outputAudioReference) : base(content, role, additionalBinaryDataProperties, refusal, participantName, toolCalls, functionCall, outputAudioReference) { } } diff --git a/src/Generated/Models/InternalFineTuneSupervisedMethodHyperparameters.Serialization.cs b/src/Generated/Models/InternalFineTuneSupervisedMethodHyperparameters.Serialization.cs new file mode 100644 index 00000000..a97f55cc --- /dev/null +++ b/src/Generated/Models/InternalFineTuneSupervisedMethodHyperparameters.Serialization.cs @@ -0,0 +1,196 @@ +// + +#nullable disable + +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; +using OpenAI; + +namespace OpenAI.FineTuning +{ + internal partial class InternalFineTuneSupervisedMethodHyperparameters : IJsonModel + { + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(InternalFineTuneSupervisedMethodHyperparameters)} does not support writing '{format}' format."); + } + if (Optional.IsDefined(BatchSize) && _additionalBinaryDataProperties?.ContainsKey("batch_size") != true) + { + writer.WritePropertyName("batch_size"u8); +#if NET6_0_OR_GREATER + writer.WriteRawValue(BatchSize); +#else + using (JsonDocument document = JsonDocument.Parse(BatchSize)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + if (Optional.IsDefined(LearningRateMultiplier) && _additionalBinaryDataProperties?.ContainsKey("learning_rate_multiplier") != true) + { + writer.WritePropertyName("learning_rate_multiplier"u8); +#if NET6_0_OR_GREATER + writer.WriteRawValue(LearningRateMultiplier); +#else + using (JsonDocument document = JsonDocument.Parse(LearningRateMultiplier)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + if (Optional.IsDefined(NEpochs) && _additionalBinaryDataProperties?.ContainsKey("n_epochs") != true) + { + writer.WritePropertyName("n_epochs"u8); +#if NET6_0_OR_GREATER + writer.WriteRawValue(NEpochs); +#else + using (JsonDocument document = JsonDocument.Parse(NEpochs)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + if (true && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + if (ModelSerializationExtensions.IsSentinelValue(item.Value)) + { + continue; + } + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + InternalFineTuneSupervisedMethodHyperparameters IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + protected virtual InternalFineTuneSupervisedMethodHyperparameters JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(InternalFineTuneSupervisedMethodHyperparameters)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeInternalFineTuneSupervisedMethodHyperparameters(document.RootElement, options); + } + + internal static InternalFineTuneSupervisedMethodHyperparameters DeserializeInternalFineTuneSupervisedMethodHyperparameters(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + BinaryData batchSize = default; + BinaryData learningRateMultiplier = default; + BinaryData nEpochs = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("batch_size"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + batchSize = BinaryData.FromString(prop.Value.GetRawText()); + continue; + } + if (prop.NameEquals("learning_rate_multiplier"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + learningRateMultiplier = BinaryData.FromString(prop.Value.GetRawText()); + continue; + } + if (prop.NameEquals("n_epochs"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + nEpochs = BinaryData.FromString(prop.Value.GetRawText()); + continue; + } + if (true) + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new InternalFineTuneSupervisedMethodHyperparameters(batchSize, learningRateMultiplier, nEpochs, additionalBinaryDataProperties); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(InternalFineTuneSupervisedMethodHyperparameters)} does not support writing '{options.Format}' format."); + } + } + + InternalFineTuneSupervisedMethodHyperparameters IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + protected virtual InternalFineTuneSupervisedMethodHyperparameters PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeInternalFineTuneSupervisedMethodHyperparameters(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(InternalFineTuneSupervisedMethodHyperparameters)} does not support reading '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + + public static implicit operator BinaryContent(InternalFineTuneSupervisedMethodHyperparameters internalFineTuneSupervisedMethodHyperparameters) + { + if (internalFineTuneSupervisedMethodHyperparameters == null) + { + return null; + } + return BinaryContent.Create(internalFineTuneSupervisedMethodHyperparameters, ModelSerializationExtensions.WireOptions); + } + + public static explicit operator InternalFineTuneSupervisedMethodHyperparameters(ClientResult result) + { + using PipelineResponse response = result.GetRawResponse(); + using JsonDocument document = JsonDocument.Parse(response.Content); + return DeserializeInternalFineTuneSupervisedMethodHyperparameters(document.RootElement, ModelSerializationExtensions.WireOptions); + } + } +} diff --git a/src/Generated/Models/InternalFineTuneSupervisedMethodHyperparameters.cs b/src/Generated/Models/InternalFineTuneSupervisedMethodHyperparameters.cs new file mode 100644 index 00000000..ff74ddb3 --- /dev/null +++ b/src/Generated/Models/InternalFineTuneSupervisedMethodHyperparameters.cs @@ -0,0 +1,38 @@ +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace OpenAI.FineTuning +{ + internal partial class InternalFineTuneSupervisedMethodHyperparameters + { + private protected IDictionary _additionalBinaryDataProperties; + + public InternalFineTuneSupervisedMethodHyperparameters() + { + } + + internal InternalFineTuneSupervisedMethodHyperparameters(BinaryData batchSize, BinaryData learningRateMultiplier, BinaryData nEpochs, IDictionary additionalBinaryDataProperties) + { + BatchSize = batchSize; + LearningRateMultiplier = learningRateMultiplier; + NEpochs = nEpochs; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + public BinaryData BatchSize { get; set; } + + public BinaryData LearningRateMultiplier { get; set; } + + public BinaryData NEpochs { get; set; } + + internal IDictionary SerializedAdditionalRawData + { + get => _additionalBinaryDataProperties; + set => _additionalBinaryDataProperties = value; + } + } +} diff --git a/src/Generated/Models/InternalFineTuningJobEventType.cs b/src/Generated/Models/InternalFineTuningJobEventType.cs new file mode 100644 index 00000000..eaa0fb90 --- /dev/null +++ b/src/Generated/Models/InternalFineTuningJobEventType.cs @@ -0,0 +1,44 @@ +// + +#nullable disable + +using System; +using System.ComponentModel; +using OpenAI; + +namespace OpenAI.FineTuning +{ + internal readonly partial struct InternalFineTuningJobEventType : IEquatable + { + private readonly string _value; + private const string MessageValue = "message"; + private const string MetricsValue = "metrics"; + + public InternalFineTuningJobEventType(string value) + { + Argument.AssertNotNull(value, nameof(value)); + + _value = value; + } + + public static InternalFineTuningJobEventType Message { get; } = new InternalFineTuningJobEventType(MessageValue); + + public static InternalFineTuningJobEventType Metrics { get; } = new InternalFineTuningJobEventType(MetricsValue); + + public static bool operator ==(InternalFineTuningJobEventType left, InternalFineTuningJobEventType right) => left.Equals(right); + + public static bool operator !=(InternalFineTuningJobEventType left, InternalFineTuningJobEventType right) => !left.Equals(right); + + public static implicit operator InternalFineTuningJobEventType(string value) => new InternalFineTuningJobEventType(value); + + [EditorBrowsable(EditorBrowsableState.Never)] + public override bool Equals(object obj) => obj is InternalFineTuningJobEventType other && Equals(other); + + public bool Equals(InternalFineTuningJobEventType 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; + } +} diff --git a/src/Generated/Models/InternalFunctionParameters.Serialization.cs b/src/Generated/Models/InternalFunctionParameters.Serialization.cs deleted file mode 100644 index cf2589d5..00000000 --- a/src/Generated/Models/InternalFunctionParameters.Serialization.cs +++ /dev/null @@ -1,120 +0,0 @@ -// - -#nullable disable - -using System; -using System.ClientModel; -using System.ClientModel.Primitives; -using System.Collections.Generic; -using System.Text.Json; -using OpenAI; - -namespace OpenAI.Chat -{ - internal partial class InternalFunctionParameters : IJsonModel - { - void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) - { - writer.WriteStartObject(); - JsonModelWriteCore(writer, options); - writer.WriteEndObject(); - } - - protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) - { - string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; - if (format != "J") - { - throw new FormatException($"The model {nameof(InternalFunctionParameters)} does not support writing '{format}' format."); - } - foreach (var item in AdditionalProperties) - { - writer.WritePropertyName(item.Key); -#if NET6_0_OR_GREATER - writer.WriteRawValue(item.Value); -#else - using (JsonDocument document = JsonDocument.Parse(item.Value)) - { - JsonSerializer.Serialize(writer, document.RootElement); - } -#endif - } - } - - InternalFunctionParameters IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); - - protected virtual InternalFunctionParameters JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) - { - string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; - if (format != "J") - { - throw new FormatException($"The model {nameof(InternalFunctionParameters)} does not support reading '{format}' format."); - } - using JsonDocument document = JsonDocument.ParseValue(ref reader); - return DeserializeInternalFunctionParameters(document.RootElement, options); - } - - internal static InternalFunctionParameters DeserializeInternalFunctionParameters(JsonElement element, ModelReaderWriterOptions options) - { - if (element.ValueKind == JsonValueKind.Null) - { - return null; - } - IDictionary additionalProperties = new ChangeTrackingDictionary(); - foreach (var prop in element.EnumerateObject()) - { - additionalProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); - } - return new InternalFunctionParameters(additionalProperties); - } - - BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); - - protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) - { - string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; - switch (format) - { - case "J": - return ModelReaderWriter.Write(this, options); - default: - throw new FormatException($"The model {nameof(InternalFunctionParameters)} does not support writing '{options.Format}' format."); - } - } - - InternalFunctionParameters IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); - - protected virtual InternalFunctionParameters PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) - { - string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; - switch (format) - { - case "J": - using (JsonDocument document = JsonDocument.Parse(data)) - { - return DeserializeInternalFunctionParameters(document.RootElement, options); - } - default: - throw new FormatException($"The model {nameof(InternalFunctionParameters)} does not support reading '{options.Format}' format."); - } - } - - string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; - - public static implicit operator BinaryContent(InternalFunctionParameters internalFunctionParameters) - { - if (internalFunctionParameters == null) - { - return null; - } - return BinaryContent.Create(internalFunctionParameters, ModelSerializationExtensions.WireOptions); - } - - public static explicit operator InternalFunctionParameters(ClientResult result) - { - using PipelineResponse response = result.GetRawResponse(); - using JsonDocument document = JsonDocument.Parse(response.Content); - return DeserializeInternalFunctionParameters(document.RootElement, ModelSerializationExtensions.WireOptions); - } - } -} diff --git a/src/Generated/Models/InternalRealtimeClientEventResponseCancel.Serialization.cs b/src/Generated/Models/InternalRealtimeClientEventResponseCancel.Serialization.cs index 6da7ef02..892c4cb6 100644 --- a/src/Generated/Models/InternalRealtimeClientEventResponseCancel.Serialization.cs +++ b/src/Generated/Models/InternalRealtimeClientEventResponseCancel.Serialization.cs @@ -28,6 +28,11 @@ protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWri throw new FormatException($"The model {nameof(InternalRealtimeClientEventResponseCancel)} does not support writing '{format}' format."); } base.JsonModelWriteCore(writer, options); + if (Optional.IsDefined(ResponseId) && _additionalBinaryDataProperties?.ContainsKey("response_id") != true) + { + writer.WritePropertyName("response_id"u8); + writer.WriteStringValue(ResponseId); + } } InternalRealtimeClientEventResponseCancel IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (InternalRealtimeClientEventResponseCancel)JsonModelCreateCore(ref reader, options); @@ -52,6 +57,7 @@ internal static InternalRealtimeClientEventResponseCancel DeserializeInternalRea InternalRealtimeClientEventType kind = default; string eventId = default; IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + string responseId = default; foreach (var prop in element.EnumerateObject()) { if (prop.NameEquals("type"u8)) @@ -64,12 +70,17 @@ internal static InternalRealtimeClientEventResponseCancel DeserializeInternalRea eventId = prop.Value.GetString(); continue; } + if (prop.NameEquals("response_id"u8)) + { + responseId = prop.Value.GetString(); + continue; + } if (true) { additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); } } - return new InternalRealtimeClientEventResponseCancel(kind, eventId, additionalBinaryDataProperties); + return new InternalRealtimeClientEventResponseCancel(kind, eventId, additionalBinaryDataProperties, responseId); } BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); diff --git a/src/Generated/Models/InternalRealtimeClientEventResponseCancel.cs b/src/Generated/Models/InternalRealtimeClientEventResponseCancel.cs index 4e7a1b22..3694fdd2 100644 --- a/src/Generated/Models/InternalRealtimeClientEventResponseCancel.cs +++ b/src/Generated/Models/InternalRealtimeClientEventResponseCancel.cs @@ -13,8 +13,11 @@ public InternalRealtimeClientEventResponseCancel() : base(InternalRealtimeClient { } - internal InternalRealtimeClientEventResponseCancel(InternalRealtimeClientEventType kind, string eventId, IDictionary additionalBinaryDataProperties) : base(kind, eventId, additionalBinaryDataProperties) + internal InternalRealtimeClientEventResponseCancel(InternalRealtimeClientEventType kind, string eventId, IDictionary additionalBinaryDataProperties, string responseId) : base(kind, eventId, additionalBinaryDataProperties) { + ResponseId = responseId; } + + public string ResponseId { get; set; } } } diff --git a/src/Generated/Models/InternalRealtimeClientEventResponseCreate.Serialization.cs b/src/Generated/Models/InternalRealtimeClientEventResponseCreate.Serialization.cs index f1c98f3c..66c7331e 100644 --- a/src/Generated/Models/InternalRealtimeClientEventResponseCreate.Serialization.cs +++ b/src/Generated/Models/InternalRealtimeClientEventResponseCreate.Serialization.cs @@ -13,10 +13,6 @@ namespace OpenAI.RealtimeConversation { internal partial class InternalRealtimeClientEventResponseCreate : IJsonModel { - internal InternalRealtimeClientEventResponseCreate() - { - } - void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { writer.WriteStartObject(); @@ -32,7 +28,7 @@ protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWri throw new FormatException($"The model {nameof(InternalRealtimeClientEventResponseCreate)} does not support writing '{format}' format."); } base.JsonModelWriteCore(writer, options); - if (_additionalBinaryDataProperties?.ContainsKey("response") != true) + if (Optional.IsDefined(Response) && _additionalBinaryDataProperties?.ContainsKey("response") != true) { writer.WritePropertyName("response"u8); writer.WriteObjectValue(Response, options); @@ -61,7 +57,7 @@ internal static InternalRealtimeClientEventResponseCreate DeserializeInternalRea InternalRealtimeClientEventType kind = default; string eventId = default; IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); - InternalRealtimeClientEventResponseCreateResponse response = default; + ConversationResponseOptions response = default; foreach (var prop in element.EnumerateObject()) { if (prop.NameEquals("type"u8)) @@ -76,7 +72,11 @@ internal static InternalRealtimeClientEventResponseCreate DeserializeInternalRea } if (prop.NameEquals("response"u8)) { - response = InternalRealtimeClientEventResponseCreateResponse.DeserializeInternalRealtimeClientEventResponseCreateResponse(prop.Value, options); + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + response = ConversationResponseOptions.DeserializeConversationResponseOptions(prop.Value, options); continue; } if (true) diff --git a/src/Generated/Models/InternalRealtimeClientEventResponseCreate.cs b/src/Generated/Models/InternalRealtimeClientEventResponseCreate.cs index 349d8e18..9c358bf6 100644 --- a/src/Generated/Models/InternalRealtimeClientEventResponseCreate.cs +++ b/src/Generated/Models/InternalRealtimeClientEventResponseCreate.cs @@ -4,24 +4,20 @@ using System; using System.Collections.Generic; -using OpenAI; namespace OpenAI.RealtimeConversation { internal partial class InternalRealtimeClientEventResponseCreate : InternalRealtimeClientEvent { - public InternalRealtimeClientEventResponseCreate(InternalRealtimeClientEventResponseCreateResponse response) : base(InternalRealtimeClientEventType.ResponseCreate) + public InternalRealtimeClientEventResponseCreate() : base(InternalRealtimeClientEventType.ResponseCreate) { - Argument.AssertNotNull(response, nameof(response)); - - Response = response; } - internal InternalRealtimeClientEventResponseCreate(InternalRealtimeClientEventType kind, string eventId, IDictionary additionalBinaryDataProperties, InternalRealtimeClientEventResponseCreateResponse response) : base(kind, eventId, additionalBinaryDataProperties) + internal InternalRealtimeClientEventResponseCreate(InternalRealtimeClientEventType kind, string eventId, IDictionary additionalBinaryDataProperties, ConversationResponseOptions response) : base(kind, eventId, additionalBinaryDataProperties) { Response = response; } - public InternalRealtimeClientEventResponseCreateResponse Response { get; } + public ConversationResponseOptions Response { get; set; } } } diff --git a/src/Generated/Models/InternalRealtimeClientEventResponseCreateResponse.Serialization.cs b/src/Generated/Models/InternalRealtimeClientEventResponseCreateResponse.Serialization.cs deleted file mode 100644 index e5feb25b..00000000 --- a/src/Generated/Models/InternalRealtimeClientEventResponseCreateResponse.Serialization.cs +++ /dev/null @@ -1,293 +0,0 @@ -// - -#nullable disable - -using System; -using System.ClientModel; -using System.ClientModel.Primitives; -using System.Collections.Generic; -using System.Text.Json; -using OpenAI; - -namespace OpenAI.RealtimeConversation -{ - internal partial class InternalRealtimeClientEventResponseCreateResponse : IJsonModel - { - void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) - { - writer.WriteStartObject(); - JsonModelWriteCore(writer, options); - writer.WriteEndObject(); - } - - protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) - { - string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; - if (format != "J") - { - throw new FormatException($"The model {nameof(InternalRealtimeClientEventResponseCreateResponse)} does not support writing '{format}' format."); - } - if (Optional.IsCollectionDefined(Modalities) && _additionalBinaryDataProperties?.ContainsKey("modalities") != true) - { - writer.WritePropertyName("modalities"u8); - writer.WriteStartArray(); - foreach (string item in Modalities) - { - if (item == null) - { - writer.WriteNullValue(); - continue; - } - writer.WriteStringValue(item); - } - writer.WriteEndArray(); - } - if (Optional.IsDefined(Instructions) && _additionalBinaryDataProperties?.ContainsKey("instructions") != true) - { - writer.WritePropertyName("instructions"u8); - writer.WriteStringValue(Instructions); - } - if (Optional.IsDefined(Voice) && _additionalBinaryDataProperties?.ContainsKey("voice") != true) - { - writer.WritePropertyName("voice"u8); - writer.WriteStringValue(Voice); - } - if (Optional.IsDefined(OutputAudioFormat) && _additionalBinaryDataProperties?.ContainsKey("output_audio_format") != true) - { - writer.WritePropertyName("output_audio_format"u8); - writer.WriteStringValue(OutputAudioFormat); - } - if (Optional.IsCollectionDefined(Tools) && _additionalBinaryDataProperties?.ContainsKey("tools") != true) - { - writer.WritePropertyName("tools"u8); - writer.WriteStartArray(); - foreach (ConversationTool item in Tools) - { - writer.WriteObjectValue(item, options); - } - writer.WriteEndArray(); - } - if (Optional.IsDefined(Temperature) && _additionalBinaryDataProperties?.ContainsKey("temperature") != true) - { - writer.WritePropertyName("temperature"u8); - writer.WriteNumberValue(Temperature.Value); - } - if (Optional.IsDefined(MaxOutputTokens) && _additionalBinaryDataProperties?.ContainsKey("max_output_tokens") != true) - { - writer.WritePropertyName("max_output_tokens"u8); -#if NET6_0_OR_GREATER - writer.WriteRawValue(MaxOutputTokens); -#else - using (JsonDocument document = JsonDocument.Parse(MaxOutputTokens)) - { - JsonSerializer.Serialize(writer, document.RootElement); - } -#endif - } - if (Optional.IsDefined(ToolChoice) && _additionalBinaryDataProperties?.ContainsKey("tool_choice") != true) - { - writer.WritePropertyName("tool_choice"u8); -#if NET6_0_OR_GREATER - writer.WriteRawValue(ToolChoice); -#else - using (JsonDocument document = JsonDocument.Parse(ToolChoice)) - { - JsonSerializer.Serialize(writer, document.RootElement); - } -#endif - } - if (true && _additionalBinaryDataProperties != null) - { - foreach (var item in _additionalBinaryDataProperties) - { - if (ModelSerializationExtensions.IsSentinelValue(item.Value)) - { - continue; - } - writer.WritePropertyName(item.Key); -#if NET6_0_OR_GREATER - writer.WriteRawValue(item.Value); -#else - using (JsonDocument document = JsonDocument.Parse(item.Value)) - { - JsonSerializer.Serialize(writer, document.RootElement); - } -#endif - } - } - } - - InternalRealtimeClientEventResponseCreateResponse IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); - - protected virtual InternalRealtimeClientEventResponseCreateResponse JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) - { - string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; - if (format != "J") - { - throw new FormatException($"The model {nameof(InternalRealtimeClientEventResponseCreateResponse)} does not support reading '{format}' format."); - } - using JsonDocument document = JsonDocument.ParseValue(ref reader); - return DeserializeInternalRealtimeClientEventResponseCreateResponse(document.RootElement, options); - } - - internal static InternalRealtimeClientEventResponseCreateResponse DeserializeInternalRealtimeClientEventResponseCreateResponse(JsonElement element, ModelReaderWriterOptions options) - { - if (element.ValueKind == JsonValueKind.Null) - { - return null; - } - IList modalities = default; - string instructions = default; - string voice = default; - string outputAudioFormat = default; - IList tools = default; - float? temperature = default; - BinaryData maxOutputTokens = default; - BinaryData toolChoice = default; - IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); - foreach (var prop in element.EnumerateObject()) - { - if (prop.NameEquals("modalities"u8)) - { - if (prop.Value.ValueKind == JsonValueKind.Null) - { - continue; - } - List array = new List(); - foreach (var item in prop.Value.EnumerateArray()) - { - if (item.ValueKind == JsonValueKind.Null) - { - array.Add(null); - } - else - { - array.Add(item.GetString()); - } - } - modalities = array; - continue; - } - if (prop.NameEquals("instructions"u8)) - { - instructions = prop.Value.GetString(); - continue; - } - if (prop.NameEquals("voice"u8)) - { - voice = prop.Value.GetString(); - continue; - } - if (prop.NameEquals("output_audio_format"u8)) - { - outputAudioFormat = prop.Value.GetString(); - continue; - } - if (prop.NameEquals("tools"u8)) - { - if (prop.Value.ValueKind == JsonValueKind.Null) - { - continue; - } - List array = new List(); - foreach (var item in prop.Value.EnumerateArray()) - { - array.Add(ConversationTool.DeserializeConversationTool(item, options)); - } - tools = array; - continue; - } - if (prop.NameEquals("temperature"u8)) - { - if (prop.Value.ValueKind == JsonValueKind.Null) - { - continue; - } - temperature = prop.Value.GetSingle(); - continue; - } - if (prop.NameEquals("max_output_tokens"u8)) - { - if (prop.Value.ValueKind == JsonValueKind.Null) - { - continue; - } - maxOutputTokens = BinaryData.FromString(prop.Value.GetRawText()); - continue; - } - if (prop.NameEquals("tool_choice"u8)) - { - if (prop.Value.ValueKind == JsonValueKind.Null) - { - continue; - } - toolChoice = BinaryData.FromString(prop.Value.GetRawText()); - continue; - } - if (true) - { - additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); - } - } - return new InternalRealtimeClientEventResponseCreateResponse( - modalities ?? new ChangeTrackingList(), - instructions, - voice, - outputAudioFormat, - tools ?? new ChangeTrackingList(), - temperature, - maxOutputTokens, - toolChoice, - additionalBinaryDataProperties); - } - - BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); - - protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) - { - string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; - switch (format) - { - case "J": - return ModelReaderWriter.Write(this, options); - default: - throw new FormatException($"The model {nameof(InternalRealtimeClientEventResponseCreateResponse)} does not support writing '{options.Format}' format."); - } - } - - InternalRealtimeClientEventResponseCreateResponse IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); - - protected virtual InternalRealtimeClientEventResponseCreateResponse PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) - { - string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; - switch (format) - { - case "J": - using (JsonDocument document = JsonDocument.Parse(data)) - { - return DeserializeInternalRealtimeClientEventResponseCreateResponse(document.RootElement, options); - } - default: - throw new FormatException($"The model {nameof(InternalRealtimeClientEventResponseCreateResponse)} does not support reading '{options.Format}' format."); - } - } - - string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; - - public static implicit operator BinaryContent(InternalRealtimeClientEventResponseCreateResponse internalRealtimeClientEventResponseCreateResponse) - { - if (internalRealtimeClientEventResponseCreateResponse == null) - { - return null; - } - return BinaryContent.Create(internalRealtimeClientEventResponseCreateResponse, ModelSerializationExtensions.WireOptions); - } - - public static explicit operator InternalRealtimeClientEventResponseCreateResponse(ClientResult result) - { - using PipelineResponse response = result.GetRawResponse(); - using JsonDocument document = JsonDocument.Parse(response.Content); - return DeserializeInternalRealtimeClientEventResponseCreateResponse(document.RootElement, ModelSerializationExtensions.WireOptions); - } - } -} diff --git a/src/Generated/Models/InternalRealtimeClientEventResponseCreateResponse.cs b/src/Generated/Models/InternalRealtimeClientEventResponseCreateResponse.cs deleted file mode 100644 index 65240476..00000000 --- a/src/Generated/Models/InternalRealtimeClientEventResponseCreateResponse.cs +++ /dev/null @@ -1,54 +0,0 @@ -// - -#nullable disable - -using System; -using System.Collections.Generic; -using OpenAI; - -namespace OpenAI.RealtimeConversation -{ - internal partial class InternalRealtimeClientEventResponseCreateResponse - { - private protected IDictionary _additionalBinaryDataProperties; - - public InternalRealtimeClientEventResponseCreateResponse() - { - Modalities = new ChangeTrackingList(); - Tools = new ChangeTrackingList(); - } - - internal InternalRealtimeClientEventResponseCreateResponse(IList modalities, string instructions, string voice, string outputAudioFormat, IList tools, float? temperature, BinaryData maxOutputTokens, BinaryData toolChoice, IDictionary additionalBinaryDataProperties) - { - Modalities = modalities; - Instructions = instructions; - Voice = voice; - OutputAudioFormat = outputAudioFormat; - Tools = tools; - Temperature = temperature; - MaxOutputTokens = maxOutputTokens; - ToolChoice = toolChoice; - _additionalBinaryDataProperties = additionalBinaryDataProperties; - } - - public IList Modalities { get; } - - public string Instructions { get; set; } - - public string Voice { get; set; } - - public string OutputAudioFormat { get; set; } - - public IList Tools { get; } - - public float? Temperature { get; set; } - - public BinaryData MaxOutputTokens { get; set; } - - internal IDictionary SerializedAdditionalRawData - { - get => _additionalBinaryDataProperties; - set => _additionalBinaryDataProperties = value; - } - } -} diff --git a/src/Generated/Models/InternalRealtimeResponseItem.Serialization.cs b/src/Generated/Models/InternalRealtimeConversationResponseItem.Serialization.cs similarity index 61% rename from src/Generated/Models/InternalRealtimeResponseItem.Serialization.cs rename to src/Generated/Models/InternalRealtimeConversationResponseItem.Serialization.cs index 8511388a..214e631d 100644 --- a/src/Generated/Models/InternalRealtimeResponseItem.Serialization.cs +++ b/src/Generated/Models/InternalRealtimeConversationResponseItem.Serialization.cs @@ -11,13 +11,13 @@ namespace OpenAI.RealtimeConversation { [PersistableModelProxy(typeof(UnknownRealtimeResponseItem))] - internal abstract partial class InternalRealtimeResponseItem : IJsonModel + internal abstract partial class InternalRealtimeConversationResponseItem : IJsonModel { - internal InternalRealtimeResponseItem() + internal InternalRealtimeConversationResponseItem() { } - void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { writer.WriteStartObject(); JsonModelWriteCore(writer, options); @@ -26,10 +26,10 @@ void IJsonModel.Write(Utf8JsonWriter writer, Model protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) { - string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; if (format != "J") { - throw new FormatException($"The model {nameof(InternalRealtimeResponseItem)} does not support writing '{format}' format."); + throw new FormatException($"The model {nameof(InternalRealtimeConversationResponseItem)} does not support writing '{format}' format."); } if (_additionalBinaryDataProperties?.ContainsKey("object") != true) { @@ -74,20 +74,20 @@ protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWrit } } - InternalRealtimeResponseItem IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + InternalRealtimeConversationResponseItem IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); - protected virtual InternalRealtimeResponseItem JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + protected virtual InternalRealtimeConversationResponseItem JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { - string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; if (format != "J") { - throw new FormatException($"The model {nameof(InternalRealtimeResponseItem)} does not support reading '{format}' format."); + throw new FormatException($"The model {nameof(InternalRealtimeConversationResponseItem)} does not support reading '{format}' format."); } using JsonDocument document = JsonDocument.ParseValue(ref reader); - return DeserializeInternalRealtimeResponseItem(document.RootElement, options); + return DeserializeInternalRealtimeConversationResponseItem(document.RootElement, options); } - internal static InternalRealtimeResponseItem DeserializeInternalRealtimeResponseItem(JsonElement element, ModelReaderWriterOptions options) + internal static InternalRealtimeConversationResponseItem DeserializeInternalRealtimeConversationResponseItem(JsonElement element, ModelReaderWriterOptions options) { if (element.ValueKind == JsonValueKind.Null) { @@ -108,53 +108,53 @@ internal static InternalRealtimeResponseItem DeserializeInternalRealtimeResponse return UnknownRealtimeResponseItem.DeserializeUnknownRealtimeResponseItem(element, options); } - BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) { - string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; switch (format) { case "J": return ModelReaderWriter.Write(this, options); default: - throw new FormatException($"The model {nameof(InternalRealtimeResponseItem)} does not support writing '{options.Format}' format."); + throw new FormatException($"The model {nameof(InternalRealtimeConversationResponseItem)} does not support writing '{options.Format}' format."); } } - InternalRealtimeResponseItem IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + InternalRealtimeConversationResponseItem IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); - protected virtual InternalRealtimeResponseItem PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + protected virtual InternalRealtimeConversationResponseItem PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) { - string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; switch (format) { case "J": using (JsonDocument document = JsonDocument.Parse(data)) { - return DeserializeInternalRealtimeResponseItem(document.RootElement, options); + return DeserializeInternalRealtimeConversationResponseItem(document.RootElement, options); } default: - throw new FormatException($"The model {nameof(InternalRealtimeResponseItem)} does not support reading '{options.Format}' format."); + throw new FormatException($"The model {nameof(InternalRealtimeConversationResponseItem)} does not support reading '{options.Format}' format."); } } - string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; - public static implicit operator BinaryContent(InternalRealtimeResponseItem internalRealtimeResponseItem) + public static implicit operator BinaryContent(InternalRealtimeConversationResponseItem internalRealtimeConversationResponseItem) { - if (internalRealtimeResponseItem == null) + if (internalRealtimeConversationResponseItem == null) { return null; } - return BinaryContent.Create(internalRealtimeResponseItem, ModelSerializationExtensions.WireOptions); + return BinaryContent.Create(internalRealtimeConversationResponseItem, ModelSerializationExtensions.WireOptions); } - public static explicit operator InternalRealtimeResponseItem(ClientResult result) + public static explicit operator InternalRealtimeConversationResponseItem(ClientResult result) { using PipelineResponse response = result.GetRawResponse(); using JsonDocument document = JsonDocument.Parse(response.Content); - return DeserializeInternalRealtimeResponseItem(document.RootElement, ModelSerializationExtensions.WireOptions); + return DeserializeInternalRealtimeConversationResponseItem(document.RootElement, ModelSerializationExtensions.WireOptions); } } } diff --git a/src/Generated/Models/InternalRealtimeResponseItem.cs b/src/Generated/Models/InternalRealtimeConversationResponseItem.cs similarity index 60% rename from src/Generated/Models/InternalRealtimeResponseItem.cs rename to src/Generated/Models/InternalRealtimeConversationResponseItem.cs index a8ed46d5..c9ba6aa6 100644 --- a/src/Generated/Models/InternalRealtimeResponseItem.cs +++ b/src/Generated/Models/InternalRealtimeConversationResponseItem.cs @@ -7,17 +7,17 @@ namespace OpenAI.RealtimeConversation { - internal abstract partial class InternalRealtimeResponseItem + internal abstract partial class InternalRealtimeConversationResponseItem { private protected IDictionary _additionalBinaryDataProperties; - private protected InternalRealtimeResponseItem(InternalRealtimeItemType @type, string id) + private protected InternalRealtimeConversationResponseItem(InternalRealtimeItemType @type, string id) { Type = @type; Id = id; } - internal InternalRealtimeResponseItem(InternalRealtimeResponseItemObject @object, InternalRealtimeItemType @type, string id, IDictionary additionalBinaryDataProperties) + internal InternalRealtimeConversationResponseItem(InternalRealtimeConversationResponseItemObject @object, InternalRealtimeItemType @type, string id, IDictionary additionalBinaryDataProperties) { Object = @object; Type = @type; @@ -25,7 +25,7 @@ internal InternalRealtimeResponseItem(InternalRealtimeResponseItemObject @object _additionalBinaryDataProperties = additionalBinaryDataProperties; } - public InternalRealtimeResponseItemObject Object { get; } = "realtime.item"; + public InternalRealtimeConversationResponseItemObject Object { get; } = "realtime.item"; internal InternalRealtimeItemType Type { get; set; } diff --git a/src/Generated/Models/InternalRealtimeConversationResponseItemObject.cs b/src/Generated/Models/InternalRealtimeConversationResponseItemObject.cs new file mode 100644 index 00000000..1d2497d7 --- /dev/null +++ b/src/Generated/Models/InternalRealtimeConversationResponseItemObject.cs @@ -0,0 +1,41 @@ +// + +#nullable disable + +using System; +using System.ComponentModel; +using OpenAI; + +namespace OpenAI.RealtimeConversation +{ + internal readonly partial struct InternalRealtimeConversationResponseItemObject : IEquatable + { + private readonly string _value; + private const string RealtimeItemValue = "realtime.item"; + + public InternalRealtimeConversationResponseItemObject(string value) + { + Argument.AssertNotNull(value, nameof(value)); + + _value = value; + } + + public static InternalRealtimeConversationResponseItemObject RealtimeItem { get; } = new InternalRealtimeConversationResponseItemObject(RealtimeItemValue); + + public static bool operator ==(InternalRealtimeConversationResponseItemObject left, InternalRealtimeConversationResponseItemObject right) => left.Equals(right); + + public static bool operator !=(InternalRealtimeConversationResponseItemObject left, InternalRealtimeConversationResponseItemObject right) => !left.Equals(right); + + public static implicit operator InternalRealtimeConversationResponseItemObject(string value) => new InternalRealtimeConversationResponseItemObject(value); + + [EditorBrowsable(EditorBrowsableState.Never)] + public override bool Equals(object obj) => obj is InternalRealtimeConversationResponseItemObject other && Equals(other); + + public bool Equals(InternalRealtimeConversationResponseItemObject 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; + } +} diff --git a/src/Generated/Models/InternalRealtimeRequestSessionModel.cs b/src/Generated/Models/InternalRealtimeRequestSessionModel.cs new file mode 100644 index 00000000..b9a74844 --- /dev/null +++ b/src/Generated/Models/InternalRealtimeRequestSessionModel.cs @@ -0,0 +1,53 @@ +// + +#nullable disable + +using System; +using System.ComponentModel; +using OpenAI; + +namespace OpenAI.RealtimeConversation +{ + internal readonly partial struct InternalRealtimeRequestSessionModel : IEquatable + { + private readonly string _value; + private const string Gpt4oRealtimePreviewValue = "gpt-4o-realtime-preview"; + private const string Gpt4oRealtimePreview20241001Value = "gpt-4o-realtime-preview-2024-10-01"; + private const string Gpt4oRealtimePreview20241217Value = "gpt-4o-realtime-preview-2024-12-17"; + private const string Gpt4oMiniRealtimePreviewValue = "gpt-4o-mini-realtime-preview"; + private const string Gpt4oMiniRealtimePreview20241217Value = "gpt-4o-mini-realtime-preview-2024-12-17"; + + public InternalRealtimeRequestSessionModel(string value) + { + Argument.AssertNotNull(value, nameof(value)); + + _value = value; + } + + public static InternalRealtimeRequestSessionModel Gpt4oRealtimePreview { get; } = new InternalRealtimeRequestSessionModel(Gpt4oRealtimePreviewValue); + + public static InternalRealtimeRequestSessionModel Gpt4oRealtimePreview20241001 { get; } = new InternalRealtimeRequestSessionModel(Gpt4oRealtimePreview20241001Value); + + public static InternalRealtimeRequestSessionModel Gpt4oRealtimePreview20241217 { get; } = new InternalRealtimeRequestSessionModel(Gpt4oRealtimePreview20241217Value); + + public static InternalRealtimeRequestSessionModel Gpt4oMiniRealtimePreview { get; } = new InternalRealtimeRequestSessionModel(Gpt4oMiniRealtimePreviewValue); + + public static InternalRealtimeRequestSessionModel Gpt4oMiniRealtimePreview20241217 { get; } = new InternalRealtimeRequestSessionModel(Gpt4oMiniRealtimePreview20241217Value); + + public static bool operator ==(InternalRealtimeRequestSessionModel left, InternalRealtimeRequestSessionModel right) => left.Equals(right); + + public static bool operator !=(InternalRealtimeRequestSessionModel left, InternalRealtimeRequestSessionModel right) => !left.Equals(right); + + public static implicit operator InternalRealtimeRequestSessionModel(string value) => new InternalRealtimeRequestSessionModel(value); + + [EditorBrowsable(EditorBrowsableState.Never)] + public override bool Equals(object obj) => obj is InternalRealtimeRequestSessionModel other && Equals(other); + + public bool Equals(InternalRealtimeRequestSessionModel 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; + } +} diff --git a/src/Generated/Models/InternalRealtimeResponse.Serialization.cs b/src/Generated/Models/InternalRealtimeResponse.Serialization.cs index 51ad43ae..13872d7d 100644 --- a/src/Generated/Models/InternalRealtimeResponse.Serialization.cs +++ b/src/Generated/Models/InternalRealtimeResponse.Serialization.cs @@ -31,39 +31,77 @@ protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWrit { throw new FormatException($"The model {nameof(InternalRealtimeResponse)} does not support writing '{format}' format."); } - if (_additionalBinaryDataProperties?.ContainsKey("object") != true) - { - writer.WritePropertyName("object"u8); - writer.WriteStringValue(Object.ToString()); - } - if (_additionalBinaryDataProperties?.ContainsKey("id") != true) + if (Optional.IsDefined(Id) && _additionalBinaryDataProperties?.ContainsKey("id") != true) { writer.WritePropertyName("id"u8); writer.WriteStringValue(Id); } - if (_additionalBinaryDataProperties?.ContainsKey("status") != true) + if (Optional.IsDefined(Object) && _additionalBinaryDataProperties?.ContainsKey("object") != true) + { + writer.WritePropertyName("object"u8); + writer.WriteStringValue(Object.Value.ToString()); + } + if (Optional.IsDefined(Status) && _additionalBinaryDataProperties?.ContainsKey("status") != true) { writer.WritePropertyName("status"u8); - writer.WriteStringValue(Status.ToString()); + writer.WriteStringValue(Status.Value.ToString()); + } + if (Optional.IsDefined(StatusDetails) && _additionalBinaryDataProperties?.ContainsKey("status_details") != true) + { + writer.WritePropertyName("status_details"u8); + writer.WriteObjectValue(StatusDetails, options); } - if (_additionalBinaryDataProperties?.ContainsKey("status_details") != true) + if (_additionalBinaryDataProperties?.ContainsKey("metadata") != true) { - if (StatusDetails != null) + if (Metadata != null && Optional.IsCollectionDefined(Metadata)) { - writer.WritePropertyName("status_details"u8); - writer.WriteObjectValue(StatusDetails, options); + writer.WritePropertyName("metadata"u8); + writer.WriteStartObject(); + foreach (var item in Metadata) + { + writer.WritePropertyName(item.Key); + if (item.Value == null) + { + writer.WriteNullValue(); + continue; + } + writer.WriteStringValue(item.Value); + } + writer.WriteEndObject(); } else { - writer.WriteNull("statusDetails"u8); + writer.WriteNull("metadata"u8); } } - if (_additionalBinaryDataProperties?.ContainsKey("usage") != true) + if (Optional.IsDefined(Usage) && _additionalBinaryDataProperties?.ContainsKey("usage") != true) { writer.WritePropertyName("usage"u8); writer.WriteObjectValue(Usage, options); } - if (_additionalBinaryDataProperties?.ContainsKey("output") != true) + if (Optional.IsDefined(ConversationId) && _additionalBinaryDataProperties?.ContainsKey("conversation_id") != true) + { + writer.WritePropertyName("conversation_id"u8); + writer.WriteStringValue(ConversationId); + } + if (Optional.IsDefined(Temperature) && _additionalBinaryDataProperties?.ContainsKey("temperature") != true) + { + writer.WritePropertyName("temperature"u8); + writer.WriteNumberValue(Temperature.Value); + } + if (Optional.IsDefined(MaxOutputTokens) && _additionalBinaryDataProperties?.ContainsKey("max_output_tokens") != true) + { + writer.WritePropertyName("max_output_tokens"u8); +#if NET6_0_OR_GREATER + writer.WriteRawValue(MaxOutputTokens); +#else + using (JsonDocument document = JsonDocument.Parse(MaxOutputTokens)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + if (Optional.IsCollectionDefined(Output) && _additionalBinaryDataProperties?.ContainsKey("output") != true) { writer.WritePropertyName("output"u8); writer.WriteStartArray(); @@ -73,6 +111,26 @@ protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWrit } writer.WriteEndArray(); } + if (Optional.IsCollectionDefined(Modalities) && _additionalBinaryDataProperties?.ContainsKey("modalities") != true) + { + writer.WritePropertyName("modalities"u8); + writer.WriteStartArray(); + foreach (InternalRealtimeResponseModality item in Modalities) + { + writer.WriteStringValue(item.ToString()); + } + writer.WriteEndArray(); + } + if (Optional.IsDefined(Voice) && _additionalBinaryDataProperties?.ContainsKey("voice") != true) + { + writer.WritePropertyName("voice"u8); + writer.WriteStringValue(Voice.Value.ToString()); + } + if (Optional.IsDefined(OutputAudioFormat) && _additionalBinaryDataProperties?.ContainsKey("output_audio_format") != true) + { + writer.WritePropertyName("output_audio_format"u8); + writer.WriteStringValue(OutputAudioFormat.Value.ToString()); + } if (true && _additionalBinaryDataProperties != null) { foreach (var item in _additionalBinaryDataProperties) @@ -113,27 +171,42 @@ internal static InternalRealtimeResponse DeserializeInternalRealtimeResponse(Jso { return null; } - InternalRealtimeResponseObject @object = default; string id = default; - ConversationStatus status = default; + InternalRealtimeResponseObject? @object = default; + ConversationStatus? status = default; ConversationStatusDetails statusDetails = default; + IDictionary metadata = default; ConversationTokenUsage usage = default; + string conversationId = default; + float? temperature = default; + BinaryData maxOutputTokens = default; IReadOnlyList output = default; + IReadOnlyList modalities = default; + ConversationVoice? voice = default; + ConversationAudioFormat? outputAudioFormat = default; IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); foreach (var prop in element.EnumerateObject()) { - if (prop.NameEquals("object"u8)) + if (prop.NameEquals("id"u8)) { - @object = new InternalRealtimeResponseObject(prop.Value.GetString()); + id = prop.Value.GetString(); continue; } - if (prop.NameEquals("id"u8)) + if (prop.NameEquals("object"u8)) { - id = prop.Value.GetString(); + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + @object = new InternalRealtimeResponseObject(prop.Value.GetString()); continue; } if (prop.NameEquals("status"u8)) { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } status = new ConversationStatus(prop.Value.GetString()); continue; } @@ -141,19 +214,71 @@ internal static InternalRealtimeResponse DeserializeInternalRealtimeResponse(Jso { if (prop.Value.ValueKind == JsonValueKind.Null) { - statusDetails = null; continue; } statusDetails = ConversationStatusDetails.DeserializeConversationStatusDetails(prop.Value, options); continue; } + if (prop.NameEquals("metadata"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + metadata = new ChangeTrackingDictionary(); + continue; + } + Dictionary dictionary = new Dictionary(); + foreach (var prop0 in prop.Value.EnumerateObject()) + { + if (prop0.Value.ValueKind == JsonValueKind.Null) + { + dictionary.Add(prop0.Name, null); + } + else + { + dictionary.Add(prop0.Name, prop0.Value.GetString()); + } + } + metadata = dictionary; + continue; + } if (prop.NameEquals("usage"u8)) { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } usage = ConversationTokenUsage.DeserializeConversationTokenUsage(prop.Value, options); continue; } + if (prop.NameEquals("conversation_id"u8)) + { + conversationId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("temperature"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + temperature = prop.Value.GetSingle(); + continue; + } + if (prop.NameEquals("max_output_tokens"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + maxOutputTokens = BinaryData.FromString(prop.Value.GetRawText()); + continue; + } if (prop.NameEquals("output"u8)) { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } List array = new List(); foreach (var item in prop.Value.EnumerateArray()) { @@ -162,18 +287,57 @@ internal static InternalRealtimeResponse DeserializeInternalRealtimeResponse(Jso output = array; continue; } + if (prop.NameEquals("modalities"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + List array = new List(); + foreach (var item in prop.Value.EnumerateArray()) + { + array.Add(new InternalRealtimeResponseModality(item.GetString())); + } + modalities = array; + continue; + } + if (prop.NameEquals("voice"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + voice = new ConversationVoice(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("output_audio_format"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + outputAudioFormat = new ConversationAudioFormat(prop.Value.GetString()); + continue; + } if (true) { additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); } } return new InternalRealtimeResponse( - @object, id, + @object, status, statusDetails, + metadata, usage, - output, + conversationId, + temperature, + maxOutputTokens, + output ?? new ChangeTrackingList(), + modalities ?? new ChangeTrackingList(), + voice, + outputAudioFormat, additionalBinaryDataProperties); } diff --git a/src/Generated/Models/InternalRealtimeResponse.cs b/src/Generated/Models/InternalRealtimeResponse.cs index 50f4a0b4..a2a824d4 100644 --- a/src/Generated/Models/InternalRealtimeResponse.cs +++ b/src/Generated/Models/InternalRealtimeResponse.cs @@ -4,7 +4,7 @@ using System; using System.Collections.Generic; -using System.Linq; +using OpenAI; namespace OpenAI.RealtimeConversation { @@ -12,36 +12,49 @@ internal partial class InternalRealtimeResponse { private protected IDictionary _additionalBinaryDataProperties; - internal InternalRealtimeResponse(string id, ConversationStatus status, ConversationStatusDetails statusDetails, ConversationTokenUsage usage, IEnumerable output) + internal InternalRealtimeResponse(IDictionary metadata) { - Id = id; - Status = status; - StatusDetails = statusDetails; - Usage = usage; - Output = output.ToList(); + Metadata = metadata; + Output = new ChangeTrackingList(); + Modalities = new ChangeTrackingList(); } - internal InternalRealtimeResponse(InternalRealtimeResponseObject @object, string id, ConversationStatus status, ConversationStatusDetails statusDetails, ConversationTokenUsage usage, IReadOnlyList output, IDictionary additionalBinaryDataProperties) + internal InternalRealtimeResponse(string id, InternalRealtimeResponseObject? @object, ConversationStatus? status, ConversationStatusDetails statusDetails, IDictionary metadata, ConversationTokenUsage usage, string conversationId, float? temperature, BinaryData maxOutputTokens, IReadOnlyList output, IReadOnlyList modalities, ConversationVoice? voice, ConversationAudioFormat? outputAudioFormat, IDictionary additionalBinaryDataProperties) { - Object = @object; Id = id; + Object = @object; Status = status; StatusDetails = statusDetails; + Metadata = metadata; Usage = usage; + ConversationId = conversationId; + Temperature = temperature; + MaxOutputTokens = maxOutputTokens; Output = output; + Modalities = modalities; + Voice = voice; + OutputAudioFormat = outputAudioFormat; _additionalBinaryDataProperties = additionalBinaryDataProperties; } - public InternalRealtimeResponseObject Object { get; } = "realtime.response"; - public string Id { get; } - public ConversationStatus Status { get; } + public InternalRealtimeResponseObject? Object { get; } + + public ConversationStatus? Status { get; } public ConversationStatusDetails StatusDetails { get; } + public IDictionary Metadata { get; } + public ConversationTokenUsage Usage { get; } + public string ConversationId { get; } + + public float? Temperature { get; } + + public BinaryData MaxOutputTokens { get; } + internal IDictionary SerializedAdditionalRawData { get => _additionalBinaryDataProperties; diff --git a/src/Generated/Models/InternalRealtimeResponseFunctionCallItem.Serialization.cs b/src/Generated/Models/InternalRealtimeResponseFunctionCallItem.Serialization.cs index 14c3d338..5af5037d 100644 --- a/src/Generated/Models/InternalRealtimeResponseFunctionCallItem.Serialization.cs +++ b/src/Generated/Models/InternalRealtimeResponseFunctionCallItem.Serialization.cs @@ -56,7 +56,7 @@ protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWri InternalRealtimeResponseFunctionCallItem IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (InternalRealtimeResponseFunctionCallItem)JsonModelCreateCore(ref reader, options); - protected override InternalRealtimeResponseItem JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + protected override InternalRealtimeConversationResponseItem JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; if (format != "J") @@ -73,7 +73,7 @@ internal static InternalRealtimeResponseFunctionCallItem DeserializeInternalReal { return null; } - InternalRealtimeResponseItemObject @object = default; + InternalRealtimeConversationResponseItemObject @object = default; InternalRealtimeItemType @type = default; string id = default; IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); @@ -85,7 +85,7 @@ internal static InternalRealtimeResponseFunctionCallItem DeserializeInternalReal { if (prop.NameEquals("object"u8)) { - @object = new InternalRealtimeResponseItemObject(prop.Value.GetString()); + @object = new InternalRealtimeConversationResponseItemObject(prop.Value.GetString()); continue; } if (prop.NameEquals("type"u8)) @@ -155,7 +155,7 @@ protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions InternalRealtimeResponseFunctionCallItem IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (InternalRealtimeResponseFunctionCallItem)PersistableModelCreateCore(data, options); - protected override InternalRealtimeResponseItem PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + protected override InternalRealtimeConversationResponseItem PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) { string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; switch (format) diff --git a/src/Generated/Models/InternalRealtimeResponseFunctionCallItem.cs b/src/Generated/Models/InternalRealtimeResponseFunctionCallItem.cs index e1d10fa8..f89f19c9 100644 --- a/src/Generated/Models/InternalRealtimeResponseFunctionCallItem.cs +++ b/src/Generated/Models/InternalRealtimeResponseFunctionCallItem.cs @@ -7,7 +7,7 @@ namespace OpenAI.RealtimeConversation { - internal partial class InternalRealtimeResponseFunctionCallItem : InternalRealtimeResponseItem + internal partial class InternalRealtimeResponseFunctionCallItem : InternalRealtimeConversationResponseItem { internal InternalRealtimeResponseFunctionCallItem(string id, string name, string callId, string arguments, ConversationItemStatus status) : base(InternalRealtimeItemType.FunctionCall, id) { @@ -17,7 +17,7 @@ internal InternalRealtimeResponseFunctionCallItem(string id, string name, string Status = status; } - internal InternalRealtimeResponseFunctionCallItem(InternalRealtimeResponseItemObject @object, InternalRealtimeItemType @type, string id, IDictionary additionalBinaryDataProperties, string name, string callId, string arguments, ConversationItemStatus status) : base(@object, @type, id, additionalBinaryDataProperties) + internal InternalRealtimeResponseFunctionCallItem(InternalRealtimeConversationResponseItemObject @object, InternalRealtimeItemType @type, string id, IDictionary additionalBinaryDataProperties, string name, string callId, string arguments, ConversationItemStatus status) : base(@object, @type, id, additionalBinaryDataProperties) { Name = name; CallId = callId; diff --git a/src/Generated/Models/InternalRealtimeResponseFunctionCallOutputItem.Serialization.cs b/src/Generated/Models/InternalRealtimeResponseFunctionCallOutputItem.Serialization.cs index c5b563a3..d7e539a5 100644 --- a/src/Generated/Models/InternalRealtimeResponseFunctionCallOutputItem.Serialization.cs +++ b/src/Generated/Models/InternalRealtimeResponseFunctionCallOutputItem.Serialization.cs @@ -46,7 +46,7 @@ protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWri InternalRealtimeResponseFunctionCallOutputItem IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (InternalRealtimeResponseFunctionCallOutputItem)JsonModelCreateCore(ref reader, options); - protected override InternalRealtimeResponseItem JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + protected override InternalRealtimeConversationResponseItem JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; if (format != "J") @@ -63,7 +63,7 @@ internal static InternalRealtimeResponseFunctionCallOutputItem DeserializeIntern { return null; } - InternalRealtimeResponseItemObject @object = default; + InternalRealtimeConversationResponseItemObject @object = default; InternalRealtimeItemType @type = default; string id = default; IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); @@ -73,7 +73,7 @@ internal static InternalRealtimeResponseFunctionCallOutputItem DeserializeIntern { if (prop.NameEquals("object"u8)) { - @object = new InternalRealtimeResponseItemObject(prop.Value.GetString()); + @object = new InternalRealtimeConversationResponseItemObject(prop.Value.GetString()); continue; } if (prop.NameEquals("type"u8)) @@ -131,7 +131,7 @@ protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions InternalRealtimeResponseFunctionCallOutputItem IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (InternalRealtimeResponseFunctionCallOutputItem)PersistableModelCreateCore(data, options); - protected override InternalRealtimeResponseItem PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + protected override InternalRealtimeConversationResponseItem PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) { string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; switch (format) diff --git a/src/Generated/Models/InternalRealtimeResponseFunctionCallOutputItem.cs b/src/Generated/Models/InternalRealtimeResponseFunctionCallOutputItem.cs index 7295ba6f..babadf19 100644 --- a/src/Generated/Models/InternalRealtimeResponseFunctionCallOutputItem.cs +++ b/src/Generated/Models/InternalRealtimeResponseFunctionCallOutputItem.cs @@ -7,7 +7,7 @@ namespace OpenAI.RealtimeConversation { - internal partial class InternalRealtimeResponseFunctionCallOutputItem : InternalRealtimeResponseItem + internal partial class InternalRealtimeResponseFunctionCallOutputItem : InternalRealtimeConversationResponseItem { internal InternalRealtimeResponseFunctionCallOutputItem(string id, string callId, string output) : base(InternalRealtimeItemType.FunctionCallOutput, id) { @@ -15,7 +15,7 @@ internal InternalRealtimeResponseFunctionCallOutputItem(string id, string callId Output = output; } - internal InternalRealtimeResponseFunctionCallOutputItem(InternalRealtimeResponseItemObject @object, InternalRealtimeItemType @type, string id, IDictionary additionalBinaryDataProperties, string callId, string output) : base(@object, @type, id, additionalBinaryDataProperties) + internal InternalRealtimeResponseFunctionCallOutputItem(InternalRealtimeConversationResponseItemObject @object, InternalRealtimeItemType @type, string id, IDictionary additionalBinaryDataProperties, string callId, string output) : base(@object, @type, id, additionalBinaryDataProperties) { CallId = callId; Output = output; diff --git a/src/Generated/Models/InternalRealtimeResponseItemObject.cs b/src/Generated/Models/InternalRealtimeResponseItemObject.cs deleted file mode 100644 index d5c5d6c5..00000000 --- a/src/Generated/Models/InternalRealtimeResponseItemObject.cs +++ /dev/null @@ -1,41 +0,0 @@ -// - -#nullable disable - -using System; -using System.ComponentModel; -using OpenAI; - -namespace OpenAI.RealtimeConversation -{ - internal readonly partial struct InternalRealtimeResponseItemObject : IEquatable - { - private readonly string _value; - private const string RealtimeItemValue = "realtime.item"; - - public InternalRealtimeResponseItemObject(string value) - { - Argument.AssertNotNull(value, nameof(value)); - - _value = value; - } - - public static InternalRealtimeResponseItemObject RealtimeItem { get; } = new InternalRealtimeResponseItemObject(RealtimeItemValue); - - public static bool operator ==(InternalRealtimeResponseItemObject left, InternalRealtimeResponseItemObject right) => left.Equals(right); - - public static bool operator !=(InternalRealtimeResponseItemObject left, InternalRealtimeResponseItemObject right) => !left.Equals(right); - - public static implicit operator InternalRealtimeResponseItemObject(string value) => new InternalRealtimeResponseItemObject(value); - - [EditorBrowsable(EditorBrowsableState.Never)] - public override bool Equals(object obj) => obj is InternalRealtimeResponseItemObject other && Equals(other); - - public bool Equals(InternalRealtimeResponseItemObject 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; - } -} diff --git a/src/Generated/Models/InternalRealtimeResponseMessageItem.Serialization.cs b/src/Generated/Models/InternalRealtimeResponseMessageItem.Serialization.cs index fc7df83e..d0fa5147 100644 --- a/src/Generated/Models/InternalRealtimeResponseMessageItem.Serialization.cs +++ b/src/Generated/Models/InternalRealtimeResponseMessageItem.Serialization.cs @@ -32,16 +32,6 @@ protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWri throw new FormatException($"The model {nameof(InternalRealtimeResponseMessageItem)} does not support writing '{format}' format."); } base.JsonModelWriteCore(writer, options); - if (true && _additionalBinaryDataProperties?.ContainsKey("content") != true) - { - writer.WritePropertyName("content"u8); - writer.WriteStartArray(); - foreach (ConversationContentPart item in Content) - { - writer.WriteObjectValue(item, options); - } - writer.WriteEndArray(); - } if (_additionalBinaryDataProperties?.ContainsKey("status") != true) { writer.WritePropertyName("status"u8); @@ -52,11 +42,21 @@ protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWri writer.WritePropertyName("role"u8); writer.WriteStringValue(Role.ToString()); } + if (true && _additionalBinaryDataProperties?.ContainsKey("content") != true) + { + writer.WritePropertyName("content"u8); + writer.WriteStartArray(); + foreach (ConversationContentPart item in Content) + { + writer.WriteObjectValue(item, options); + } + writer.WriteEndArray(); + } } InternalRealtimeResponseMessageItem IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (InternalRealtimeResponseMessageItem)JsonModelCreateCore(ref reader, options); - protected override InternalRealtimeResponseItem JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + protected override InternalRealtimeConversationResponseItem JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; if (format != "J") @@ -73,18 +73,18 @@ internal static InternalRealtimeResponseMessageItem DeserializeInternalRealtimeR { return null; } - InternalRealtimeResponseItemObject @object = default; + InternalRealtimeConversationResponseItemObject @object = default; InternalRealtimeItemType @type = default; string id = default; IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); - IReadOnlyList content = default; ConversationItemStatus status = default; ConversationMessageRole role = default; + IReadOnlyList content = default; foreach (var prop in element.EnumerateObject()) { if (prop.NameEquals("object"u8)) { - @object = new InternalRealtimeResponseItemObject(prop.Value.GetString()); + @object = new InternalRealtimeConversationResponseItemObject(prop.Value.GetString()); continue; } if (prop.NameEquals("type"u8)) @@ -102,16 +102,6 @@ internal static InternalRealtimeResponseMessageItem DeserializeInternalRealtimeR id = prop.Value.GetString(); continue; } - if (prop.NameEquals("content"u8)) - { - List array = new List(); - foreach (var item in prop.Value.EnumerateArray()) - { - array.Add(ConversationContentPart.DeserializeConversationContentPart(item, options)); - } - content = array; - continue; - } if (prop.NameEquals("status"u8)) { status = new ConversationItemStatus(prop.Value.GetString()); @@ -122,6 +112,16 @@ internal static InternalRealtimeResponseMessageItem DeserializeInternalRealtimeR role = new ConversationMessageRole(prop.Value.GetString()); continue; } + if (prop.NameEquals("content"u8)) + { + List array = new List(); + foreach (var item in prop.Value.EnumerateArray()) + { + array.Add(ConversationContentPart.DeserializeConversationContentPart(item, options)); + } + content = array; + continue; + } if (true) { additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); @@ -132,9 +132,9 @@ internal static InternalRealtimeResponseMessageItem DeserializeInternalRealtimeR @type, id, additionalBinaryDataProperties, - content, status, - role); + role, + content); } BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); @@ -153,7 +153,7 @@ protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions InternalRealtimeResponseMessageItem IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (InternalRealtimeResponseMessageItem)PersistableModelCreateCore(data, options); - protected override InternalRealtimeResponseItem PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + protected override InternalRealtimeConversationResponseItem PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) { string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; switch (format) diff --git a/src/Generated/Models/InternalRealtimeResponseMessageItem.cs b/src/Generated/Models/InternalRealtimeResponseMessageItem.cs index 827580df..87bf3c1a 100644 --- a/src/Generated/Models/InternalRealtimeResponseMessageItem.cs +++ b/src/Generated/Models/InternalRealtimeResponseMessageItem.cs @@ -8,24 +8,22 @@ namespace OpenAI.RealtimeConversation { - internal partial class InternalRealtimeResponseMessageItem : InternalRealtimeResponseItem + internal partial class InternalRealtimeResponseMessageItem : InternalRealtimeConversationResponseItem { internal InternalRealtimeResponseMessageItem(string id, ConversationItemStatus status, ConversationMessageRole role) : base(InternalRealtimeItemType.Message, id) { - Content = new ChangeTrackingList(); Status = status; Role = role; + Content = new ChangeTrackingList(); } - internal InternalRealtimeResponseMessageItem(InternalRealtimeResponseItemObject @object, InternalRealtimeItemType @type, string id, IDictionary additionalBinaryDataProperties, IReadOnlyList content, ConversationItemStatus status, ConversationMessageRole role) : base(@object, @type, id, additionalBinaryDataProperties) + internal InternalRealtimeResponseMessageItem(InternalRealtimeConversationResponseItemObject @object, InternalRealtimeItemType @type, string id, IDictionary additionalBinaryDataProperties, ConversationItemStatus status, ConversationMessageRole role, IReadOnlyList content) : base(@object, @type, id, additionalBinaryDataProperties) { - Content = content; Status = status; Role = role; + Content = content; } - public IReadOnlyList Content { get; } - public ConversationItemStatus Status { get; } } } diff --git a/src/Generated/Models/InternalRealtimeResponseModality.cs b/src/Generated/Models/InternalRealtimeResponseModality.cs new file mode 100644 index 00000000..363f5e03 --- /dev/null +++ b/src/Generated/Models/InternalRealtimeResponseModality.cs @@ -0,0 +1,44 @@ +// + +#nullable disable + +using System; +using System.ComponentModel; +using OpenAI; + +namespace OpenAI.RealtimeConversation +{ + internal readonly partial struct InternalRealtimeResponseModality : IEquatable + { + private readonly string _value; + private const string TextValue = "text"; + private const string AudioValue = "audio"; + + public InternalRealtimeResponseModality(string value) + { + Argument.AssertNotNull(value, nameof(value)); + + _value = value; + } + + public static InternalRealtimeResponseModality Text { get; } = new InternalRealtimeResponseModality(TextValue); + + public static InternalRealtimeResponseModality Audio { get; } = new InternalRealtimeResponseModality(AudioValue); + + public static bool operator ==(InternalRealtimeResponseModality left, InternalRealtimeResponseModality right) => left.Equals(right); + + public static bool operator !=(InternalRealtimeResponseModality left, InternalRealtimeResponseModality right) => !left.Equals(right); + + public static implicit operator InternalRealtimeResponseModality(string value) => new InternalRealtimeResponseModality(value); + + [EditorBrowsable(EditorBrowsableState.Never)] + public override bool Equals(object obj) => obj is InternalRealtimeResponseModality other && Equals(other); + + public bool Equals(InternalRealtimeResponseModality 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; + } +} diff --git a/src/Generated/Models/InternalRealtimeResponseOutputAudioFormat.cs b/src/Generated/Models/InternalRealtimeResponseOutputAudioFormat.cs new file mode 100644 index 00000000..3eed3ffa --- /dev/null +++ b/src/Generated/Models/InternalRealtimeResponseOutputAudioFormat.cs @@ -0,0 +1,47 @@ +// + +#nullable disable + +using System; +using System.ComponentModel; +using OpenAI; + +namespace OpenAI.RealtimeConversation +{ + internal readonly partial struct InternalRealtimeResponseOutputAudioFormat : IEquatable + { + private readonly string _value; + private const string Pcm16Value = "pcm16"; + private const string G711UlawValue = "g711_ulaw"; + private const string G711AlawValue = "g711_alaw"; + + public InternalRealtimeResponseOutputAudioFormat(string value) + { + Argument.AssertNotNull(value, nameof(value)); + + _value = value; + } + + public static InternalRealtimeResponseOutputAudioFormat Pcm16 { get; } = new InternalRealtimeResponseOutputAudioFormat(Pcm16Value); + + public static InternalRealtimeResponseOutputAudioFormat G711Ulaw { get; } = new InternalRealtimeResponseOutputAudioFormat(G711UlawValue); + + public static InternalRealtimeResponseOutputAudioFormat G711Alaw { get; } = new InternalRealtimeResponseOutputAudioFormat(G711AlawValue); + + public static bool operator ==(InternalRealtimeResponseOutputAudioFormat left, InternalRealtimeResponseOutputAudioFormat right) => left.Equals(right); + + public static bool operator !=(InternalRealtimeResponseOutputAudioFormat left, InternalRealtimeResponseOutputAudioFormat right) => !left.Equals(right); + + public static implicit operator InternalRealtimeResponseOutputAudioFormat(string value) => new InternalRealtimeResponseOutputAudioFormat(value); + + [EditorBrowsable(EditorBrowsableState.Never)] + public override bool Equals(object obj) => obj is InternalRealtimeResponseOutputAudioFormat other && Equals(other); + + public bool Equals(InternalRealtimeResponseOutputAudioFormat 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; + } +} diff --git a/src/Generated/Models/InternalRealtimeResponseStatusDetailsError.Serialization.cs b/src/Generated/Models/InternalRealtimeResponseStatusDetailsError.Serialization.cs new file mode 100644 index 00000000..897183a1 --- /dev/null +++ b/src/Generated/Models/InternalRealtimeResponseStatusDetailsError.Serialization.cs @@ -0,0 +1,152 @@ +// + +#nullable disable + +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; +using OpenAI; + +namespace OpenAI.RealtimeConversation +{ + internal partial class InternalRealtimeResponseStatusDetailsError : IJsonModel + { + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(InternalRealtimeResponseStatusDetailsError)} does not support writing '{format}' format."); + } + if (Optional.IsDefined(Type) && _additionalBinaryDataProperties?.ContainsKey("type") != true) + { + writer.WritePropertyName("type"u8); + writer.WriteStringValue(Type); + } + if (Optional.IsDefined(Code) && _additionalBinaryDataProperties?.ContainsKey("code") != true) + { + writer.WritePropertyName("code"u8); + writer.WriteStringValue(Code); + } + if (true && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + if (ModelSerializationExtensions.IsSentinelValue(item.Value)) + { + continue; + } + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + InternalRealtimeResponseStatusDetailsError IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + protected virtual InternalRealtimeResponseStatusDetailsError JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(InternalRealtimeResponseStatusDetailsError)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeInternalRealtimeResponseStatusDetailsError(document.RootElement, options); + } + + internal static InternalRealtimeResponseStatusDetailsError DeserializeInternalRealtimeResponseStatusDetailsError(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + string @type = default; + string code = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("code"u8)) + { + code = prop.Value.GetString(); + continue; + } + if (true) + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new InternalRealtimeResponseStatusDetailsError(@type, code, additionalBinaryDataProperties); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(InternalRealtimeResponseStatusDetailsError)} does not support writing '{options.Format}' format."); + } + } + + InternalRealtimeResponseStatusDetailsError IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + protected virtual InternalRealtimeResponseStatusDetailsError PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeInternalRealtimeResponseStatusDetailsError(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(InternalRealtimeResponseStatusDetailsError)} does not support reading '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + + public static implicit operator BinaryContent(InternalRealtimeResponseStatusDetailsError internalRealtimeResponseStatusDetailsError) + { + if (internalRealtimeResponseStatusDetailsError == null) + { + return null; + } + return BinaryContent.Create(internalRealtimeResponseStatusDetailsError, ModelSerializationExtensions.WireOptions); + } + + public static explicit operator InternalRealtimeResponseStatusDetailsError(ClientResult result) + { + using PipelineResponse response = result.GetRawResponse(); + using JsonDocument document = JsonDocument.Parse(response.Content); + return DeserializeInternalRealtimeResponseStatusDetailsError(document.RootElement, ModelSerializationExtensions.WireOptions); + } + } +} diff --git a/src/Generated/Models/InternalRealtimeResponseStatusDetailsError.cs b/src/Generated/Models/InternalRealtimeResponseStatusDetailsError.cs new file mode 100644 index 00000000..6a93dd32 --- /dev/null +++ b/src/Generated/Models/InternalRealtimeResponseStatusDetailsError.cs @@ -0,0 +1,35 @@ +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace OpenAI.RealtimeConversation +{ + internal partial class InternalRealtimeResponseStatusDetailsError + { + private protected IDictionary _additionalBinaryDataProperties; + + internal InternalRealtimeResponseStatusDetailsError() + { + } + + internal InternalRealtimeResponseStatusDetailsError(string @type, string code, IDictionary additionalBinaryDataProperties) + { + Type = @type; + Code = code; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + public string Type { get; } + + public string Code { get; } + + internal IDictionary SerializedAdditionalRawData + { + get => _additionalBinaryDataProperties; + set => _additionalBinaryDataProperties = value; + } + } +} diff --git a/src/Generated/Models/InternalRealtimeResponseStatusDetailsType.cs b/src/Generated/Models/InternalRealtimeResponseStatusDetailsType.cs new file mode 100644 index 00000000..19492c90 --- /dev/null +++ b/src/Generated/Models/InternalRealtimeResponseStatusDetailsType.cs @@ -0,0 +1,50 @@ +// + +#nullable disable + +using System; +using System.ComponentModel; +using OpenAI; + +namespace OpenAI.RealtimeConversation +{ + internal readonly partial struct InternalRealtimeResponseStatusDetailsType : IEquatable + { + private readonly string _value; + private const string CompletedValue = "completed"; + private const string CancelledValue = "cancelled"; + private const string FailedValue = "failed"; + private const string IncompleteValue = "incomplete"; + + public InternalRealtimeResponseStatusDetailsType(string value) + { + Argument.AssertNotNull(value, nameof(value)); + + _value = value; + } + + public static InternalRealtimeResponseStatusDetailsType Completed { get; } = new InternalRealtimeResponseStatusDetailsType(CompletedValue); + + public static InternalRealtimeResponseStatusDetailsType Cancelled { get; } = new InternalRealtimeResponseStatusDetailsType(CancelledValue); + + public static InternalRealtimeResponseStatusDetailsType Failed { get; } = new InternalRealtimeResponseStatusDetailsType(FailedValue); + + public static InternalRealtimeResponseStatusDetailsType Incomplete { get; } = new InternalRealtimeResponseStatusDetailsType(IncompleteValue); + + public static bool operator ==(InternalRealtimeResponseStatusDetailsType left, InternalRealtimeResponseStatusDetailsType right) => left.Equals(right); + + public static bool operator !=(InternalRealtimeResponseStatusDetailsType left, InternalRealtimeResponseStatusDetailsType right) => !left.Equals(right); + + public static implicit operator InternalRealtimeResponseStatusDetailsType(string value) => new InternalRealtimeResponseStatusDetailsType(value); + + [EditorBrowsable(EditorBrowsableState.Never)] + public override bool Equals(object obj) => obj is InternalRealtimeResponseStatusDetailsType other && Equals(other); + + public bool Equals(InternalRealtimeResponseStatusDetailsType 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; + } +} diff --git a/src/Generated/Models/InternalRealtimeResponseVoice.cs b/src/Generated/Models/InternalRealtimeResponseVoice.cs new file mode 100644 index 00000000..488f3825 --- /dev/null +++ b/src/Generated/Models/InternalRealtimeResponseVoice.cs @@ -0,0 +1,62 @@ +// + +#nullable disable + +using System; +using System.ComponentModel; +using OpenAI; + +namespace OpenAI.RealtimeConversation +{ + internal readonly partial struct InternalRealtimeResponseVoice : IEquatable + { + private readonly string _value; + private const string AlloyValue = "alloy"; + private const string AshValue = "ash"; + private const string BalladValue = "ballad"; + private const string CoralValue = "coral"; + private const string EchoValue = "echo"; + private const string SageValue = "sage"; + private const string ShimmerValue = "shimmer"; + private const string VerseValue = "verse"; + + public InternalRealtimeResponseVoice(string value) + { + Argument.AssertNotNull(value, nameof(value)); + + _value = value; + } + + public static InternalRealtimeResponseVoice Alloy { get; } = new InternalRealtimeResponseVoice(AlloyValue); + + public static InternalRealtimeResponseVoice Ash { get; } = new InternalRealtimeResponseVoice(AshValue); + + public static InternalRealtimeResponseVoice Ballad { get; } = new InternalRealtimeResponseVoice(BalladValue); + + public static InternalRealtimeResponseVoice Coral { get; } = new InternalRealtimeResponseVoice(CoralValue); + + public static InternalRealtimeResponseVoice Echo { get; } = new InternalRealtimeResponseVoice(EchoValue); + + public static InternalRealtimeResponseVoice Sage { get; } = new InternalRealtimeResponseVoice(SageValue); + + public static InternalRealtimeResponseVoice Shimmer { get; } = new InternalRealtimeResponseVoice(ShimmerValue); + + public static InternalRealtimeResponseVoice Verse { get; } = new InternalRealtimeResponseVoice(VerseValue); + + public static bool operator ==(InternalRealtimeResponseVoice left, InternalRealtimeResponseVoice right) => left.Equals(right); + + public static bool operator !=(InternalRealtimeResponseVoice left, InternalRealtimeResponseVoice right) => !left.Equals(right); + + public static implicit operator InternalRealtimeResponseVoice(string value) => new InternalRealtimeResponseVoice(value); + + [EditorBrowsable(EditorBrowsableState.Never)] + public override bool Equals(object obj) => obj is InternalRealtimeResponseVoice other && Equals(other); + + public bool Equals(InternalRealtimeResponseVoice 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; + } +} diff --git a/src/Generated/Models/InternalRealtimeServerEventErrorError.Serialization.cs b/src/Generated/Models/InternalRealtimeServerEventErrorError.Serialization.cs index b9180e74..6204d19b 100644 --- a/src/Generated/Models/InternalRealtimeServerEventErrorError.Serialization.cs +++ b/src/Generated/Models/InternalRealtimeServerEventErrorError.Serialization.cs @@ -13,6 +13,10 @@ namespace OpenAI.RealtimeConversation { internal partial class InternalRealtimeServerEventErrorError : IJsonModel { + internal InternalRealtimeServerEventErrorError() + { + } + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { writer.WriteStartObject(); @@ -27,30 +31,51 @@ protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWrit { throw new FormatException($"The model {nameof(InternalRealtimeServerEventErrorError)} does not support writing '{format}' format."); } - if (Optional.IsDefined(Type) && _additionalBinaryDataProperties?.ContainsKey("type") != true) + if (_additionalBinaryDataProperties?.ContainsKey("type") != true) { writer.WritePropertyName("type"u8); writer.WriteStringValue(Type); } if (Optional.IsDefined(Code) && _additionalBinaryDataProperties?.ContainsKey("code") != true) { - writer.WritePropertyName("code"u8); - writer.WriteStringValue(Code); + if (Code != null) + { + writer.WritePropertyName("code"u8); + writer.WriteStringValue(Code); + } + else + { + writer.WriteNull("code"u8); + } } - if (Optional.IsDefined(Message) && _additionalBinaryDataProperties?.ContainsKey("message") != true) + if (_additionalBinaryDataProperties?.ContainsKey("message") != true) { writer.WritePropertyName("message"u8); writer.WriteStringValue(Message); } if (Optional.IsDefined(Param) && _additionalBinaryDataProperties?.ContainsKey("param") != true) { - writer.WritePropertyName("param"u8); - writer.WriteStringValue(Param); + if (Param != null) + { + writer.WritePropertyName("param"u8); + writer.WriteStringValue(Param); + } + else + { + writer.WriteNull("param"u8); + } } if (Optional.IsDefined(EventId) && _additionalBinaryDataProperties?.ContainsKey("event_id") != true) { - writer.WritePropertyName("event_id"u8); - writer.WriteStringValue(EventId); + if (EventId != null) + { + writer.WritePropertyName("event_id"u8); + writer.WriteStringValue(EventId); + } + else + { + writer.WriteNull("eventId"u8); + } } if (true && _additionalBinaryDataProperties != null) { @@ -107,6 +132,11 @@ internal static InternalRealtimeServerEventErrorError DeserializeInternalRealtim } if (prop.NameEquals("code"u8)) { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + code = null; + continue; + } code = prop.Value.GetString(); continue; } @@ -117,11 +147,21 @@ internal static InternalRealtimeServerEventErrorError DeserializeInternalRealtim } if (prop.NameEquals("param"u8)) { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + @param = null; + continue; + } @param = prop.Value.GetString(); continue; } if (prop.NameEquals("event_id"u8)) { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + eventId = null; + continue; + } eventId = prop.Value.GetString(); continue; } diff --git a/src/Generated/Models/InternalRealtimeServerEventErrorError.cs b/src/Generated/Models/InternalRealtimeServerEventErrorError.cs index 41498342..07233ba4 100644 --- a/src/Generated/Models/InternalRealtimeServerEventErrorError.cs +++ b/src/Generated/Models/InternalRealtimeServerEventErrorError.cs @@ -11,8 +11,10 @@ internal partial class InternalRealtimeServerEventErrorError { private protected IDictionary _additionalBinaryDataProperties; - internal InternalRealtimeServerEventErrorError() + internal InternalRealtimeServerEventErrorError(string @type, string message) { + Type = @type; + Message = message; } internal InternalRealtimeServerEventErrorError(string @type, string code, string message, string @param, string eventId, IDictionary additionalBinaryDataProperties) diff --git a/src/Generated/Models/InternalRealtimeServerVadTurnDetection.Serialization.cs b/src/Generated/Models/InternalRealtimeServerVadTurnDetection.Serialization.cs index 6bc541de..6323d180 100644 --- a/src/Generated/Models/InternalRealtimeServerVadTurnDetection.Serialization.cs +++ b/src/Generated/Models/InternalRealtimeServerVadTurnDetection.Serialization.cs @@ -43,6 +43,11 @@ protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWri writer.WritePropertyName("silence_duration_ms"u8); this.SerializeSilenceDurationMs(writer, options); } + if (Optional.IsDefined(CreateResponse) && _additionalBinaryDataProperties?.ContainsKey("create_response") != true) + { + writer.WritePropertyName("create_response"u8); + writer.WriteBooleanValue(CreateResponse.Value); + } } InternalRealtimeServerVadTurnDetection IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (InternalRealtimeServerVadTurnDetection)JsonModelCreateCore(ref reader, options); @@ -69,6 +74,7 @@ internal static InternalRealtimeServerVadTurnDetection DeserializeInternalRealti float? threshold = default; TimeSpan? prefixPaddingMs = default; TimeSpan? silenceDurationMs = default; + bool? createResponse = default; foreach (var prop in element.EnumerateObject()) { if (prop.NameEquals("type"u8)) @@ -95,12 +101,27 @@ internal static InternalRealtimeServerVadTurnDetection DeserializeInternalRealti DeserializeMillisecondDuration(prop, ref silenceDurationMs); continue; } + if (prop.NameEquals("create_response"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + createResponse = prop.Value.GetBoolean(); + continue; + } if (true) { additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); } } - return new InternalRealtimeServerVadTurnDetection(kind, additionalBinaryDataProperties, threshold, prefixPaddingMs, silenceDurationMs); + return new InternalRealtimeServerVadTurnDetection( + kind, + additionalBinaryDataProperties, + threshold, + prefixPaddingMs, + silenceDurationMs, + createResponse); } BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); diff --git a/src/Generated/Models/InternalRealtimeServerVadTurnDetection.cs b/src/Generated/Models/InternalRealtimeServerVadTurnDetection.cs index 2d781bf8..6e89b9f0 100644 --- a/src/Generated/Models/InternalRealtimeServerVadTurnDetection.cs +++ b/src/Generated/Models/InternalRealtimeServerVadTurnDetection.cs @@ -13,11 +13,12 @@ public InternalRealtimeServerVadTurnDetection() : base(RealtimeConversation.Conv { } - internal InternalRealtimeServerVadTurnDetection(RealtimeConversation.ConversationTurnDetectionKind kind, IDictionary additionalBinaryDataProperties, float? threshold, TimeSpan? prefixPaddingMs, TimeSpan? silenceDurationMs) : base(kind, additionalBinaryDataProperties) + internal InternalRealtimeServerVadTurnDetection(RealtimeConversation.ConversationTurnDetectionKind kind, IDictionary additionalBinaryDataProperties, float? threshold, TimeSpan? prefixPaddingMs, TimeSpan? silenceDurationMs, bool? createResponse) : base(kind, additionalBinaryDataProperties) { Threshold = threshold; PrefixPaddingMs = prefixPaddingMs; SilenceDurationMs = silenceDurationMs; + CreateResponse = createResponse; } public float? Threshold { get; set; } @@ -25,5 +26,7 @@ internal InternalRealtimeServerVadTurnDetection(RealtimeConversation.Conversatio public TimeSpan? PrefixPaddingMs { get; set; } public TimeSpan? SilenceDurationMs { get; set; } + + public bool? CreateResponse { get; set; } } } diff --git a/src/Generated/Models/InternalRunStepDeltaStepDetailsToolCallsFileSearchObject.Serialization.cs b/src/Generated/Models/InternalRunStepDeltaStepDetailsToolCallsFileSearchObject.Serialization.cs index b58e9c1f..20fd0364 100644 --- a/src/Generated/Models/InternalRunStepDeltaStepDetailsToolCallsFileSearchObject.Serialization.cs +++ b/src/Generated/Models/InternalRunStepDeltaStepDetailsToolCallsFileSearchObject.Serialization.cs @@ -45,7 +45,7 @@ protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWri if (_additionalBinaryDataProperties?.ContainsKey("file_search") != true) { writer.WritePropertyName("file_search"u8); - writer.WriteObjectValue(FileSearch, options); + writer.WriteObjectValue(FileSearch, options); } } @@ -72,7 +72,7 @@ internal static InternalRunStepDeltaStepDetailsToolCallsFileSearchObject Deseria IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); int index = default; string id = default; - InternalRunStepDeltaStepDetailsToolCallsFileSearchObjectFileSearch fileSearch = default; + InternalRunStepDetailsToolCallsFileSearchObjectFileSearch fileSearch = default; foreach (var prop in element.EnumerateObject()) { if (prop.NameEquals("type"u8)) @@ -92,7 +92,7 @@ internal static InternalRunStepDeltaStepDetailsToolCallsFileSearchObject Deseria } if (prop.NameEquals("file_search"u8)) { - fileSearch = InternalRunStepDeltaStepDetailsToolCallsFileSearchObjectFileSearch.DeserializeInternalRunStepDeltaStepDetailsToolCallsFileSearchObjectFileSearch(prop.Value, options); + fileSearch = InternalRunStepDetailsToolCallsFileSearchObjectFileSearch.DeserializeInternalRunStepDetailsToolCallsFileSearchObjectFileSearch(prop.Value, options); continue; } if (true) diff --git a/src/Generated/Models/InternalRunStepDeltaStepDetailsToolCallsFileSearchObject.cs b/src/Generated/Models/InternalRunStepDeltaStepDetailsToolCallsFileSearchObject.cs index b0da34cf..59052b52 100644 --- a/src/Generated/Models/InternalRunStepDeltaStepDetailsToolCallsFileSearchObject.cs +++ b/src/Generated/Models/InternalRunStepDeltaStepDetailsToolCallsFileSearchObject.cs @@ -9,13 +9,13 @@ namespace OpenAI.Assistants { internal partial class InternalRunStepDeltaStepDetailsToolCallsFileSearchObject : InternalRunStepDeltaStepDetailsToolCallsObjectToolCallsObject { - internal InternalRunStepDeltaStepDetailsToolCallsFileSearchObject(int index, InternalRunStepDeltaStepDetailsToolCallsFileSearchObjectFileSearch fileSearch) : base("file_search") + internal InternalRunStepDeltaStepDetailsToolCallsFileSearchObject(int index, InternalRunStepDetailsToolCallsFileSearchObjectFileSearch fileSearch) : base("file_search") { Index = index; FileSearch = fileSearch; } - internal InternalRunStepDeltaStepDetailsToolCallsFileSearchObject(string @type, IDictionary additionalBinaryDataProperties, int index, string id, InternalRunStepDeltaStepDetailsToolCallsFileSearchObjectFileSearch fileSearch) : base(@type, additionalBinaryDataProperties) + internal InternalRunStepDeltaStepDetailsToolCallsFileSearchObject(string @type, IDictionary additionalBinaryDataProperties, int index, string id, InternalRunStepDetailsToolCallsFileSearchObjectFileSearch fileSearch) : base(@type, additionalBinaryDataProperties) { Index = index; Id = id; @@ -25,7 +25,5 @@ internal InternalRunStepDeltaStepDetailsToolCallsFileSearchObject(string @type, public int Index { get; } public string Id { get; } - - public InternalRunStepDeltaStepDetailsToolCallsFileSearchObjectFileSearch FileSearch { get; } } } diff --git a/src/Generated/Models/InternalFinetuneChatRequestInput.Serialization.cs b/src/Generated/Models/InternalTodoFineTuneChatRequestInput.Serialization.cs similarity index 71% rename from src/Generated/Models/InternalFinetuneChatRequestInput.Serialization.cs rename to src/Generated/Models/InternalTodoFineTuneChatRequestInput.Serialization.cs index 2f5a99d7..ce3cb7ed 100644 --- a/src/Generated/Models/InternalFinetuneChatRequestInput.Serialization.cs +++ b/src/Generated/Models/InternalTodoFineTuneChatRequestInput.Serialization.cs @@ -12,9 +12,9 @@ namespace OpenAI.FineTuning { - internal partial class InternalFinetuneChatRequestInput : IJsonModel + internal partial class InternalTodoFineTuneChatRequestInput : IJsonModel { - void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { writer.WriteStartObject(); JsonModelWriteCore(writer, options); @@ -23,10 +23,10 @@ void IJsonModel.Write(Utf8JsonWriter writer, M protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) { - string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; if (format != "J") { - throw new FormatException($"The model {nameof(InternalFinetuneChatRequestInput)} does not support writing '{format}' format."); + throw new FormatException($"The model {nameof(InternalTodoFineTuneChatRequestInput)} does not support writing '{format}' format."); } if (Optional.IsCollectionDefined(Messages) && _additionalBinaryDataProperties?.ContainsKey("messages") != true) { @@ -96,20 +96,20 @@ protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWrit } } - InternalFinetuneChatRequestInput IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + InternalTodoFineTuneChatRequestInput IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); - protected virtual InternalFinetuneChatRequestInput JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + protected virtual InternalTodoFineTuneChatRequestInput JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { - string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; if (format != "J") { - throw new FormatException($"The model {nameof(InternalFinetuneChatRequestInput)} does not support reading '{format}' format."); + throw new FormatException($"The model {nameof(InternalTodoFineTuneChatRequestInput)} does not support reading '{format}' format."); } using JsonDocument document = JsonDocument.ParseValue(ref reader); - return DeserializeInternalFinetuneChatRequestInput(document.RootElement, options); + return DeserializeInternalTodoFineTuneChatRequestInput(document.RootElement, options); } - internal static InternalFinetuneChatRequestInput DeserializeInternalFinetuneChatRequestInput(JsonElement element, ModelReaderWriterOptions options) + internal static InternalTodoFineTuneChatRequestInput DeserializeInternalTodoFineTuneChatRequestInput(JsonElement element, ModelReaderWriterOptions options) { if (element.ValueKind == JsonValueKind.Null) { @@ -185,56 +185,56 @@ internal static InternalFinetuneChatRequestInput DeserializeInternalFinetuneChat additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); } } - return new InternalFinetuneChatRequestInput(messages ?? new ChangeTrackingList(), tools ?? new ChangeTrackingList(), parallelToolCalls, functions ?? new ChangeTrackingList(), additionalBinaryDataProperties); + return new InternalTodoFineTuneChatRequestInput(messages ?? new ChangeTrackingList(), tools ?? new ChangeTrackingList(), parallelToolCalls, functions ?? new ChangeTrackingList(), additionalBinaryDataProperties); } - BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) { - string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; switch (format) { case "J": return ModelReaderWriter.Write(this, options); default: - throw new FormatException($"The model {nameof(InternalFinetuneChatRequestInput)} does not support writing '{options.Format}' format."); + throw new FormatException($"The model {nameof(InternalTodoFineTuneChatRequestInput)} does not support writing '{options.Format}' format."); } } - InternalFinetuneChatRequestInput IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + InternalTodoFineTuneChatRequestInput IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); - protected virtual InternalFinetuneChatRequestInput PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + protected virtual InternalTodoFineTuneChatRequestInput PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) { - string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; switch (format) { case "J": using (JsonDocument document = JsonDocument.Parse(data)) { - return DeserializeInternalFinetuneChatRequestInput(document.RootElement, options); + return DeserializeInternalTodoFineTuneChatRequestInput(document.RootElement, options); } default: - throw new FormatException($"The model {nameof(InternalFinetuneChatRequestInput)} does not support reading '{options.Format}' format."); + throw new FormatException($"The model {nameof(InternalTodoFineTuneChatRequestInput)} does not support reading '{options.Format}' format."); } } - string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; - public static implicit operator BinaryContent(InternalFinetuneChatRequestInput internalFinetuneChatRequestInput) + public static implicit operator BinaryContent(InternalTodoFineTuneChatRequestInput internalTodoFineTuneChatRequestInput) { - if (internalFinetuneChatRequestInput == null) + if (internalTodoFineTuneChatRequestInput == null) { return null; } - return BinaryContent.Create(internalFinetuneChatRequestInput, ModelSerializationExtensions.WireOptions); + return BinaryContent.Create(internalTodoFineTuneChatRequestInput, ModelSerializationExtensions.WireOptions); } - public static explicit operator InternalFinetuneChatRequestInput(ClientResult result) + public static explicit operator InternalTodoFineTuneChatRequestInput(ClientResult result) { using PipelineResponse response = result.GetRawResponse(); using JsonDocument document = JsonDocument.Parse(response.Content); - return DeserializeInternalFinetuneChatRequestInput(document.RootElement, ModelSerializationExtensions.WireOptions); + return DeserializeInternalTodoFineTuneChatRequestInput(document.RootElement, ModelSerializationExtensions.WireOptions); } } } diff --git a/src/Generated/Models/InternalFinetuneChatRequestInput.cs b/src/Generated/Models/InternalTodoFineTuneChatRequestInput.cs similarity index 76% rename from src/Generated/Models/InternalFinetuneChatRequestInput.cs rename to src/Generated/Models/InternalTodoFineTuneChatRequestInput.cs index 6588ee14..165135c4 100644 --- a/src/Generated/Models/InternalFinetuneChatRequestInput.cs +++ b/src/Generated/Models/InternalTodoFineTuneChatRequestInput.cs @@ -9,18 +9,18 @@ namespace OpenAI.FineTuning { - internal partial class InternalFinetuneChatRequestInput + internal partial class InternalTodoFineTuneChatRequestInput { private protected IDictionary _additionalBinaryDataProperties; - public InternalFinetuneChatRequestInput() + public InternalTodoFineTuneChatRequestInput() { Messages = new ChangeTrackingList(); Tools = new ChangeTrackingList(); Functions = new ChangeTrackingList(); } - internal InternalFinetuneChatRequestInput(IList messages, IList tools, bool? parallelToolCalls, IList functions, IDictionary additionalBinaryDataProperties) + internal InternalTodoFineTuneChatRequestInput(IList messages, IList tools, bool? parallelToolCalls, IList functions, IDictionary additionalBinaryDataProperties) { Messages = messages; Tools = tools; diff --git a/src/Generated/Models/InternalFinetuneCompletionRequestInput.Serialization.cs b/src/Generated/Models/InternalTodoFineTuneCompletionRequestInput.Serialization.cs similarity index 56% rename from src/Generated/Models/InternalFinetuneCompletionRequestInput.Serialization.cs rename to src/Generated/Models/InternalTodoFineTuneCompletionRequestInput.Serialization.cs index 30c68454..ca2640d3 100644 --- a/src/Generated/Models/InternalFinetuneCompletionRequestInput.Serialization.cs +++ b/src/Generated/Models/InternalTodoFineTuneCompletionRequestInput.Serialization.cs @@ -11,9 +11,9 @@ namespace OpenAI.FineTuning { - internal partial class InternalFinetuneCompletionRequestInput : IJsonModel + internal partial class InternalTodoFineTuneCompletionRequestInput : IJsonModel { - void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { writer.WriteStartObject(); JsonModelWriteCore(writer, options); @@ -22,10 +22,10 @@ void IJsonModel.Write(Utf8JsonWriter wri protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) { - string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; if (format != "J") { - throw new FormatException($"The model {nameof(InternalFinetuneCompletionRequestInput)} does not support writing '{format}' format."); + throw new FormatException($"The model {nameof(InternalTodoFineTuneCompletionRequestInput)} does not support writing '{format}' format."); } if (Optional.IsDefined(Prompt) && _additionalBinaryDataProperties?.ContainsKey("prompt") != true) { @@ -58,20 +58,20 @@ protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWrit } } - InternalFinetuneCompletionRequestInput IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + InternalTodoFineTuneCompletionRequestInput IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); - protected virtual InternalFinetuneCompletionRequestInput JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + protected virtual InternalTodoFineTuneCompletionRequestInput JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { - string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; if (format != "J") { - throw new FormatException($"The model {nameof(InternalFinetuneCompletionRequestInput)} does not support reading '{format}' format."); + throw new FormatException($"The model {nameof(InternalTodoFineTuneCompletionRequestInput)} does not support reading '{format}' format."); } using JsonDocument document = JsonDocument.ParseValue(ref reader); - return DeserializeInternalFinetuneCompletionRequestInput(document.RootElement, options); + return DeserializeInternalTodoFineTuneCompletionRequestInput(document.RootElement, options); } - internal static InternalFinetuneCompletionRequestInput DeserializeInternalFinetuneCompletionRequestInput(JsonElement element, ModelReaderWriterOptions options) + internal static InternalTodoFineTuneCompletionRequestInput DeserializeInternalTodoFineTuneCompletionRequestInput(JsonElement element, ModelReaderWriterOptions options) { if (element.ValueKind == JsonValueKind.Null) { @@ -97,56 +97,56 @@ internal static InternalFinetuneCompletionRequestInput DeserializeInternalFinetu additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); } } - return new InternalFinetuneCompletionRequestInput(prompt, completion, additionalBinaryDataProperties); + return new InternalTodoFineTuneCompletionRequestInput(prompt, completion, additionalBinaryDataProperties); } - BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) { - string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; switch (format) { case "J": return ModelReaderWriter.Write(this, options); default: - throw new FormatException($"The model {nameof(InternalFinetuneCompletionRequestInput)} does not support writing '{options.Format}' format."); + throw new FormatException($"The model {nameof(InternalTodoFineTuneCompletionRequestInput)} does not support writing '{options.Format}' format."); } } - InternalFinetuneCompletionRequestInput IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + InternalTodoFineTuneCompletionRequestInput IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); - protected virtual InternalFinetuneCompletionRequestInput PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + protected virtual InternalTodoFineTuneCompletionRequestInput PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) { - string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; switch (format) { case "J": using (JsonDocument document = JsonDocument.Parse(data)) { - return DeserializeInternalFinetuneCompletionRequestInput(document.RootElement, options); + return DeserializeInternalTodoFineTuneCompletionRequestInput(document.RootElement, options); } default: - throw new FormatException($"The model {nameof(InternalFinetuneCompletionRequestInput)} does not support reading '{options.Format}' format."); + throw new FormatException($"The model {nameof(InternalTodoFineTuneCompletionRequestInput)} does not support reading '{options.Format}' format."); } } - string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; - public static implicit operator BinaryContent(InternalFinetuneCompletionRequestInput internalFinetuneCompletionRequestInput) + public static implicit operator BinaryContent(InternalTodoFineTuneCompletionRequestInput internalTodoFineTuneCompletionRequestInput) { - if (internalFinetuneCompletionRequestInput == null) + if (internalTodoFineTuneCompletionRequestInput == null) { return null; } - return BinaryContent.Create(internalFinetuneCompletionRequestInput, ModelSerializationExtensions.WireOptions); + return BinaryContent.Create(internalTodoFineTuneCompletionRequestInput, ModelSerializationExtensions.WireOptions); } - public static explicit operator InternalFinetuneCompletionRequestInput(ClientResult result) + public static explicit operator InternalTodoFineTuneCompletionRequestInput(ClientResult result) { using PipelineResponse response = result.GetRawResponse(); using JsonDocument document = JsonDocument.Parse(response.Content); - return DeserializeInternalFinetuneCompletionRequestInput(document.RootElement, ModelSerializationExtensions.WireOptions); + return DeserializeInternalTodoFineTuneCompletionRequestInput(document.RootElement, ModelSerializationExtensions.WireOptions); } } } diff --git a/src/Generated/Models/InternalFinetuneCompletionRequestInput.cs b/src/Generated/Models/InternalTodoFineTuneCompletionRequestInput.cs similarity index 71% rename from src/Generated/Models/InternalFinetuneCompletionRequestInput.cs rename to src/Generated/Models/InternalTodoFineTuneCompletionRequestInput.cs index 77224a7f..f7292b95 100644 --- a/src/Generated/Models/InternalFinetuneCompletionRequestInput.cs +++ b/src/Generated/Models/InternalTodoFineTuneCompletionRequestInput.cs @@ -7,15 +7,15 @@ namespace OpenAI.FineTuning { - internal partial class InternalFinetuneCompletionRequestInput + internal partial class InternalTodoFineTuneCompletionRequestInput { private protected IDictionary _additionalBinaryDataProperties; - public InternalFinetuneCompletionRequestInput() + public InternalTodoFineTuneCompletionRequestInput() { } - internal InternalFinetuneCompletionRequestInput(string prompt, string completion, IDictionary additionalBinaryDataProperties) + internal InternalTodoFineTuneCompletionRequestInput(string prompt, string completion, IDictionary additionalBinaryDataProperties) { Prompt = prompt; Completion = completion; diff --git a/src/Generated/Models/InternalTodoFineTuneDPOMethod.Serialization.cs b/src/Generated/Models/InternalTodoFineTuneDPOMethod.Serialization.cs new file mode 100644 index 00000000..5c6d3fbe --- /dev/null +++ b/src/Generated/Models/InternalTodoFineTuneDPOMethod.Serialization.cs @@ -0,0 +1,145 @@ +// + +#nullable disable + +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; +using OpenAI; + +namespace OpenAI.FineTuning +{ + internal partial class InternalTodoFineTuneDPOMethod : IJsonModel + { + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(InternalTodoFineTuneDPOMethod)} does not support writing '{format}' format."); + } + if (Optional.IsDefined(Hyperparameters) && _additionalBinaryDataProperties?.ContainsKey("hyperparameters") != true) + { + writer.WritePropertyName("hyperparameters"u8); + writer.WriteObjectValue(Hyperparameters, options); + } + if (true && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + if (ModelSerializationExtensions.IsSentinelValue(item.Value)) + { + continue; + } + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + InternalTodoFineTuneDPOMethod IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + protected virtual InternalTodoFineTuneDPOMethod JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(InternalTodoFineTuneDPOMethod)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeInternalTodoFineTuneDPOMethod(document.RootElement, options); + } + + internal static InternalTodoFineTuneDPOMethod DeserializeInternalTodoFineTuneDPOMethod(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + InternalTodoFineTuneDPOMethodHyperparameters hyperparameters = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("hyperparameters"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + hyperparameters = InternalTodoFineTuneDPOMethodHyperparameters.DeserializeInternalTodoFineTuneDPOMethodHyperparameters(prop.Value, options); + continue; + } + if (true) + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new InternalTodoFineTuneDPOMethod(hyperparameters, additionalBinaryDataProperties); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(InternalTodoFineTuneDPOMethod)} does not support writing '{options.Format}' format."); + } + } + + InternalTodoFineTuneDPOMethod IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + protected virtual InternalTodoFineTuneDPOMethod PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeInternalTodoFineTuneDPOMethod(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(InternalTodoFineTuneDPOMethod)} does not support reading '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + + public static implicit operator BinaryContent(InternalTodoFineTuneDPOMethod internalTodoFineTuneDPOMethod) + { + if (internalTodoFineTuneDPOMethod == null) + { + return null; + } + return BinaryContent.Create(internalTodoFineTuneDPOMethod, ModelSerializationExtensions.WireOptions); + } + + public static explicit operator InternalTodoFineTuneDPOMethod(ClientResult result) + { + using PipelineResponse response = result.GetRawResponse(); + using JsonDocument document = JsonDocument.Parse(response.Content); + return DeserializeInternalTodoFineTuneDPOMethod(document.RootElement, ModelSerializationExtensions.WireOptions); + } + } +} diff --git a/src/Generated/Models/InternalTodoFineTuneDPOMethod.cs b/src/Generated/Models/InternalTodoFineTuneDPOMethod.cs new file mode 100644 index 00000000..15ee9dbc --- /dev/null +++ b/src/Generated/Models/InternalTodoFineTuneDPOMethod.cs @@ -0,0 +1,32 @@ +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace OpenAI.FineTuning +{ + internal partial class InternalTodoFineTuneDPOMethod + { + private protected IDictionary _additionalBinaryDataProperties; + + public InternalTodoFineTuneDPOMethod() + { + } + + internal InternalTodoFineTuneDPOMethod(InternalTodoFineTuneDPOMethodHyperparameters hyperparameters, IDictionary additionalBinaryDataProperties) + { + Hyperparameters = hyperparameters; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + public InternalTodoFineTuneDPOMethodHyperparameters Hyperparameters { get; set; } + + internal IDictionary SerializedAdditionalRawData + { + get => _additionalBinaryDataProperties; + set => _additionalBinaryDataProperties = value; + } + } +} diff --git a/src/Generated/Models/InternalTodoFineTuneDPOMethodHyperparameters.Serialization.cs b/src/Generated/Models/InternalTodoFineTuneDPOMethodHyperparameters.Serialization.cs new file mode 100644 index 00000000..8cb18f1b --- /dev/null +++ b/src/Generated/Models/InternalTodoFineTuneDPOMethodHyperparameters.Serialization.cs @@ -0,0 +1,218 @@ +// + +#nullable disable + +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; +using OpenAI; + +namespace OpenAI.FineTuning +{ + internal partial class InternalTodoFineTuneDPOMethodHyperparameters : IJsonModel + { + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(InternalTodoFineTuneDPOMethodHyperparameters)} does not support writing '{format}' format."); + } + if (Optional.IsDefined(Beta) && _additionalBinaryDataProperties?.ContainsKey("beta") != true) + { + writer.WritePropertyName("beta"u8); +#if NET6_0_OR_GREATER + writer.WriteRawValue(Beta); +#else + using (JsonDocument document = JsonDocument.Parse(Beta)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + if (Optional.IsDefined(BatchSize) && _additionalBinaryDataProperties?.ContainsKey("batch_size") != true) + { + writer.WritePropertyName("batch_size"u8); +#if NET6_0_OR_GREATER + writer.WriteRawValue(BatchSize); +#else + using (JsonDocument document = JsonDocument.Parse(BatchSize)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + if (Optional.IsDefined(LearningRateMultiplier) && _additionalBinaryDataProperties?.ContainsKey("learning_rate_multiplier") != true) + { + writer.WritePropertyName("learning_rate_multiplier"u8); +#if NET6_0_OR_GREATER + writer.WriteRawValue(LearningRateMultiplier); +#else + using (JsonDocument document = JsonDocument.Parse(LearningRateMultiplier)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + if (Optional.IsDefined(NEpochs) && _additionalBinaryDataProperties?.ContainsKey("n_epochs") != true) + { + writer.WritePropertyName("n_epochs"u8); +#if NET6_0_OR_GREATER + writer.WriteRawValue(NEpochs); +#else + using (JsonDocument document = JsonDocument.Parse(NEpochs)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + if (true && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + if (ModelSerializationExtensions.IsSentinelValue(item.Value)) + { + continue; + } + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + InternalTodoFineTuneDPOMethodHyperparameters IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + protected virtual InternalTodoFineTuneDPOMethodHyperparameters JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(InternalTodoFineTuneDPOMethodHyperparameters)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeInternalTodoFineTuneDPOMethodHyperparameters(document.RootElement, options); + } + + internal static InternalTodoFineTuneDPOMethodHyperparameters DeserializeInternalTodoFineTuneDPOMethodHyperparameters(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + BinaryData beta = default; + BinaryData batchSize = default; + BinaryData learningRateMultiplier = default; + BinaryData nEpochs = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("beta"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + beta = BinaryData.FromString(prop.Value.GetRawText()); + continue; + } + if (prop.NameEquals("batch_size"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + batchSize = BinaryData.FromString(prop.Value.GetRawText()); + continue; + } + if (prop.NameEquals("learning_rate_multiplier"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + learningRateMultiplier = BinaryData.FromString(prop.Value.GetRawText()); + continue; + } + if (prop.NameEquals("n_epochs"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + nEpochs = BinaryData.FromString(prop.Value.GetRawText()); + continue; + } + if (true) + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new InternalTodoFineTuneDPOMethodHyperparameters(beta, batchSize, learningRateMultiplier, nEpochs, additionalBinaryDataProperties); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(InternalTodoFineTuneDPOMethodHyperparameters)} does not support writing '{options.Format}' format."); + } + } + + InternalTodoFineTuneDPOMethodHyperparameters IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + protected virtual InternalTodoFineTuneDPOMethodHyperparameters PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeInternalTodoFineTuneDPOMethodHyperparameters(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(InternalTodoFineTuneDPOMethodHyperparameters)} does not support reading '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + + public static implicit operator BinaryContent(InternalTodoFineTuneDPOMethodHyperparameters internalTodoFineTuneDPOMethodHyperparameters) + { + if (internalTodoFineTuneDPOMethodHyperparameters == null) + { + return null; + } + return BinaryContent.Create(internalTodoFineTuneDPOMethodHyperparameters, ModelSerializationExtensions.WireOptions); + } + + public static explicit operator InternalTodoFineTuneDPOMethodHyperparameters(ClientResult result) + { + using PipelineResponse response = result.GetRawResponse(); + using JsonDocument document = JsonDocument.Parse(response.Content); + return DeserializeInternalTodoFineTuneDPOMethodHyperparameters(document.RootElement, ModelSerializationExtensions.WireOptions); + } + } +} diff --git a/src/Generated/Models/InternalTodoFineTuneDPOMethodHyperparameters.cs b/src/Generated/Models/InternalTodoFineTuneDPOMethodHyperparameters.cs new file mode 100644 index 00000000..2d0fc8cd --- /dev/null +++ b/src/Generated/Models/InternalTodoFineTuneDPOMethodHyperparameters.cs @@ -0,0 +1,41 @@ +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace OpenAI.FineTuning +{ + internal partial class InternalTodoFineTuneDPOMethodHyperparameters + { + private protected IDictionary _additionalBinaryDataProperties; + + public InternalTodoFineTuneDPOMethodHyperparameters() + { + } + + internal InternalTodoFineTuneDPOMethodHyperparameters(BinaryData beta, BinaryData batchSize, BinaryData learningRateMultiplier, BinaryData nEpochs, IDictionary additionalBinaryDataProperties) + { + Beta = beta; + BatchSize = batchSize; + LearningRateMultiplier = learningRateMultiplier; + NEpochs = nEpochs; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + public BinaryData Beta { get; set; } + + public BinaryData BatchSize { get; set; } + + public BinaryData LearningRateMultiplier { get; set; } + + public BinaryData NEpochs { get; set; } + + internal IDictionary SerializedAdditionalRawData + { + get => _additionalBinaryDataProperties; + set => _additionalBinaryDataProperties = value; + } + } +} diff --git a/src/Generated/Models/InternalTodoFineTuneMethod.Serialization.cs b/src/Generated/Models/InternalTodoFineTuneMethod.Serialization.cs new file mode 100644 index 00000000..222f5636 --- /dev/null +++ b/src/Generated/Models/InternalTodoFineTuneMethod.Serialization.cs @@ -0,0 +1,175 @@ +// + +#nullable disable + +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; +using OpenAI; + +namespace OpenAI.FineTuning +{ + internal partial class InternalTodoFineTuneMethod : IJsonModel + { + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(InternalTodoFineTuneMethod)} does not support writing '{format}' format."); + } + if (Optional.IsDefined(Type) && _additionalBinaryDataProperties?.ContainsKey("type") != true) + { + writer.WritePropertyName("type"u8); + writer.WriteStringValue(Type.Value.ToString()); + } + if (Optional.IsDefined(Supervised) && _additionalBinaryDataProperties?.ContainsKey("supervised") != true) + { + writer.WritePropertyName("supervised"u8); + writer.WriteObjectValue(Supervised, options); + } + if (Optional.IsDefined(Dpo) && _additionalBinaryDataProperties?.ContainsKey("dpo") != true) + { + writer.WritePropertyName("dpo"u8); + writer.WriteObjectValue(Dpo, options); + } + if (true && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + if (ModelSerializationExtensions.IsSentinelValue(item.Value)) + { + continue; + } + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + InternalTodoFineTuneMethod IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + protected virtual InternalTodoFineTuneMethod JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(InternalTodoFineTuneMethod)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeInternalTodoFineTuneMethod(document.RootElement, options); + } + + internal static InternalTodoFineTuneMethod DeserializeInternalTodoFineTuneMethod(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + InternalTodoFineTuneMethodType? @type = default; + InternalTodoFineTuneSupervisedMethod supervised = default; + InternalTodoFineTuneDPOMethod dpo = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + @type = new InternalTodoFineTuneMethodType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("supervised"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + supervised = InternalTodoFineTuneSupervisedMethod.DeserializeInternalTodoFineTuneSupervisedMethod(prop.Value, options); + continue; + } + if (prop.NameEquals("dpo"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + dpo = InternalTodoFineTuneDPOMethod.DeserializeInternalTodoFineTuneDPOMethod(prop.Value, options); + continue; + } + if (true) + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new InternalTodoFineTuneMethod(@type, supervised, dpo, additionalBinaryDataProperties); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(InternalTodoFineTuneMethod)} does not support writing '{options.Format}' format."); + } + } + + InternalTodoFineTuneMethod IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + protected virtual InternalTodoFineTuneMethod PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeInternalTodoFineTuneMethod(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(InternalTodoFineTuneMethod)} does not support reading '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + + public static implicit operator BinaryContent(InternalTodoFineTuneMethod internalTodoFineTuneMethod) + { + if (internalTodoFineTuneMethod == null) + { + return null; + } + return BinaryContent.Create(internalTodoFineTuneMethod, ModelSerializationExtensions.WireOptions); + } + + public static explicit operator InternalTodoFineTuneMethod(ClientResult result) + { + using PipelineResponse response = result.GetRawResponse(); + using JsonDocument document = JsonDocument.Parse(response.Content); + return DeserializeInternalTodoFineTuneMethod(document.RootElement, ModelSerializationExtensions.WireOptions); + } + } +} diff --git a/src/Generated/Models/InternalTodoFineTuneMethod.cs b/src/Generated/Models/InternalTodoFineTuneMethod.cs new file mode 100644 index 00000000..f3c742bc --- /dev/null +++ b/src/Generated/Models/InternalTodoFineTuneMethod.cs @@ -0,0 +1,38 @@ +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace OpenAI.FineTuning +{ + internal partial class InternalTodoFineTuneMethod + { + private protected IDictionary _additionalBinaryDataProperties; + + public InternalTodoFineTuneMethod() + { + } + + internal InternalTodoFineTuneMethod(InternalTodoFineTuneMethodType? @type, InternalTodoFineTuneSupervisedMethod supervised, InternalTodoFineTuneDPOMethod dpo, IDictionary additionalBinaryDataProperties) + { + Type = @type; + Supervised = supervised; + Dpo = dpo; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + public InternalTodoFineTuneMethodType? Type { get; set; } + + public InternalTodoFineTuneSupervisedMethod Supervised { get; set; } + + public InternalTodoFineTuneDPOMethod Dpo { get; set; } + + internal IDictionary SerializedAdditionalRawData + { + get => _additionalBinaryDataProperties; + set => _additionalBinaryDataProperties = value; + } + } +} diff --git a/src/Generated/Models/InternalTodoFineTuneMethodType.cs b/src/Generated/Models/InternalTodoFineTuneMethodType.cs new file mode 100644 index 00000000..9d4bff17 --- /dev/null +++ b/src/Generated/Models/InternalTodoFineTuneMethodType.cs @@ -0,0 +1,44 @@ +// + +#nullable disable + +using System; +using System.ComponentModel; +using OpenAI; + +namespace OpenAI.FineTuning +{ + internal readonly partial struct InternalTodoFineTuneMethodType : IEquatable + { + private readonly string _value; + private const string SupervisedValue = "supervised"; + private const string DpoValue = "dpo"; + + public InternalTodoFineTuneMethodType(string value) + { + Argument.AssertNotNull(value, nameof(value)); + + _value = value; + } + + public static InternalTodoFineTuneMethodType Supervised { get; } = new InternalTodoFineTuneMethodType(SupervisedValue); + + public static InternalTodoFineTuneMethodType Dpo { get; } = new InternalTodoFineTuneMethodType(DpoValue); + + public static bool operator ==(InternalTodoFineTuneMethodType left, InternalTodoFineTuneMethodType right) => left.Equals(right); + + public static bool operator !=(InternalTodoFineTuneMethodType left, InternalTodoFineTuneMethodType right) => !left.Equals(right); + + public static implicit operator InternalTodoFineTuneMethodType(string value) => new InternalTodoFineTuneMethodType(value); + + [EditorBrowsable(EditorBrowsableState.Never)] + public override bool Equals(object obj) => obj is InternalTodoFineTuneMethodType other && Equals(other); + + public bool Equals(InternalTodoFineTuneMethodType 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; + } +} diff --git a/src/Generated/Models/InternalTodoFineTuneSupervisedMethod.Serialization.cs b/src/Generated/Models/InternalTodoFineTuneSupervisedMethod.Serialization.cs new file mode 100644 index 00000000..eac268c8 --- /dev/null +++ b/src/Generated/Models/InternalTodoFineTuneSupervisedMethod.Serialization.cs @@ -0,0 +1,145 @@ +// + +#nullable disable + +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; +using OpenAI; + +namespace OpenAI.FineTuning +{ + internal partial class InternalTodoFineTuneSupervisedMethod : IJsonModel + { + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(InternalTodoFineTuneSupervisedMethod)} does not support writing '{format}' format."); + } + if (Optional.IsDefined(Hyperparameters) && _additionalBinaryDataProperties?.ContainsKey("hyperparameters") != true) + { + writer.WritePropertyName("hyperparameters"u8); + writer.WriteObjectValue(Hyperparameters, options); + } + if (true && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + if (ModelSerializationExtensions.IsSentinelValue(item.Value)) + { + continue; + } + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + InternalTodoFineTuneSupervisedMethod IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + protected virtual InternalTodoFineTuneSupervisedMethod JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(InternalTodoFineTuneSupervisedMethod)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeInternalTodoFineTuneSupervisedMethod(document.RootElement, options); + } + + internal static InternalTodoFineTuneSupervisedMethod DeserializeInternalTodoFineTuneSupervisedMethod(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + InternalFineTuneSupervisedMethodHyperparameters hyperparameters = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("hyperparameters"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + hyperparameters = InternalFineTuneSupervisedMethodHyperparameters.DeserializeInternalFineTuneSupervisedMethodHyperparameters(prop.Value, options); + continue; + } + if (true) + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new InternalTodoFineTuneSupervisedMethod(hyperparameters, additionalBinaryDataProperties); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(InternalTodoFineTuneSupervisedMethod)} does not support writing '{options.Format}' format."); + } + } + + InternalTodoFineTuneSupervisedMethod IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + protected virtual InternalTodoFineTuneSupervisedMethod PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeInternalTodoFineTuneSupervisedMethod(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(InternalTodoFineTuneSupervisedMethod)} does not support reading '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + + public static implicit operator BinaryContent(InternalTodoFineTuneSupervisedMethod internalTodoFineTuneSupervisedMethod) + { + if (internalTodoFineTuneSupervisedMethod == null) + { + return null; + } + return BinaryContent.Create(internalTodoFineTuneSupervisedMethod, ModelSerializationExtensions.WireOptions); + } + + public static explicit operator InternalTodoFineTuneSupervisedMethod(ClientResult result) + { + using PipelineResponse response = result.GetRawResponse(); + using JsonDocument document = JsonDocument.Parse(response.Content); + return DeserializeInternalTodoFineTuneSupervisedMethod(document.RootElement, ModelSerializationExtensions.WireOptions); + } + } +} diff --git a/src/Generated/Models/InternalTodoFineTuneSupervisedMethod.cs b/src/Generated/Models/InternalTodoFineTuneSupervisedMethod.cs new file mode 100644 index 00000000..3cc8531a --- /dev/null +++ b/src/Generated/Models/InternalTodoFineTuneSupervisedMethod.cs @@ -0,0 +1,32 @@ +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace OpenAI.FineTuning +{ + internal partial class InternalTodoFineTuneSupervisedMethod + { + private protected IDictionary _additionalBinaryDataProperties; + + public InternalTodoFineTuneSupervisedMethod() + { + } + + internal InternalTodoFineTuneSupervisedMethod(InternalFineTuneSupervisedMethodHyperparameters hyperparameters, IDictionary additionalBinaryDataProperties) + { + Hyperparameters = hyperparameters; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + public InternalFineTuneSupervisedMethodHyperparameters Hyperparameters { get; set; } + + internal IDictionary SerializedAdditionalRawData + { + get => _additionalBinaryDataProperties; + set => _additionalBinaryDataProperties = value; + } + } +} diff --git a/src/Generated/Models/InternalUnknownChatMessage.Serialization.cs b/src/Generated/Models/InternalUnknownChatMessage.Serialization.cs index 1dbb31be..70a0deb0 100644 --- a/src/Generated/Models/InternalUnknownChatMessage.Serialization.cs +++ b/src/Generated/Models/InternalUnknownChatMessage.Serialization.cs @@ -45,19 +45,19 @@ internal static InternalUnknownChatMessage DeserializeInternalUnknownChatMessage { return null; } - Chat.ChatMessageRole role = default; ChatMessageContent content = default; + Chat.ChatMessageRole role = default; IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); foreach (var prop in element.EnumerateObject()) { - if (prop.NameEquals("role"u8)) + if (prop.NameEquals("content"u8)) { - role = prop.Value.GetString().ToChatMessageRole(); + DeserializeContentValue(prop, ref content); continue; } - if (prop.NameEquals("content"u8)) + if (prop.NameEquals("role"u8)) { - DeserializeContentValue(prop, ref content); + role = prop.Value.GetString().ToChatMessageRole(); continue; } if (true) @@ -66,7 +66,7 @@ internal static InternalUnknownChatMessage DeserializeInternalUnknownChatMessage } } // CUSTOM: Initialize Content collection property. - return new InternalUnknownChatMessage(role, content ?? new ChatMessageContent(), additionalBinaryDataProperties); + return new InternalUnknownChatMessage(content ?? new ChatMessageContent(), role, additionalBinaryDataProperties); } BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); diff --git a/src/Generated/Models/InternalUnknownChatMessage.cs b/src/Generated/Models/InternalUnknownChatMessage.cs index 994ab4d5..82bb59b2 100644 --- a/src/Generated/Models/InternalUnknownChatMessage.cs +++ b/src/Generated/Models/InternalUnknownChatMessage.cs @@ -9,7 +9,7 @@ namespace OpenAI.Chat { internal partial class InternalUnknownChatMessage : ChatMessage { - internal InternalUnknownChatMessage(Chat.ChatMessageRole role, ChatMessageContent content, IDictionary additionalBinaryDataProperties) : base(role, content, additionalBinaryDataProperties) + internal InternalUnknownChatMessage(ChatMessageContent content, Chat.ChatMessageRole role, IDictionary additionalBinaryDataProperties) : base(content, role, additionalBinaryDataProperties) { } } diff --git a/src/Generated/Models/InternalUnknownChatOutputPrediction.Serialization.cs b/src/Generated/Models/InternalUnknownChatOutputPrediction.Serialization.cs new file mode 100644 index 00000000..ba0c062c --- /dev/null +++ b/src/Generated/Models/InternalUnknownChatOutputPrediction.Serialization.cs @@ -0,0 +1,105 @@ +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; +using OpenAI; + +namespace OpenAI.Chat +{ + internal partial class InternalUnknownChatOutputPrediction : IJsonModel + { + internal InternalUnknownChatOutputPrediction() + { + } + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ChatOutputPrediction)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + } + + ChatOutputPrediction IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + protected override ChatOutputPrediction JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ChatOutputPrediction)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeChatOutputPrediction(document.RootElement, options); + } + + internal static InternalUnknownChatOutputPrediction DeserializeInternalUnknownChatOutputPrediction(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + InternalChatOutputPredictionKind @type = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new InternalChatOutputPredictionKind(prop.Value.GetString()); + continue; + } + if (true) + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new InternalUnknownChatOutputPrediction(@type, additionalBinaryDataProperties); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(ChatOutputPrediction)} does not support writing '{options.Format}' format."); + } + } + + ChatOutputPrediction IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + protected override ChatOutputPrediction PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeChatOutputPrediction(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ChatOutputPrediction)} does not support reading '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/src/Generated/Models/InternalUnknownChatOutputPrediction.cs b/src/Generated/Models/InternalUnknownChatOutputPrediction.cs new file mode 100644 index 00000000..6de1ab5c --- /dev/null +++ b/src/Generated/Models/InternalUnknownChatOutputPrediction.cs @@ -0,0 +1,16 @@ +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace OpenAI.Chat +{ + internal partial class InternalUnknownChatOutputPrediction : ChatOutputPrediction + { + internal InternalUnknownChatOutputPrediction(InternalChatOutputPredictionKind @type, IDictionary additionalBinaryDataProperties) : base(@type != default ? @type : "unknown", additionalBinaryDataProperties) + { + } + } +} diff --git a/src/Generated/Models/MessageCreationOptions.Serialization.cs b/src/Generated/Models/MessageCreationOptions.Serialization.cs index 171c2df2..24e5ec42 100644 --- a/src/Generated/Models/MessageCreationOptions.Serialization.cs +++ b/src/Generated/Models/MessageCreationOptions.Serialization.cs @@ -46,26 +46,19 @@ protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWrit } if (Optional.IsCollectionDefined(Metadata) && _additionalBinaryDataProperties?.ContainsKey("metadata") != true) { - if (Metadata != null) + writer.WritePropertyName("metadata"u8); + writer.WriteStartObject(); + foreach (var item in Metadata) { - writer.WritePropertyName("metadata"u8); - writer.WriteStartObject(); - foreach (var item in Metadata) + writer.WritePropertyName(item.Key); + if (item.Value == null) { - writer.WritePropertyName(item.Key); - if (item.Value == null) - { - writer.WriteNullValue(); - continue; - } - writer.WriteStringValue(item.Value); + writer.WriteNullValue(); + continue; } - writer.WriteEndObject(); - } - else - { - writer.WriteNull("metadata"u8); + writer.WriteStringValue(item.Value); } + writer.WriteEndObject(); } if (_additionalBinaryDataProperties?.ContainsKey("role") != true) { diff --git a/src/Generated/Models/MessageCreationOptions.cs b/src/Generated/Models/MessageCreationOptions.cs index b1399e85..c8c4b234 100644 --- a/src/Generated/Models/MessageCreationOptions.cs +++ b/src/Generated/Models/MessageCreationOptions.cs @@ -22,7 +22,7 @@ internal MessageCreationOptions(IList attachments, ID public IList Attachments { get; set; } - public IDictionary Metadata { get; set; } + public IDictionary Metadata { get; } internal IDictionary SerializedAdditionalRawData { diff --git a/src/Generated/Models/MessageModificationOptions.Serialization.cs b/src/Generated/Models/MessageModificationOptions.Serialization.cs index a80017c7..bcb1eebd 100644 --- a/src/Generated/Models/MessageModificationOptions.Serialization.cs +++ b/src/Generated/Models/MessageModificationOptions.Serialization.cs @@ -29,26 +29,19 @@ protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWrit } if (Optional.IsCollectionDefined(Metadata) && _additionalBinaryDataProperties?.ContainsKey("metadata") != true) { - if (Metadata != null) + writer.WritePropertyName("metadata"u8); + writer.WriteStartObject(); + foreach (var item in Metadata) { - writer.WritePropertyName("metadata"u8); - writer.WriteStartObject(); - foreach (var item in Metadata) + writer.WritePropertyName(item.Key); + if (item.Value == null) { - writer.WritePropertyName(item.Key); - if (item.Value == null) - { - writer.WriteNullValue(); - continue; - } - writer.WriteStringValue(item.Value); + writer.WriteNullValue(); + continue; } - writer.WriteEndObject(); - } - else - { - writer.WriteNull("metadata"u8); + writer.WriteStringValue(item.Value); } + writer.WriteEndObject(); } if (true && _additionalBinaryDataProperties != null) { diff --git a/src/Generated/Models/MessageModificationOptions.cs b/src/Generated/Models/MessageModificationOptions.cs index 3818571f..128b930b 100644 --- a/src/Generated/Models/MessageModificationOptions.cs +++ b/src/Generated/Models/MessageModificationOptions.cs @@ -23,7 +23,7 @@ internal MessageModificationOptions(IDictionary metadata, IDicti _additionalBinaryDataProperties = additionalBinaryDataProperties; } - public IDictionary Metadata { get; set; } + public IDictionary Metadata { get; } internal IDictionary SerializedAdditionalRawData { diff --git a/src/Generated/Models/OpenAIFileCollection.Serialization.cs b/src/Generated/Models/OpenAIFileCollection.Serialization.cs index 4c04572b..b7a29613 100644 --- a/src/Generated/Models/OpenAIFileCollection.Serialization.cs +++ b/src/Generated/Models/OpenAIFileCollection.Serialization.cs @@ -24,6 +24,21 @@ protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWrit writer.WritePropertyName("object"u8); writer.WriteStringValue(this.Object.ToString()); } + if (_additionalBinaryDataProperties?.ContainsKey("first_id") != true) + { + writer.WritePropertyName("first_id"u8); + writer.WriteStringValue(FirstId); + } + if (_additionalBinaryDataProperties?.ContainsKey("last_id") != true) + { + writer.WritePropertyName("last_id"u8); + writer.WriteStringValue(LastId); + } + if (_additionalBinaryDataProperties?.ContainsKey("has_more") != true) + { + writer.WritePropertyName("has_more"u8); + writer.WriteBooleanValue(HasMore); + } if (true && _additionalBinaryDataProperties != null) { foreach (var item in _additionalBinaryDataProperties) diff --git a/src/Generated/Models/ResponseConversationSelection.cs b/src/Generated/Models/ResponseConversationSelection.cs new file mode 100644 index 00000000..0fbfb42a --- /dev/null +++ b/src/Generated/Models/ResponseConversationSelection.cs @@ -0,0 +1,44 @@ +// + +#nullable disable + +using System; +using System.ComponentModel; +using OpenAI; + +namespace OpenAI.RealtimeConversation +{ + public readonly partial struct ResponseConversationSelection : IEquatable + { + private readonly string _value; + private const string AutoValue = "auto"; + private const string NoneValue = "none"; + + public ResponseConversationSelection(string value) + { + Argument.AssertNotNull(value, nameof(value)); + + _value = value; + } + + public static ResponseConversationSelection Auto { get; } = new ResponseConversationSelection(AutoValue); + + public static ResponseConversationSelection None { get; } = new ResponseConversationSelection(NoneValue); + + public static bool operator ==(ResponseConversationSelection left, ResponseConversationSelection right) => left.Equals(right); + + public static bool operator !=(ResponseConversationSelection left, ResponseConversationSelection right) => !left.Equals(right); + + public static implicit operator ResponseConversationSelection(string value) => new ResponseConversationSelection(value); + + [EditorBrowsable(EditorBrowsableState.Never)] + public override bool Equals(object obj) => obj is ResponseConversationSelection other && Equals(other); + + public bool Equals(ResponseConversationSelection 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; + } +} diff --git a/src/Generated/Models/RunCreationOptions.Serialization.cs b/src/Generated/Models/RunCreationOptions.Serialization.cs index ee5dc6c4..e205dd68 100644 --- a/src/Generated/Models/RunCreationOptions.Serialization.cs +++ b/src/Generated/Models/RunCreationOptions.Serialization.cs @@ -133,26 +133,19 @@ protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWrit } if (Optional.IsCollectionDefined(Metadata) && _additionalBinaryDataProperties?.ContainsKey("metadata") != true) { - if (Metadata != null) + writer.WritePropertyName("metadata"u8); + writer.WriteStartObject(); + foreach (var item in Metadata) { - writer.WritePropertyName("metadata"u8); - writer.WriteStartObject(); - foreach (var item in Metadata) + writer.WritePropertyName(item.Key); + if (item.Value == null) { - writer.WritePropertyName(item.Key); - if (item.Value == null) - { - writer.WriteNullValue(); - continue; - } - writer.WriteStringValue(item.Value); + writer.WriteNullValue(); + continue; } - writer.WriteEndObject(); - } - else - { - writer.WriteNull("metadata"u8); + writer.WriteStringValue(item.Value); } + writer.WriteEndObject(); } if (Optional.IsDefined(Temperature) && _additionalBinaryDataProperties?.ContainsKey("temperature") != true) { diff --git a/src/Generated/Models/RunModificationOptions.Serialization.cs b/src/Generated/Models/RunModificationOptions.Serialization.cs index a5fbcc54..4a77d2e2 100644 --- a/src/Generated/Models/RunModificationOptions.Serialization.cs +++ b/src/Generated/Models/RunModificationOptions.Serialization.cs @@ -29,26 +29,19 @@ protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWrit } if (Optional.IsCollectionDefined(Metadata) && _additionalBinaryDataProperties?.ContainsKey("metadata") != true) { - if (Metadata != null) + writer.WritePropertyName("metadata"u8); + writer.WriteStartObject(); + foreach (var item in Metadata) { - writer.WritePropertyName("metadata"u8); - writer.WriteStartObject(); - foreach (var item in Metadata) + writer.WritePropertyName(item.Key); + if (item.Value == null) { - writer.WritePropertyName(item.Key); - if (item.Value == null) - { - writer.WriteNullValue(); - continue; - } - writer.WriteStringValue(item.Value); + writer.WriteNullValue(); + continue; } - writer.WriteEndObject(); - } - else - { - writer.WriteNull("metadata"u8); + writer.WriteStringValue(item.Value); } + writer.WriteEndObject(); } if (true && _additionalBinaryDataProperties != null) { diff --git a/src/Generated/Models/RunModificationOptions.cs b/src/Generated/Models/RunModificationOptions.cs index 4295bfb3..45750f93 100644 --- a/src/Generated/Models/RunModificationOptions.cs +++ b/src/Generated/Models/RunModificationOptions.cs @@ -23,7 +23,7 @@ internal RunModificationOptions(IDictionary metadata, IDictionar _additionalBinaryDataProperties = additionalBinaryDataProperties; } - public IDictionary Metadata { get; set; } + public IDictionary Metadata { get; } internal IDictionary SerializedAdditionalRawData { diff --git a/src/Generated/Models/RunStepFileSearchResultContent.Serialization.cs b/src/Generated/Models/RunStepFileSearchResultContent.Serialization.cs index ff4b07f5..26de3553 100644 --- a/src/Generated/Models/RunStepFileSearchResultContent.Serialization.cs +++ b/src/Generated/Models/RunStepFileSearchResultContent.Serialization.cs @@ -13,6 +13,10 @@ namespace OpenAI.Assistants { public partial class RunStepFileSearchResultContent : IJsonModel { + internal RunStepFileSearchResultContent() + { + } + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { writer.WriteStartObject(); @@ -27,7 +31,7 @@ protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWrit { throw new FormatException($"The model {nameof(RunStepFileSearchResultContent)} does not support writing '{format}' format."); } - if (Optional.IsDefined(Text) && _additionalBinaryDataProperties?.ContainsKey("text") != true) + if (_additionalBinaryDataProperties?.ContainsKey("text") != true) { writer.WritePropertyName("text"u8); writer.WriteStringValue(Text); diff --git a/src/Generated/Models/RunStepFileSearchResultContent.cs b/src/Generated/Models/RunStepFileSearchResultContent.cs index 95d299b1..8324a3db 100644 --- a/src/Generated/Models/RunStepFileSearchResultContent.cs +++ b/src/Generated/Models/RunStepFileSearchResultContent.cs @@ -11,8 +11,9 @@ public partial class RunStepFileSearchResultContent { private protected IDictionary _additionalBinaryDataProperties; - internal RunStepFileSearchResultContent() + internal RunStepFileSearchResultContent(string text) { + Text = text; } internal RunStepFileSearchResultContent(string text, Assistants.RunStepFileSearchResultContentKind kind, IDictionary additionalBinaryDataProperties) diff --git a/src/Generated/Models/StreamingChatCompletionUpdate.Serialization.cs b/src/Generated/Models/StreamingChatCompletionUpdate.Serialization.cs index ccb709a7..db571acc 100644 --- a/src/Generated/Models/StreamingChatCompletionUpdate.Serialization.cs +++ b/src/Generated/Models/StreamingChatCompletionUpdate.Serialization.cs @@ -80,8 +80,15 @@ protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWrit } if (Optional.IsDefined(Usage) && _additionalBinaryDataProperties?.ContainsKey("usage") != true) { - writer.WritePropertyName("usage"u8); - writer.WriteObjectValue(Usage, options); + if (Usage != null) + { + writer.WritePropertyName("usage"u8); + writer.WriteObjectValue(Usage, options); + } + else + { + writer.WriteNull("usage"u8); + } } if (true && _additionalBinaryDataProperties != null) { @@ -183,6 +190,7 @@ internal static StreamingChatCompletionUpdate DeserializeStreamingChatCompletion { if (prop.Value.ValueKind == JsonValueKind.Null) { + usage = null; continue; } usage = ChatTokenUsage.DeserializeChatTokenUsage(prop.Value, options); diff --git a/src/Generated/Models/StreamingChatOutputAudioUpdate.Serialization.cs b/src/Generated/Models/StreamingChatOutputAudioUpdate.Serialization.cs new file mode 100644 index 00000000..080cfa4c --- /dev/null +++ b/src/Generated/Models/StreamingChatOutputAudioUpdate.Serialization.cs @@ -0,0 +1,182 @@ +// + +#nullable disable + +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; +using OpenAI; + +namespace OpenAI.Chat +{ + public partial class StreamingChatOutputAudioUpdate : IJsonModel + { + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(StreamingChatOutputAudioUpdate)} does not support writing '{format}' format."); + } + if (Optional.IsDefined(Id) && _additionalBinaryDataProperties?.ContainsKey("id") != true) + { + writer.WritePropertyName("id"u8); + writer.WriteStringValue(Id); + } + if (Optional.IsDefined(ExpiresAt) && _additionalBinaryDataProperties?.ContainsKey("expires_at") != true) + { + writer.WritePropertyName("expires_at"u8); + writer.WriteNumberValue(ExpiresAt.Value, "U"); + } + if (Optional.IsDefined(TranscriptUpdate) && _additionalBinaryDataProperties?.ContainsKey("transcript") != true) + { + writer.WritePropertyName("transcript"u8); + writer.WriteStringValue(TranscriptUpdate); + } + if (Optional.IsDefined(AudioBytesUpdate) && _additionalBinaryDataProperties?.ContainsKey("data") != true) + { + writer.WritePropertyName("data"u8); + writer.WriteBase64StringValue(AudioBytesUpdate.ToArray(), "D"); + } + if (true && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + if (ModelSerializationExtensions.IsSentinelValue(item.Value)) + { + continue; + } + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + StreamingChatOutputAudioUpdate IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + protected virtual StreamingChatOutputAudioUpdate JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(StreamingChatOutputAudioUpdate)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeStreamingChatOutputAudioUpdate(document.RootElement, options); + } + + internal static StreamingChatOutputAudioUpdate DeserializeStreamingChatOutputAudioUpdate(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + string id = default; + DateTimeOffset? expiresAt = default; + string transcriptUpdate = default; + BinaryData audioBytesUpdate = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("id"u8)) + { + id = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("expires_at"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + expiresAt = DateTimeOffset.FromUnixTimeSeconds(prop.Value.GetInt64()); + continue; + } + if (prop.NameEquals("transcript"u8)) + { + transcriptUpdate = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("data"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + audioBytesUpdate = BinaryData.FromBytes(prop.Value.GetBytesFromBase64("D")); + continue; + } + if (true) + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new StreamingChatOutputAudioUpdate(id, expiresAt, transcriptUpdate, audioBytesUpdate, additionalBinaryDataProperties); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(StreamingChatOutputAudioUpdate)} does not support writing '{options.Format}' format."); + } + } + + StreamingChatOutputAudioUpdate IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + protected virtual StreamingChatOutputAudioUpdate PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeStreamingChatOutputAudioUpdate(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(StreamingChatOutputAudioUpdate)} does not support reading '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + + public static implicit operator BinaryContent(StreamingChatOutputAudioUpdate streamingChatOutputAudioUpdate) + { + if (streamingChatOutputAudioUpdate == null) + { + return null; + } + return BinaryContent.Create(streamingChatOutputAudioUpdate, ModelSerializationExtensions.WireOptions); + } + + public static explicit operator StreamingChatOutputAudioUpdate(ClientResult result) + { + using PipelineResponse response = result.GetRawResponse(); + using JsonDocument document = JsonDocument.Parse(response.Content); + return DeserializeStreamingChatOutputAudioUpdate(document.RootElement, ModelSerializationExtensions.WireOptions); + } + } +} diff --git a/src/Generated/Models/StreamingChatOutputAudioUpdate.cs b/src/Generated/Models/StreamingChatOutputAudioUpdate.cs new file mode 100644 index 00000000..9abebceb --- /dev/null +++ b/src/Generated/Models/StreamingChatOutputAudioUpdate.cs @@ -0,0 +1,37 @@ +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace OpenAI.Chat +{ + public partial class StreamingChatOutputAudioUpdate + { + private protected IDictionary _additionalBinaryDataProperties; + + internal StreamingChatOutputAudioUpdate() + { + } + + internal StreamingChatOutputAudioUpdate(string id, DateTimeOffset? expiresAt, string transcriptUpdate, BinaryData audioBytesUpdate, IDictionary additionalBinaryDataProperties) + { + Id = id; + ExpiresAt = expiresAt; + TranscriptUpdate = transcriptUpdate; + AudioBytesUpdate = audioBytesUpdate; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + public string Id { get; } + + public DateTimeOffset? ExpiresAt { get; } + + internal IDictionary SerializedAdditionalRawData + { + get => _additionalBinaryDataProperties; + set => _additionalBinaryDataProperties = value; + } + } +} diff --git a/src/Generated/Models/SystemChatMessage.Serialization.cs b/src/Generated/Models/SystemChatMessage.Serialization.cs index 620f4d85..9f11bed1 100644 --- a/src/Generated/Models/SystemChatMessage.Serialization.cs +++ b/src/Generated/Models/SystemChatMessage.Serialization.cs @@ -47,20 +47,20 @@ internal static SystemChatMessage DeserializeSystemChatMessage(JsonElement eleme { return null; } - Chat.ChatMessageRole role = default; ChatMessageContent content = default; + Chat.ChatMessageRole role = default; IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); string participantName = default; foreach (var prop in element.EnumerateObject()) { - if (prop.NameEquals("role"u8)) + if (prop.NameEquals("content"u8)) { - role = prop.Value.GetString().ToChatMessageRole(); + DeserializeContentValue(prop, ref content); continue; } - if (prop.NameEquals("content"u8)) + if (prop.NameEquals("role"u8)) { - DeserializeContentValue(prop, ref content); + role = prop.Value.GetString().ToChatMessageRole(); continue; } if (prop.NameEquals("name"u8)) @@ -74,7 +74,7 @@ internal static SystemChatMessage DeserializeSystemChatMessage(JsonElement eleme } } // CUSTOM: Initialize Content collection property. - return new SystemChatMessage(role, content ?? new ChatMessageContent(), additionalBinaryDataProperties, participantName); + return new SystemChatMessage(content ?? new ChatMessageContent(), role, additionalBinaryDataProperties, participantName); } BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); diff --git a/src/Generated/Models/SystemChatMessage.cs b/src/Generated/Models/SystemChatMessage.cs index 0785ec94..0f8453e0 100644 --- a/src/Generated/Models/SystemChatMessage.cs +++ b/src/Generated/Models/SystemChatMessage.cs @@ -9,7 +9,7 @@ namespace OpenAI.Chat { public partial class SystemChatMessage : ChatMessage { - internal SystemChatMessage(Chat.ChatMessageRole role, ChatMessageContent content, IDictionary additionalBinaryDataProperties, string participantName) : base(role, content, additionalBinaryDataProperties) + internal SystemChatMessage(ChatMessageContent content, Chat.ChatMessageRole role, IDictionary additionalBinaryDataProperties, string participantName) : base(content, role, additionalBinaryDataProperties) { ParticipantName = participantName; } diff --git a/src/Generated/Models/ThreadCreationOptions.Serialization.cs b/src/Generated/Models/ThreadCreationOptions.Serialization.cs index 8fd981fe..ebe9da76 100644 --- a/src/Generated/Models/ThreadCreationOptions.Serialization.cs +++ b/src/Generated/Models/ThreadCreationOptions.Serialization.cs @@ -29,26 +29,19 @@ protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWrit } if (Optional.IsCollectionDefined(Metadata) && _additionalBinaryDataProperties?.ContainsKey("metadata") != true) { - if (Metadata != null) + writer.WritePropertyName("metadata"u8); + writer.WriteStartObject(); + foreach (var item in Metadata) { - writer.WritePropertyName("metadata"u8); - writer.WriteStartObject(); - foreach (var item in Metadata) + writer.WritePropertyName(item.Key); + if (item.Value == null) { - writer.WritePropertyName(item.Key); - if (item.Value == null) - { - writer.WriteNullValue(); - continue; - } - writer.WriteStringValue(item.Value); + writer.WriteNullValue(); + continue; } - writer.WriteEndObject(); - } - else - { - writer.WriteNull("metadata"u8); + writer.WriteStringValue(item.Value); } + writer.WriteEndObject(); } if (Optional.IsDefined(ToolResources) && _additionalBinaryDataProperties?.ContainsKey("tool_resources") != true) { diff --git a/src/Generated/Models/ThreadCreationOptions.cs b/src/Generated/Models/ThreadCreationOptions.cs index 7675b564..c667f5df 100644 --- a/src/Generated/Models/ThreadCreationOptions.cs +++ b/src/Generated/Models/ThreadCreationOptions.cs @@ -26,7 +26,7 @@ internal ThreadCreationOptions(IDictionary metadata, ToolResourc _additionalBinaryDataProperties = additionalBinaryDataProperties; } - public IDictionary Metadata { get; set; } + public IDictionary Metadata { get; } internal IDictionary SerializedAdditionalRawData { diff --git a/src/Generated/Models/ThreadModificationOptions.Serialization.cs b/src/Generated/Models/ThreadModificationOptions.Serialization.cs index b1bad14a..93c91dc4 100644 --- a/src/Generated/Models/ThreadModificationOptions.Serialization.cs +++ b/src/Generated/Models/ThreadModificationOptions.Serialization.cs @@ -29,26 +29,19 @@ protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWrit } if (Optional.IsCollectionDefined(Metadata) && _additionalBinaryDataProperties?.ContainsKey("metadata") != true) { - if (Metadata != null) + writer.WritePropertyName("metadata"u8); + writer.WriteStartObject(); + foreach (var item in Metadata) { - writer.WritePropertyName("metadata"u8); - writer.WriteStartObject(); - foreach (var item in Metadata) + writer.WritePropertyName(item.Key); + if (item.Value == null) { - writer.WritePropertyName(item.Key); - if (item.Value == null) - { - writer.WriteNullValue(); - continue; - } - writer.WriteStringValue(item.Value); + writer.WriteNullValue(); + continue; } - writer.WriteEndObject(); - } - else - { - writer.WriteNull("metadata"u8); + writer.WriteStringValue(item.Value); } + writer.WriteEndObject(); } if (Optional.IsDefined(ToolResources) && _additionalBinaryDataProperties?.ContainsKey("tool_resources") != true) { diff --git a/src/Generated/Models/ThreadModificationOptions.cs b/src/Generated/Models/ThreadModificationOptions.cs index 261bcaf1..ee4e2f16 100644 --- a/src/Generated/Models/ThreadModificationOptions.cs +++ b/src/Generated/Models/ThreadModificationOptions.cs @@ -24,7 +24,7 @@ internal ThreadModificationOptions(IDictionary metadata, ToolRes _additionalBinaryDataProperties = additionalBinaryDataProperties; } - public IDictionary Metadata { get; set; } + public IDictionary Metadata { get; } internal IDictionary SerializedAdditionalRawData { diff --git a/src/Generated/Models/ToolChatMessage.Serialization.cs b/src/Generated/Models/ToolChatMessage.Serialization.cs index c3072ce6..6762d530 100644 --- a/src/Generated/Models/ToolChatMessage.Serialization.cs +++ b/src/Generated/Models/ToolChatMessage.Serialization.cs @@ -51,20 +51,20 @@ internal static ToolChatMessage DeserializeToolChatMessage(JsonElement element, { return null; } - Chat.ChatMessageRole role = default; ChatMessageContent content = default; + Chat.ChatMessageRole role = default; IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); string toolCallId = default; foreach (var prop in element.EnumerateObject()) { - if (prop.NameEquals("role"u8)) + if (prop.NameEquals("content"u8)) { - role = prop.Value.GetString().ToChatMessageRole(); + DeserializeContentValue(prop, ref content); continue; } - if (prop.NameEquals("content"u8)) + if (prop.NameEquals("role"u8)) { - DeserializeContentValue(prop, ref content); + role = prop.Value.GetString().ToChatMessageRole(); continue; } if (prop.NameEquals("tool_call_id"u8)) @@ -78,7 +78,7 @@ internal static ToolChatMessage DeserializeToolChatMessage(JsonElement element, } } // CUSTOM: Initialize Content collection property. - return new ToolChatMessage(role, content ?? new ChatMessageContent(), additionalBinaryDataProperties, toolCallId); + return new ToolChatMessage(content ?? new ChatMessageContent(), role, additionalBinaryDataProperties, toolCallId); } BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); diff --git a/src/Generated/Models/ToolChatMessage.cs b/src/Generated/Models/ToolChatMessage.cs index 6e671b9c..c0c78656 100644 --- a/src/Generated/Models/ToolChatMessage.cs +++ b/src/Generated/Models/ToolChatMessage.cs @@ -9,7 +9,7 @@ namespace OpenAI.Chat { public partial class ToolChatMessage : ChatMessage { - internal ToolChatMessage(Chat.ChatMessageRole role, ChatMessageContent content, IDictionary additionalBinaryDataProperties, string toolCallId) : base(role, content, additionalBinaryDataProperties) + internal ToolChatMessage(ChatMessageContent content, Chat.ChatMessageRole role, IDictionary additionalBinaryDataProperties, string toolCallId) : base(content, role, additionalBinaryDataProperties) { ToolCallId = toolCallId; } diff --git a/src/Generated/Models/UnknownRealtimeResponseItem.Serialization.cs b/src/Generated/Models/UnknownRealtimeResponseItem.Serialization.cs index f618f94f..5a0d718b 100644 --- a/src/Generated/Models/UnknownRealtimeResponseItem.Serialization.cs +++ b/src/Generated/Models/UnknownRealtimeResponseItem.Serialization.cs @@ -10,13 +10,13 @@ namespace OpenAI.RealtimeConversation { - internal partial class UnknownRealtimeResponseItem : IJsonModel + internal partial class UnknownRealtimeResponseItem : IJsonModel { internal UnknownRealtimeResponseItem() { } - void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { writer.WriteStartObject(); JsonModelWriteCore(writer, options); @@ -25,25 +25,25 @@ void IJsonModel.Write(Utf8JsonWriter writer, Model protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) { - string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; if (format != "J") { - throw new FormatException($"The model {nameof(InternalRealtimeResponseItem)} does not support writing '{format}' format."); + throw new FormatException($"The model {nameof(InternalRealtimeConversationResponseItem)} does not support writing '{format}' format."); } base.JsonModelWriteCore(writer, options); } - InternalRealtimeResponseItem IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + InternalRealtimeConversationResponseItem IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); - protected override InternalRealtimeResponseItem JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + protected override InternalRealtimeConversationResponseItem JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { - string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; if (format != "J") { - throw new FormatException($"The model {nameof(InternalRealtimeResponseItem)} does not support reading '{format}' format."); + throw new FormatException($"The model {nameof(InternalRealtimeConversationResponseItem)} does not support reading '{format}' format."); } using JsonDocument document = JsonDocument.ParseValue(ref reader); - return DeserializeInternalRealtimeResponseItem(document.RootElement, options); + return DeserializeInternalRealtimeConversationResponseItem(document.RootElement, options); } internal static UnknownRealtimeResponseItem DeserializeUnknownRealtimeResponseItem(JsonElement element, ModelReaderWriterOptions options) @@ -52,7 +52,7 @@ internal static UnknownRealtimeResponseItem DeserializeUnknownRealtimeResponseIt { return null; } - InternalRealtimeResponseItemObject @object = default; + InternalRealtimeConversationResponseItemObject @object = default; InternalRealtimeItemType @type = default; string id = default; IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); @@ -60,7 +60,7 @@ internal static UnknownRealtimeResponseItem DeserializeUnknownRealtimeResponseIt { if (prop.NameEquals("object"u8)) { - @object = new InternalRealtimeResponseItemObject(prop.Value.GetString()); + @object = new InternalRealtimeConversationResponseItemObject(prop.Value.GetString()); continue; } if (prop.NameEquals("type"u8)) @@ -86,37 +86,37 @@ internal static UnknownRealtimeResponseItem DeserializeUnknownRealtimeResponseIt return new UnknownRealtimeResponseItem(@object, @type, id, additionalBinaryDataProperties); } - BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) { - string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; switch (format) { case "J": return ModelReaderWriter.Write(this, options); default: - throw new FormatException($"The model {nameof(InternalRealtimeResponseItem)} does not support writing '{options.Format}' format."); + throw new FormatException($"The model {nameof(InternalRealtimeConversationResponseItem)} does not support writing '{options.Format}' format."); } } - InternalRealtimeResponseItem IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + InternalRealtimeConversationResponseItem IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); - protected override InternalRealtimeResponseItem PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + protected override InternalRealtimeConversationResponseItem PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) { - string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; switch (format) { case "J": using (JsonDocument document = JsonDocument.Parse(data)) { - return DeserializeInternalRealtimeResponseItem(document.RootElement, options); + return DeserializeInternalRealtimeConversationResponseItem(document.RootElement, options); } default: - throw new FormatException($"The model {nameof(InternalRealtimeResponseItem)} does not support reading '{options.Format}' format."); + throw new FormatException($"The model {nameof(InternalRealtimeConversationResponseItem)} does not support reading '{options.Format}' format."); } } - string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/src/Generated/Models/UnknownRealtimeResponseItem.cs b/src/Generated/Models/UnknownRealtimeResponseItem.cs index bb08f7ea..1f77d4c2 100644 --- a/src/Generated/Models/UnknownRealtimeResponseItem.cs +++ b/src/Generated/Models/UnknownRealtimeResponseItem.cs @@ -7,9 +7,9 @@ namespace OpenAI.RealtimeConversation { - internal partial class UnknownRealtimeResponseItem : InternalRealtimeResponseItem + internal partial class UnknownRealtimeResponseItem : InternalRealtimeConversationResponseItem { - internal UnknownRealtimeResponseItem(InternalRealtimeResponseItemObject @object, InternalRealtimeItemType @type, string id, IDictionary additionalBinaryDataProperties) : base(@object, @type != default ? @type : "unknown", id, additionalBinaryDataProperties) + internal UnknownRealtimeResponseItem(InternalRealtimeConversationResponseItemObject @object, InternalRealtimeItemType @type, string id, IDictionary additionalBinaryDataProperties) : base(@object, @type != default ? @type : "unknown", id, additionalBinaryDataProperties) { } } diff --git a/src/Generated/Models/UnknownRealtimeResponseStatusDetails.Serialization.cs b/src/Generated/Models/UnknownRealtimeResponseStatusDetails.Serialization.cs deleted file mode 100644 index 21fc7644..00000000 --- a/src/Generated/Models/UnknownRealtimeResponseStatusDetails.Serialization.cs +++ /dev/null @@ -1,105 +0,0 @@ -// - -#nullable disable - -using System; -using System.ClientModel.Primitives; -using System.Collections.Generic; -using System.Text.Json; -using OpenAI; - -namespace OpenAI.RealtimeConversation -{ - internal partial class UnknownRealtimeResponseStatusDetails : IJsonModel - { - internal UnknownRealtimeResponseStatusDetails() - { - } - - void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) - { - writer.WriteStartObject(); - JsonModelWriteCore(writer, options); - writer.WriteEndObject(); - } - - protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) - { - string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; - if (format != "J") - { - throw new FormatException($"The model {nameof(ConversationStatusDetails)} does not support writing '{format}' format."); - } - base.JsonModelWriteCore(writer, options); - } - - ConversationStatusDetails IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); - - protected override ConversationStatusDetails JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) - { - string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; - if (format != "J") - { - throw new FormatException($"The model {nameof(ConversationStatusDetails)} does not support reading '{format}' format."); - } - using JsonDocument document = JsonDocument.ParseValue(ref reader); - return DeserializeConversationStatusDetails(document.RootElement, options); - } - - internal static UnknownRealtimeResponseStatusDetails DeserializeUnknownRealtimeResponseStatusDetails(JsonElement element, ModelReaderWriterOptions options) - { - if (element.ValueKind == JsonValueKind.Null) - { - return null; - } - ConversationStatus statusKind = default; - IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); - foreach (var prop in element.EnumerateObject()) - { - if (prop.NameEquals("type"u8)) - { - statusKind = new ConversationStatus(prop.Value.GetString()); - continue; - } - if (true) - { - additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); - } - } - return new UnknownRealtimeResponseStatusDetails(statusKind, additionalBinaryDataProperties); - } - - BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); - - protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) - { - string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; - switch (format) - { - case "J": - return ModelReaderWriter.Write(this, options); - default: - throw new FormatException($"The model {nameof(ConversationStatusDetails)} does not support writing '{options.Format}' format."); - } - } - - ConversationStatusDetails IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); - - protected override ConversationStatusDetails PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) - { - string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; - switch (format) - { - case "J": - using (JsonDocument document = JsonDocument.Parse(data)) - { - return DeserializeConversationStatusDetails(document.RootElement, options); - } - default: - throw new FormatException($"The model {nameof(ConversationStatusDetails)} does not support reading '{options.Format}' format."); - } - } - - string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; - } -} diff --git a/src/Generated/Models/UnknownRealtimeResponseStatusDetails.cs b/src/Generated/Models/UnknownRealtimeResponseStatusDetails.cs deleted file mode 100644 index 0bbcb1f2..00000000 --- a/src/Generated/Models/UnknownRealtimeResponseStatusDetails.cs +++ /dev/null @@ -1,16 +0,0 @@ -// - -#nullable disable - -using System; -using System.Collections.Generic; - -namespace OpenAI.RealtimeConversation -{ - internal partial class UnknownRealtimeResponseStatusDetails : ConversationStatusDetails - { - internal UnknownRealtimeResponseStatusDetails(ConversationStatus statusKind, IDictionary additionalBinaryDataProperties) : base(statusKind != default ? statusKind : "unknown", additionalBinaryDataProperties) - { - } - } -} diff --git a/src/Generated/Models/UserChatMessage.Serialization.cs b/src/Generated/Models/UserChatMessage.Serialization.cs index 300edf21..c53bf0f9 100644 --- a/src/Generated/Models/UserChatMessage.Serialization.cs +++ b/src/Generated/Models/UserChatMessage.Serialization.cs @@ -47,20 +47,20 @@ internal static UserChatMessage DeserializeUserChatMessage(JsonElement element, { return null; } - Chat.ChatMessageRole role = default; ChatMessageContent content = default; + Chat.ChatMessageRole role = default; IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); string participantName = default; foreach (var prop in element.EnumerateObject()) { - if (prop.NameEquals("role"u8)) + if (prop.NameEquals("content"u8)) { - role = prop.Value.GetString().ToChatMessageRole(); + DeserializeContentValue(prop, ref content); continue; } - if (prop.NameEquals("content"u8)) + if (prop.NameEquals("role"u8)) { - DeserializeContentValue(prop, ref content); + role = prop.Value.GetString().ToChatMessageRole(); continue; } if (prop.NameEquals("name"u8)) @@ -74,7 +74,7 @@ internal static UserChatMessage DeserializeUserChatMessage(JsonElement element, } } // CUSTOM: Initialize Content collection property. - return new UserChatMessage(role, content ?? new ChatMessageContent(), additionalBinaryDataProperties, participantName); + return new UserChatMessage(content ?? new ChatMessageContent(), role, additionalBinaryDataProperties, participantName); } BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); diff --git a/src/Generated/Models/UserChatMessage.cs b/src/Generated/Models/UserChatMessage.cs index 259270b7..4d7bda7a 100644 --- a/src/Generated/Models/UserChatMessage.cs +++ b/src/Generated/Models/UserChatMessage.cs @@ -9,7 +9,7 @@ namespace OpenAI.Chat { public partial class UserChatMessage : ChatMessage { - internal UserChatMessage(Chat.ChatMessageRole role, ChatMessageContent content, IDictionary additionalBinaryDataProperties, string participantName) : base(role, content, additionalBinaryDataProperties) + internal UserChatMessage(ChatMessageContent content, Chat.ChatMessageRole role, IDictionary additionalBinaryDataProperties, string participantName) : base(content, role, additionalBinaryDataProperties) { ParticipantName = participantName; } diff --git a/src/Generated/Models/VectorStoreCreationOptions.Serialization.cs b/src/Generated/Models/VectorStoreCreationOptions.Serialization.cs index 91403959..e5147480 100644 --- a/src/Generated/Models/VectorStoreCreationOptions.Serialization.cs +++ b/src/Generated/Models/VectorStoreCreationOptions.Serialization.cs @@ -49,26 +49,19 @@ protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWrit } if (Optional.IsCollectionDefined(Metadata) && _additionalBinaryDataProperties?.ContainsKey("metadata") != true) { - if (Metadata != null) + writer.WritePropertyName("metadata"u8); + writer.WriteStartObject(); + foreach (var item in Metadata) { - writer.WritePropertyName("metadata"u8); - writer.WriteStartObject(); - foreach (var item in Metadata) + writer.WritePropertyName(item.Key); + if (item.Value == null) { - writer.WritePropertyName(item.Key); - if (item.Value == null) - { - writer.WriteNullValue(); - continue; - } - writer.WriteStringValue(item.Value); + writer.WriteNullValue(); + continue; } - writer.WriteEndObject(); - } - else - { - writer.WriteNull("metadata"u8); + writer.WriteStringValue(item.Value); } + writer.WriteEndObject(); } if (Optional.IsDefined(ExpirationPolicy) && _additionalBinaryDataProperties?.ContainsKey("expires_after") != true) { diff --git a/src/Generated/Models/VectorStoreCreationOptions.cs b/src/Generated/Models/VectorStoreCreationOptions.cs index 563e1c7d..0e0e4259 100644 --- a/src/Generated/Models/VectorStoreCreationOptions.cs +++ b/src/Generated/Models/VectorStoreCreationOptions.cs @@ -32,7 +32,7 @@ internal VectorStoreCreationOptions(IList fileIds, string name, IDiction public string Name { get; set; } - public IDictionary Metadata { get; set; } + public IDictionary Metadata { get; } internal IDictionary SerializedAdditionalRawData { diff --git a/src/Generated/Models/VectorStoreModificationOptions.Serialization.cs b/src/Generated/Models/VectorStoreModificationOptions.Serialization.cs index ad9c7f88..f74cbb1c 100644 --- a/src/Generated/Models/VectorStoreModificationOptions.Serialization.cs +++ b/src/Generated/Models/VectorStoreModificationOptions.Serialization.cs @@ -41,26 +41,19 @@ protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWrit } if (Optional.IsCollectionDefined(Metadata) && _additionalBinaryDataProperties?.ContainsKey("metadata") != true) { - if (Metadata != null) + writer.WritePropertyName("metadata"u8); + writer.WriteStartObject(); + foreach (var item in Metadata) { - writer.WritePropertyName("metadata"u8); - writer.WriteStartObject(); - foreach (var item in Metadata) + writer.WritePropertyName(item.Key); + if (item.Value == null) { - writer.WritePropertyName(item.Key); - if (item.Value == null) - { - writer.WriteNullValue(); - continue; - } - writer.WriteStringValue(item.Value); + writer.WriteNullValue(); + continue; } - writer.WriteEndObject(); - } - else - { - writer.WriteNull("metadata"u8); + writer.WriteStringValue(item.Value); } + writer.WriteEndObject(); } if (Optional.IsDefined(ExpirationPolicy) && _additionalBinaryDataProperties?.ContainsKey("expires_after") != true) { diff --git a/src/Generated/Models/VectorStoreModificationOptions.cs b/src/Generated/Models/VectorStoreModificationOptions.cs index a9a6d29b..9a581468 100644 --- a/src/Generated/Models/VectorStoreModificationOptions.cs +++ b/src/Generated/Models/VectorStoreModificationOptions.cs @@ -27,7 +27,7 @@ internal VectorStoreModificationOptions(string name, IDictionary public string Name { get; set; } - public IDictionary Metadata { get; set; } + public IDictionary Metadata { get; } internal IDictionary SerializedAdditionalRawData { diff --git a/src/Generated/OpenAIModelFactory.cs b/src/Generated/OpenAIModelFactory.cs index 10419b84..809cb209 100644 --- a/src/Generated/OpenAIModelFactory.cs +++ b/src/Generated/OpenAIModelFactory.cs @@ -419,7 +419,7 @@ public static ThreadDeletionResult ThreadDeletionResult(bool deleted = default, return new ThreadDeletionResult(deleted, threadId, @object, additionalBinaryDataProperties: null); } - public static ConversationSessionOptions ConversationSessionOptions(string instructions = default, ConversationVoice? voice = default, ConversationAudioFormat? inputAudioFormat = default, ConversationAudioFormat? outputAudioFormat = default, IEnumerable tools = default, float? temperature = default, ConversationTurnDetectionOptions turnDetectionOptions = default, ConversationInputTranscriptionOptions inputTranscriptionOptions = default, IEnumerable internalModalities = default, BinaryData internalToolChoice = default, BinaryData maxResponseOutputTokens = default) + public static ConversationSessionOptions ConversationSessionOptions(string instructions = default, ConversationVoice? voice = default, ConversationAudioFormat? inputAudioFormat = default, ConversationAudioFormat? outputAudioFormat = default, IEnumerable tools = default, float? temperature = default, InternalRealtimeRequestSessionModel? model = default, ConversationTurnDetectionOptions turnDetectionOptions = default, ConversationInputTranscriptionOptions inputTranscriptionOptions = default, IEnumerable internalModalities = default, BinaryData internalToolChoice = default, BinaryData maxResponseOutputTokens = default) { tools ??= new ChangeTrackingList(); internalModalities ??= new ChangeTrackingList(); @@ -431,6 +431,7 @@ public static ConversationSessionOptions ConversationSessionOptions(string instr outputAudioFormat, tools?.ToList(), temperature, + model, turnDetectionOptions, inputTranscriptionOptions, internalModalities?.ToList(), @@ -475,6 +476,28 @@ public static ConversationContentPart ConversationContentPart(string kind = defa return new UnknownRealtimeContentPart(new ConversationContentPartKind(kind), additionalBinaryDataProperties: null); } + public static ConversationResponseOptions ConversationResponseOptions(string instructions = default, ConversationVoice? voice = default, ConversationAudioFormat? outputAudioFormat = default, IEnumerable tools = default, float? temperature = default, IDictionary metadata = default, ResponseConversationSelection? conversationSelection = default, RealtimeConversation.ConversationMaxTokensChoice maxOutputTokens = default, IEnumerable overrideItems = default, IEnumerable internalModalities = default, BinaryData internalToolChoice = default) + { + tools ??= new ChangeTrackingList(); + metadata ??= new ChangeTrackingDictionary(); + overrideItems ??= new ChangeTrackingList(); + internalModalities ??= new ChangeTrackingList(); + + return new ConversationResponseOptions( + instructions, + voice, + outputAudioFormat, + tools?.ToList(), + temperature, + metadata, + conversationSelection, + maxOutputTokens, + overrideItems?.ToList(), + internalModalities?.ToList(), + internalToolChoice, + additionalBinaryDataProperties: null); + } + public static ConversationUpdate ConversationUpdate(string eventId = default, string kind = default) { @@ -523,7 +546,7 @@ public static ConversationInputSpeechFinishedUpdate ConversationInputSpeechFinis return new ConversationInputSpeechFinishedUpdate(eventId, RealtimeConversation.ConversationUpdateKind.InputSpeechStopped, additionalBinaryDataProperties: null, itemId, audioEndMs); } - public static ConversationItemCreatedUpdate ConversationItemCreatedUpdate(string eventId = default, string previousItemId = default, InternalRealtimeResponseItem internalItem = default) + public static ConversationItemCreatedUpdate ConversationItemCreatedUpdate(string eventId = default, string previousItemId = default, InternalRealtimeConversationResponseItem internalItem = default) { return new ConversationItemCreatedUpdate(eventId, RealtimeConversation.ConversationUpdateKind.ItemCreated, additionalBinaryDataProperties: null, previousItemId, internalItem); @@ -577,34 +600,34 @@ public static ConversationResponseStartedUpdate ConversationResponseStartedUpdat return new ConversationResponseStartedUpdate(eventId, RealtimeConversation.ConversationUpdateKind.ResponseStarted, additionalBinaryDataProperties: null, internalResponse); } - public static ConversationStatusDetails ConversationStatusDetails(string statusKind = default) + public static ConversationStatusDetails ConversationStatusDetails(ConversationStatus statusKind = default, ConversationIncompleteReason? incompleteReason = default, InternalRealtimeResponseStatusDetailsError error = default) { - return new UnknownRealtimeResponseStatusDetails(new ConversationStatus(statusKind), additionalBinaryDataProperties: null); + return new ConversationStatusDetails(statusKind, incompleteReason, error, additionalBinaryDataProperties: null); } - public static ConversationTokenUsage ConversationTokenUsage(int totalTokens = default, int inputTokens = default, int outputTokens = default, ConversationInputTokenUsageDetails inputTokenDetails = default, ConversationOutputTokenUsageDetails outputTokenDetails = default) + public static ConversationTokenUsage ConversationTokenUsage(ConversationInputTokenUsageDetails inputTokenDetails = default, ConversationOutputTokenUsageDetails outputTokenDetails = default, int inputTokenCount = default, int outputTokenCount = default, int totalTokenCount = default) { return new ConversationTokenUsage( - totalTokens, - inputTokens, - outputTokens, inputTokenDetails, outputTokenDetails, + inputTokenCount, + outputTokenCount, + totalTokenCount, additionalBinaryDataProperties: null); } - public static ConversationInputTokenUsageDetails ConversationInputTokenUsageDetails(int cachedTokens = default, int textTokens = default, int audioTokens = default) + public static ConversationInputTokenUsageDetails ConversationInputTokenUsageDetails(int audioTokenCount = default, int cachedTokenCount = default, int textTokenCount = default) { - return new ConversationInputTokenUsageDetails(cachedTokens, textTokens, audioTokens, additionalBinaryDataProperties: null); + return new ConversationInputTokenUsageDetails(audioTokenCount, cachedTokenCount, textTokenCount, additionalBinaryDataProperties: null); } - public static ConversationOutputTokenUsageDetails ConversationOutputTokenUsageDetails(int textTokens = default, int audioTokens = default) + public static ConversationOutputTokenUsageDetails ConversationOutputTokenUsageDetails(int textTokenCount = default, int audioTokenCount = default) { - return new ConversationOutputTokenUsageDetails(textTokens, audioTokens, additionalBinaryDataProperties: null); + return new ConversationOutputTokenUsageDetails(textTokenCount, audioTokenCount, additionalBinaryDataProperties: null); } public static ConversationResponseFinishedUpdate ConversationResponseFinishedUpdate(string eventId = default, InternalRealtimeResponse internalResponse = default) @@ -613,7 +636,7 @@ public static ConversationResponseFinishedUpdate ConversationResponseFinishedUpd return new ConversationResponseFinishedUpdate(eventId, RealtimeConversation.ConversationUpdateKind.ResponseFinished, additionalBinaryDataProperties: null, internalResponse); } - public static ConversationItemStreamingStartedUpdate ConversationItemStreamingStartedUpdate(string eventId = default, string responseId = default, int itemIndex = default, InternalRealtimeResponseItem internalItem = default) + public static ConversationItemStreamingStartedUpdate ConversationItemStreamingStartedUpdate(string eventId = default, string responseId = default, int itemIndex = default, InternalRealtimeConversationResponseItem internalItem = default) { return new ConversationItemStreamingStartedUpdate( @@ -625,7 +648,7 @@ public static ConversationItemStreamingStartedUpdate ConversationItemStreamingSt internalItem); } - public static ConversationItemStreamingFinishedUpdate ConversationItemStreamingFinishedUpdate(string eventId = default, string responseId = default, int outputIndex = default, InternalRealtimeResponseItem internalItem = default) + public static ConversationItemStreamingFinishedUpdate ConversationItemStreamingFinishedUpdate(string eventId = default, string responseId = default, int outputIndex = default, InternalRealtimeConversationResponseItem internalItem = default) { return new ConversationItemStreamingFinishedUpdate( @@ -822,11 +845,17 @@ public static ImageVariationOptions ImageVariationOptions(InternalCreateImageVar additionalBinaryDataProperties: null); } - public static OpenAIFileCollection OpenAIFileCollection(IEnumerable data = default, InternalListFilesResponseObject @object = default) + public static OpenAIFileCollection OpenAIFileCollection(IEnumerable data = default, string @object = default, string firstId = default, string lastId = default, bool hasMore = default) { data ??= new ChangeTrackingList(); - return new OpenAIFileCollection(data?.ToList(), @object, serializedAdditionalRawData: null); + return new OpenAIFileCollection( + data?.ToList(), + @object, + firstId, + lastId, + hasMore, + serializedAdditionalRawData: null); } public static FileDeletionResult FileDeletionResult(bool deleted = default, string fileId = default, InternalDeleteFileResponseObject @object = default) @@ -878,10 +907,10 @@ public static ChatTokenUsage ChatTokenUsage(int outputTokenCount = default, int additionalBinaryDataProperties: null); } - public static ChatOutputTokenUsageDetails ChatOutputTokenUsageDetails(int reasoningTokenCount = default, int audioTokenCount = default) + public static ChatOutputTokenUsageDetails ChatOutputTokenUsageDetails(int reasoningTokenCount = default, int audioTokenCount = default, int acceptedPredictionTokenCount = default, int rejectedPredictionTokenCount = default) { - return new ChatOutputTokenUsageDetails(reasoningTokenCount, audioTokenCount, additionalBinaryDataProperties: null); + return new ChatOutputTokenUsageDetails(reasoningTokenCount, audioTokenCount, acceptedPredictionTokenCount, rejectedPredictionTokenCount, additionalBinaryDataProperties: null); } public static ChatInputTokenUsageDetails ChatInputTokenUsageDetails(int audioTokenCount = default, int cachedTokenCount = default) @@ -890,7 +919,7 @@ public static ChatInputTokenUsageDetails ChatInputTokenUsageDetails(int audioTok return new ChatInputTokenUsageDetails(audioTokenCount, cachedTokenCount, additionalBinaryDataProperties: null); } - public static ChatCompletionOptions ChatCompletionOptions(float? frequencyPenalty = default, float? presencePenalty = default, ChatResponseFormat responseFormat = default, float? temperature = default, float? topP = default, IEnumerable tools = default, IEnumerable messages = default, InternalCreateChatCompletionRequestModel model = default, int? n = default, bool? stream = default, InternalChatCompletionStreamOptions streamOptions = default, bool? includeLogProbabilities = default, int? topLogProbabilityCount = default, IEnumerable stopSequences = default, IDictionary logitBiases = default, ChatToolChoice toolChoice = default, ChatFunctionChoice functionChoice = default, bool? allowParallelToolCalls = default, string endUserId = default, long? seed = default, int? deprecatedMaxTokens = default, int? maxOutputTokenCount = default, IEnumerable functions = default, IDictionary metadata = default, bool? storedOutputEnabled = default, InternalCreateChatCompletionRequestServiceTier? serviceTier = default) + public static ChatCompletionOptions ChatCompletionOptions(float? frequencyPenalty = default, float? presencePenalty = default, ChatResponseFormat responseFormat = default, float? temperature = default, float? topP = default, IEnumerable tools = default, IEnumerable messages = default, InternalCreateChatCompletionRequestModel model = default, int? n = default, bool? stream = default, InternalChatCompletionStreamOptions streamOptions = default, bool? includeLogProbabilities = default, int? topLogProbabilityCount = default, IEnumerable stopSequences = default, IDictionary logitBiases = default, ChatToolChoice toolChoice = default, ChatFunctionChoice functionChoice = default, bool? allowParallelToolCalls = default, string endUserId = default, long? seed = default, int? deprecatedMaxTokens = default, int? maxOutputTokenCount = default, IEnumerable functions = default, IDictionary metadata = default, bool? storedOutputEnabled = default, ChatReasoningEffortLevel? reasoningEffortLevel = default, ChatOutputPrediction outputPrediction = default, InternalCreateChatCompletionRequestServiceTier? serviceTier = default, IEnumerable internalModalities = default, ChatAudioOptions audioOptions = default) { tools ??= new ChangeTrackingList(); messages ??= new ChangeTrackingList(); @@ -898,6 +927,7 @@ public static ChatCompletionOptions ChatCompletionOptions(float? frequencyPenalt logitBiases ??= new ChangeTrackingDictionary(); functions ??= new ChangeTrackingList(); metadata ??= new ChangeTrackingDictionary(); + internalModalities ??= new ChangeTrackingList(); return new ChatCompletionOptions( frequencyPenalty, @@ -925,40 +955,57 @@ public static ChatCompletionOptions ChatCompletionOptions(float? frequencyPenalt functions?.ToList(), metadata, storedOutputEnabled, + reasoningEffortLevel, + outputPrediction, serviceTier, + internalModalities?.ToList(), + audioOptions, additionalBinaryDataProperties: null); } - public static ChatMessage ChatMessage(string role = default, ChatMessageContent content = default) + public static ChatMessage ChatMessage(ChatMessageContent content = default, string role = default) { - return new InternalUnknownChatMessage(role.ToChatMessageRole(), content, additionalBinaryDataProperties: null); + return new InternalUnknownChatMessage(content, role.ToChatMessageRole(), additionalBinaryDataProperties: null); } public static SystemChatMessage SystemChatMessage(ChatMessageContent content = default, string participantName = default) { - return new SystemChatMessage(Chat.ChatMessageRole.System, content, additionalBinaryDataProperties: null, participantName); + return new SystemChatMessage(content, Chat.ChatMessageRole.System, additionalBinaryDataProperties: null, participantName); + } + + public static DeveloperChatMessage DeveloperChatMessage(ChatMessageContent content = default, string participantName = default) + { + + return new DeveloperChatMessage(content, Chat.ChatMessageRole.Developer, additionalBinaryDataProperties: null, participantName); } public static UserChatMessage UserChatMessage(ChatMessageContent content = default, string participantName = default) { - return new UserChatMessage(Chat.ChatMessageRole.User, content, additionalBinaryDataProperties: null, participantName); + return new UserChatMessage(content, Chat.ChatMessageRole.User, additionalBinaryDataProperties: null, participantName); } - public static AssistantChatMessage AssistantChatMessage(ChatMessageContent content = default, string refusal = default, string participantName = default, IEnumerable toolCalls = default, ChatFunctionCall functionCall = default) + public static AssistantChatMessage AssistantChatMessage(ChatMessageContent content = default, string refusal = default, string participantName = default, IEnumerable toolCalls = default, ChatFunctionCall functionCall = default, ChatOutputAudioReference outputAudioReference = default) { toolCalls ??= new ChangeTrackingList(); return new AssistantChatMessage( - Chat.ChatMessageRole.Assistant, content, + Chat.ChatMessageRole.Assistant, additionalBinaryDataProperties: null, refusal, participantName, toolCalls?.ToList(), - functionCall); + functionCall, + outputAudioReference); + } + + public static ChatOutputAudioReference ChatOutputAudioReference(string id = default) + { + + return new ChatOutputAudioReference(id, additionalBinaryDataProperties: null); } public static ChatToolCall ChatToolCall(string id = default, InternalChatCompletionMessageToolCallFunction function = default, Chat.ChatToolCallKind kind = default) @@ -976,13 +1023,25 @@ public static ChatFunctionCall ChatFunctionCall(string functionName = default, B public static ToolChatMessage ToolChatMessage(ChatMessageContent content = default, string toolCallId = default) { - return new ToolChatMessage(Chat.ChatMessageRole.Tool, content, additionalBinaryDataProperties: null, toolCallId); + return new ToolChatMessage(content, Chat.ChatMessageRole.Tool, additionalBinaryDataProperties: null, toolCallId); } public static FunctionChatMessage FunctionChatMessage(ChatMessageContent content = default, string functionName = default) { - return new FunctionChatMessage(Chat.ChatMessageRole.Function, content, additionalBinaryDataProperties: null, functionName); + return new FunctionChatMessage(content, Chat.ChatMessageRole.Function, additionalBinaryDataProperties: null, functionName); + } + + public static ChatOutputPrediction ChatOutputPrediction(string @type = default) + { + + return new InternalUnknownChatOutputPrediction(new InternalChatOutputPredictionKind(@type), additionalBinaryDataProperties: null); + } + + public static ChatAudioOptions ChatAudioOptions(ChatOutputAudioVoice outputAudioVoice = default, ChatOutputAudioFormat outputAudioFormat = default) + { + + return new ChatAudioOptions(outputAudioVoice, outputAudioFormat, additionalBinaryDataProperties: null); } public static ChatResponseFormat ChatResponseFormat(string @type = default) @@ -1019,6 +1078,12 @@ public static ChatCompletion ChatCompletion(string id = default, string model = additionalBinaryDataProperties: null); } + public static ChatOutputAudio ChatOutputAudio(string id = default, DateTimeOffset expiresAt = default, string transcript = default, BinaryData audioBytes = default) + { + + return new ChatOutputAudio(id, expiresAt, transcript, audioBytes, additionalBinaryDataProperties: null); + } + public static ChatTokenLogProbabilityDetails ChatTokenLogProbabilityDetails(string token = default, float logProbability = default, ReadOnlyMemory? utf8Bytes = default, IEnumerable topLogProbabilities = default) { topLogProbabilities ??= new ChangeTrackingList(); @@ -1225,10 +1290,22 @@ public static ChatMessageContent ChatMessageContent() return new ChatMessageContent(additionalBinaryDataProperties: null); } - public static ChatMessageContentPart ChatMessageContentPart(Chat.ChatMessageContentPartKind kind = default, string text = default, InternalChatCompletionRequestMessageContentPartImageImageUrl imageUri = default, string refusal = default) + public static ChatMessageContentPart ChatMessageContentPart(Chat.ChatMessageContentPartKind kind = default, string text = default, InternalChatCompletionRequestMessageContentPartImageImageUrl imageUri = default, string refusal = default, InternalChatCompletionRequestMessageContentPartAudioInputAudio inputAudio = default) + { + + return new ChatMessageContentPart( + kind, + text, + imageUri, + refusal, + inputAudio, + serializedAdditionalRawData: null); + } + + public static StreamingChatOutputAudioUpdate StreamingChatOutputAudioUpdate(string id = default, DateTimeOffset? expiresAt = default, string transcriptUpdate = default, BinaryData audioBytesUpdate = default) { - return new ChatMessageContentPart(kind, text, imageUri, refusal, serializedAdditionalRawData: null); + return new StreamingChatOutputAudioUpdate(id, expiresAt, transcriptUpdate, audioBytesUpdate, additionalBinaryDataProperties: null); } public static StreamingChatFunctionCallUpdate StreamingChatFunctionCallUpdate(string functionName = default, BinaryData functionArgumentsUpdate = default) diff --git a/src/OpenAI.csproj b/src/OpenAI.csproj index 1626c53d..f0d283ce 100644 --- a/src/OpenAI.csproj +++ b/src/OpenAI.csproj @@ -9,7 +9,7 @@ 2.1.0 - netstandard2.0;net6.0;net8.0 + net8.0;net6.0;netstandard2.0 latest @@ -42,6 +42,9 @@ $(NoWarn),OPENAI001;OPENAI002 Debug;Release;Unsigned + + true + true @@ -78,14 +81,5 @@ - - - - true - true - true - false - false - diff --git a/src/SourceGenerationContext.cs b/src/SourceGenerationContext.cs deleted file mode 100644 index 7b909b03..00000000 --- a/src/SourceGenerationContext.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text.Json.Serialization; - -namespace OpenAI; - -[JsonSourceGenerationOptions] -[JsonSerializable(typeof(string))] -[JsonSerializable(typeof(IEnumerable))] -[JsonSerializable(typeof(IEnumerable>))] -[JsonSerializable(typeof(ReadOnlyMemory))] -internal sealed partial class SourceGenerationContext : JsonSerializerContext; \ No newline at end of file diff --git a/tests/Chat/ChatSmokeTests.cs b/tests/Chat/ChatSmokeTests.cs index 9d167808..7c518a4a 100644 --- a/tests/Chat/ChatSmokeTests.cs +++ b/tests/Chat/ChatSmokeTests.cs @@ -533,6 +533,119 @@ public void SerializeRefusalMessages() Assert.That(serialized, Does.Not.Contain("content")); } + [Test] + public void SerializeAudioThings() + { + // User audio input: wire-correlated ("real") content parts should cleanly serialize/deserialize + ChatMessageContentPart inputAudioContentPart = ChatMessageContentPart.CreateInputAudioPart( + BinaryData.FromBytes([0x4, 0x2]), + ChatInputAudioFormat.Mp3); + Assert.That(inputAudioContentPart, Is.Not.Null); + BinaryData serializedInputAudioContentPart = ModelReaderWriter.Write(inputAudioContentPart); + Assert.That(serializedInputAudioContentPart.ToString(), Does.Contain(@"""format"":""mp3""")); + ChatMessageContentPart deserializedInputAudioContentPart = ModelReaderWriter.Read(serializedInputAudioContentPart); + Assert.That(deserializedInputAudioContentPart.InputAudioBytes.ToArray()[1], Is.EqualTo(0x2)); + + AssistantChatMessage message = ModelReaderWriter.Read(BinaryData.FromBytes(""" + { + "role": "assistant", + "audio": { + "id": "audio_correlated_id_1234" + } + } + """u8.ToArray())); + Assert.That(message.Content, Has.Count.EqualTo(0)); + Assert.That(message.OutputAudioReference, Is.Not.Null); + Assert.That(message.OutputAudioReference.Id, Is.EqualTo("audio_correlated_id_1234")); + string serializedMessage = ModelReaderWriter.Write(message).ToString(); + Assert.That(serializedMessage, Does.Contain(@"""audio"":{""id"":""audio_correlated_id_1234""}")); + + AssistantChatMessage ordinaryTextAssistantMessage = new(["This was a message from the assistant"]); + ordinaryTextAssistantMessage.OutputAudioReference = new("extra-audio-id"); + BinaryData serializedLateAudioMessage = ModelReaderWriter.Write(ordinaryTextAssistantMessage); + Assert.That(serializedLateAudioMessage.ToString(), Does.Contain("was a message")); + Assert.That(serializedLateAudioMessage.ToString(), Does.Contain("extra-audio-id")); + + BinaryData rawAudioResponse = BinaryData.FromBytes(""" + { + "id": "chatcmpl-AOqyHuhjVDeGVbCZXJZ8mCLyl5nBq", + "object": "chat.completion", + "created": 1730486857, + "model": "gpt-4o-audio-preview-2024-10-01", + "choices": [ + { + "index": 0, + "message": { + "role": "assistant", + "content": null, + "refusal": null, + "audio": { + "id": "audio_6725224ac62481908ab55dc283289d87", + "data": "dHJ1bmNhdGVk", + "expires_at": 1730490458, + "transcript": "Hello there! How can I assist you with your test today?" + } + }, + "finish_reason": "stop" + } + ], + "usage": { + "prompt_tokens": 28, + "completion_tokens": 97, + "total_tokens": 125, + "prompt_tokens_details": { + "cached_tokens": 0, + "text_tokens": 11, + "image_tokens": 0, + "audio_tokens": 17 + }, + "completion_tokens_details": { + "reasoning_tokens": 0, + "text_tokens": 23, + "audio_tokens": 74, + "accepted_prediction_tokens": 0, + "rejected_prediction_tokens": 0 + } + }, + "system_fingerprint": "fp_49254d0e9b" + } + """u8.ToArray()); + ChatCompletion audioCompletion = ModelReaderWriter.Read(rawAudioResponse); + Assert.That(audioCompletion, Is.Not.Null); + Assert.That(audioCompletion.Content, Has.Count.EqualTo(0)); + Assert.That(audioCompletion.OutputAudio, Is.Not.Null); + Assert.That(audioCompletion.OutputAudio.Id, Is.EqualTo("audio_6725224ac62481908ab55dc283289d87")); + Assert.That(audioCompletion.OutputAudio.AudioBytes, Is.Not.Null); + Assert.That(audioCompletion.OutputAudio.Transcript, Is.Not.Null.And.Not.Empty); + + AssistantChatMessage audioHistoryMessage = new(audioCompletion); + Assert.That(audioHistoryMessage.OutputAudioReference?.Id, Is.EqualTo(audioCompletion.OutputAudio.Id)); + + foreach (KeyValuePair modalitiesValueToKeyTextAndAudioPresenceItem + in new List>() + { + new(ChatResponseModalities.Default, (false, false, false)), + new(ChatResponseModalities.Default | ChatResponseModalities.Text, (true, true, false)), + new(ChatResponseModalities.Default | ChatResponseModalities.Audio, (true, false, true)), + new(ChatResponseModalities.Default | ChatResponseModalities.Text | ChatResponseModalities.Audio, (true, true, true)), + new(ChatResponseModalities.Text, (true, true, false)), + new(ChatResponseModalities.Audio, (true, false, true)), + new(ChatResponseModalities.Text | ChatResponseModalities.Audio, (true, true, true)), + }) + { + ChatResponseModalities modalitiesValue = modalitiesValueToKeyTextAndAudioPresenceItem.Key; + (bool keyExpected, bool textExpected, bool audioExpected) = modalitiesValueToKeyTextAndAudioPresenceItem.Value; + ChatCompletionOptions testOptions = new() + { + ResponseModalities = modalitiesValue, + }; + string serializedOptions = ModelReaderWriter.Write(testOptions).ToString().ToLower(); + Assert.That(serializedOptions.Contains("modalities"), Is.EqualTo(keyExpected)); + Assert.That(serializedOptions.Contains("text"), Is.EqualTo(textExpected)); + Assert.That(serializedOptions.Contains("audio"), Is.EqualTo(audioExpected)); + } + } + [Test] [TestCase(true)] [TestCase(false)] @@ -716,6 +829,27 @@ public void SerializeChatMessageWithNoContent(bool fromRawJson) } } +#pragma warning disable CS0618 + [Test] + public void AssistantAndFunctionMessagesHandleNoContentCorrectly() + { + // AssistantChatMessage and FunctionChatMessage can both exist without content, but follow different rules: + // - AssistantChatMessage treats content as optional, as valid assistant message variants (e.g. for tool calls) + // - FunctionChatMessage meanwhile treats content as required and nullable. + // This test validates that no-content assistant messages just don't serialize content, while no-content + // function messages serialize content with an explicit null value. + + ChatToolCall fakeToolCall = ChatToolCall.CreateFunctionToolCall("call_abcd1234", "function_name", functionArguments: BinaryData.FromString("{}")); + AssistantChatMessage assistantChatMessage = new([fakeToolCall]); + string serializedAssistantChatMessage = ModelReaderWriter.Write(assistantChatMessage).ToString(); + Assert.That(serializedAssistantChatMessage, Does.Not.Contain("content")); + + FunctionChatMessage functionChatMessage = new("function_name", null); + string serializedFunctionChatMessage = ModelReaderWriter.Write(functionChatMessage).ToString(); + Assert.That(serializedFunctionChatMessage, Does.Contain(@"""content"":null")); + } +#pragma warning restore CS0618 + #pragma warning disable CS0618 [Test] public void SerializeMessagesWithNullProperties() @@ -793,4 +927,13 @@ public void TopLevelClientOptionsPersistence() Assert.That(observedEndpoint, Is.Not.Null); Assert.That(observedEndpoint.AbsoluteUri, Does.Contain("my.custom.com/expected/test/endpoint")); } + + [Test] + public void CanUseCollections() + { + ChatCompletionOptions options = new(); + Assert.That(options.Tools.Count, Is.EqualTo(0)); + Assert.That(options.Metadata.Count, Is.EqualTo(0)); + Assert.That(options.StopSequences.Count, Is.EqualTo(0)); + } } diff --git a/tests/Chat/ChatTests.cs b/tests/Chat/ChatTests.cs index b4943967..04c5db51 100644 --- a/tests/Chat/ChatTests.cs +++ b/tests/Chat/ChatTests.cs @@ -93,8 +93,6 @@ public void StreamingChat() latestTokenReceiptTime = stopwatch.Elapsed; usage ??= chatUpdate.Usage; updateCount++; - - Console.WriteLine(stopwatch.Elapsed.TotalMilliseconds); } stopwatch.Stop(); @@ -368,6 +366,88 @@ public async Task ChatWithVision() Assert.That(result.Value.Content[0].Text.ToLowerInvariant(), Does.Contain("dog").Or.Contain("cat").IgnoreCase); } + [Test] + public async Task ChatWithAudio() + { + ChatClient client = GetTestClient(TestScenario.Chat, "gpt-4o-audio-preview"); + + string helloWorldAudioPath = Path.Join("Assets", "audio_hello_world.mp3"); + BinaryData helloWorldAudioBytes = BinaryData.FromBytes(File.ReadAllBytes(helloWorldAudioPath)); + ChatMessageContentPart helloWorldAudioContentPart = ChatMessageContentPart.CreateInputAudioPart( + helloWorldAudioBytes, + ChatInputAudioFormat.Mp3); + string whatsTheWeatherAudioPath = Path.Join("Assets", "realtime_whats_the_weather_pcm16_24khz_mono.wav"); + BinaryData whatsTheWeatherAudioBytes = BinaryData.FromBytes(File.ReadAllBytes(whatsTheWeatherAudioPath)); + ChatMessageContentPart whatsTheWeatherAudioContentPart = ChatMessageContentPart.CreateInputAudioPart( + whatsTheWeatherAudioBytes, + ChatInputAudioFormat.Wav); + + List messages = [new UserChatMessage([helloWorldAudioContentPart])]; + + ChatCompletionOptions options = new() + { + ResponseModalities = ChatResponseModalities.Text | ChatResponseModalities.Audio, + AudioOptions = new(ChatOutputAudioVoice.Alloy, ChatOutputAudioFormat.Pcm16) + }; + + ChatCompletion completion = await client.CompleteChatAsync(messages, options); + Assert.That(completion, Is.Not.Null); + Assert.That(completion.Content, Has.Count.EqualTo(0)); + + ChatOutputAudio outputAudio = completion.OutputAudio; + Assert.That(outputAudio, Is.Not.Null); + Assert.That(outputAudio.Id, Is.Not.Null.And.Not.Empty); + Assert.That(outputAudio.AudioBytes, Is.Not.Null); + Assert.That(outputAudio.Transcript, Is.Not.Null.And.Not.Empty); + + AssistantChatMessage audioHistoryMessage = ChatMessage.CreateAssistantMessage(completion); + Assert.That(audioHistoryMessage, Is.InstanceOf()); + Assert.That(audioHistoryMessage.Content, Has.Count.EqualTo(0)); + + Assert.That(audioHistoryMessage.OutputAudioReference?.Id, Is.EqualTo(completion.OutputAudio.Id)); + messages.Add(audioHistoryMessage); + + messages.Add( + new UserChatMessage( + [ + "Please answer the following spoken question:", + ChatMessageContentPart.CreateInputAudioPart(whatsTheWeatherAudioBytes, ChatInputAudioFormat.Wav), + ])); + + string streamedCorrelationId = null; + DateTimeOffset? streamedExpiresAt = null; + StringBuilder streamedTranscriptBuilder = new(); + using MemoryStream outputAudioStream = new(); + await foreach (StreamingChatCompletionUpdate update in client.CompleteChatStreamingAsync(messages, options)) + { + Assert.That(update.ContentUpdate, Has.Count.EqualTo(0)); + StreamingChatOutputAudioUpdate outputAudioUpdate = update.OutputAudioUpdate; + + if (outputAudioUpdate is not null) + { + string serializedOutputAudioUpdate = ModelReaderWriter.Write(outputAudioUpdate).ToString(); + Assert.That(serializedOutputAudioUpdate, Is.Not.Null.And.Not.Empty); + + if (outputAudioUpdate.Id is not null) + { + Assert.That(streamedCorrelationId, Is.Null.Or.EqualTo(streamedCorrelationId)); + streamedCorrelationId ??= outputAudioUpdate.Id; + } + if (outputAudioUpdate.ExpiresAt.HasValue) + { + Assert.That(streamedExpiresAt.HasValue, Is.False); + streamedExpiresAt = outputAudioUpdate.ExpiresAt; + } + streamedTranscriptBuilder.Append(outputAudioUpdate.TranscriptUpdate); + outputAudioStream.Write(outputAudioUpdate.AudioBytesUpdate); + } + } + Assert.That(streamedCorrelationId, Is.Not.Null.And.Not.Empty); + Assert.That(streamedExpiresAt.HasValue, Is.True); + Assert.That(streamedTranscriptBuilder.ToString(), Is.Not.Null.And.Not.Empty); + Assert.That(outputAudioStream.Length, Is.GreaterThan(9000)); + } + [Test] public async Task AuthFailure() { @@ -787,13 +867,15 @@ public async Task HelloWorldChatWithTracingAndMetrics() [Test] public async Task ReasoningTokensWork() { - ChatClient client = GetTestClient(TestScenario.Chat, "o1-mini"); + ChatClient client = GetTestClient(TestScenario.Chat, "o3-mini"); UserChatMessage message = new("Using a comprehensive evaluation of popular media in the 1970s and 1980s, what were the most common sci-fi themes?"); ChatCompletionOptions options = new() { - MaxOutputTokenCount = 2148 + MaxOutputTokenCount = 2148, + ReasoningEffortLevel = ChatReasoningEffortLevel.Low, }; + Assert.That(ModelReaderWriter.Write(options).ToString(), Does.Contain(@"""reasoning_effort"":""low""")); ClientResult completionResult = IsAsync ? await client.CompleteChatAsync([message], options) : client.CompleteChat([message], options); @@ -807,4 +889,100 @@ public async Task ReasoningTokensWork() Assert.That(completion.Usage.OutputTokenDetails?.ReasoningTokenCount, Is.GreaterThan(0)); Assert.That(completion.Usage.OutputTokenDetails?.ReasoningTokenCount, Is.LessThan(completion.Usage.OutputTokenCount)); } + + [Test] + public async Task PredictedOutputsWork() + { + ChatClient client = GetTestClient(TestScenario.Chat); + + foreach (ChatOutputPrediction predictionVariant in new List( + [ + // Plain string + ChatOutputPrediction.CreateStaticContentPrediction(""" + { + "feature_name": "test_feature", + "enabled": true + } + """.ReplaceLineEndings("\n")), + // One content part + ChatOutputPrediction.CreateStaticContentPrediction( + [ + ChatMessageContentPart.CreateTextPart(""" + { + "feature_name": "test_feature", + "enabled": true + } + """.ReplaceLineEndings("\n")), + ]), + // Several content parts + ChatOutputPrediction.CreateStaticContentPrediction( + [ + "{\n", + " \"feature_name\": \"test_feature\",\n", + " \"enabled\": true\n", + "}", + ]), + ])) + { + ChatCompletionOptions options = new() + { + OutputPrediction = predictionVariant, + }; + + ChatMessage message = ChatMessage.CreateUserMessage(""" + Modify the following input to enable the feature. Only respond with the JSON and include no other text. Do not enclose in markdown backticks or any other additional annotations. + + { + "feature_name": "test_feature", + "enabled": false + } + """.ReplaceLineEndings("\n")); + + ChatCompletion completion = await client.CompleteChatAsync([message], options); + + Assert.That(completion.Usage.OutputTokenDetails.AcceptedPredictionTokenCount, Is.GreaterThan(0)); + } + } + + [Test] + public async Task O3miniDeveloperMessagesWork() + { + List messages = + [ + ChatMessage.CreateDeveloperMessage("End every response to the user with the exact phrase: 'Hope this helps!'"), + ChatMessage.CreateUserMessage("How long will it take to make a cheesecake from scratch? Including getting ingredients.") + ]; + + ChatCompletionOptions options = new() + { + ReasoningEffortLevel = ChatReasoningEffortLevel.Low, + }; + + ChatClient client = GetTestClient(TestScenario.Chat, "o3-mini"); + ChatCompletion completion = await client.CompleteChatAsync(messages, options); + + Assert.That(completion.Content, Has.Count.EqualTo(1)); + Assert.That(completion.Content[0].Text, Does.EndWith("Hope this helps!")); + } + + [Test] + public async Task ChatMetadata() + { + ChatClient client = GetTestClient(); + + ChatCompletionOptions options = new() + { + StoredOutputEnabled = true, + Metadata = + { + ["my_metadata_key"] = "my_metadata_value", + }, + }; + + ChatCompletion completion = await client.CompleteChatAsync( + ["Hello, world!"], + options); + } + + private static ChatClient GetTestClient(string overrideModel = null) => GetTestClient(TestScenario.Chat, overrideModel); } diff --git a/tests/Files/FilesMockTests.cs b/tests/Files/FilesMockTests.cs index 25bbbe50..eace0f3f 100644 --- a/tests/Files/FilesMockTests.cs +++ b/tests/Files/FilesMockTests.cs @@ -265,6 +265,7 @@ public async Task GetFilesDeserializesId() { OpenAIClientOptions clientOptions = GetClientOptionsWithMockResponse(200, """ { + "object": "list", "data": [ { "id": "returned_file_id" @@ -287,6 +288,7 @@ public async Task GetFilesDeserializesCreatedAt() { OpenAIClientOptions clientOptions = GetClientOptionsWithMockResponse(200, """ { + "object": "list", "data": [ { "created_at": 1704096000 @@ -310,6 +312,7 @@ public async Task GetFilesDeserializesPurpose((string stringValue, FilePurpose e { OpenAIClientOptions clientOptions = GetClientOptionsWithMockResponse(200, $$""" { + "object": "list", "data": [ { "purpose": "{{purpose.stringValue}}" @@ -334,6 +337,7 @@ public async Task GetFilesDeserializesStatus((string stringValue, FileStatus exp { OpenAIClientOptions clientOptions = GetClientOptionsWithMockResponse(200, $$""" { + "object": "list", "data": [ { "status": "{{status.stringValue}}" @@ -358,6 +362,7 @@ public async Task GetFilesDeserializesStatusDetails() { OpenAIClientOptions clientOptions = GetClientOptionsWithMockResponse(200, """ { + "object": "list", "data": [ { "status_details": "This is definitely an error." diff --git a/tests/Images/ImagesTests.cs b/tests/Images/ImagesTests.cs index 3fe13179..2246da36 100644 --- a/tests/Images/ImagesTests.cs +++ b/tests/Images/ImagesTests.cs @@ -6,6 +6,7 @@ using System.ClientModel; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Threading.Tasks; using static OpenAI.Tests.TestHelpers; @@ -47,7 +48,7 @@ public async Task BasicGenerationWorks() Assert.That(image.ImageBytes, Is.Null); Console.WriteLine(image.ImageUri.AbsoluteUri); - ValidateGeneratedImage(image.ImageUri, "stop"); + ValidateGeneratedImage(image.ImageUri, ["stop"]); } [Test] @@ -69,7 +70,7 @@ public async Task GenerationWithOptionsWorks() Assert.That(image.ImageUri, Is.Not.Null); Assert.That(image.ImageBytes, Is.Null); - ValidateGeneratedImage(image.ImageUri, "stop"); + ValidateGeneratedImage(image.ImageUri, ["stop"]); } [Test] @@ -90,7 +91,7 @@ public async Task GenerationWithBytesResponseWorks() Assert.That(image.ImageUri, Is.Null); Assert.That(image.ImageBytes, Is.Not.Null); - ValidateGeneratedImage(image.ImageBytes, "stop"); + ValidateGeneratedImage(image.ImageBytes, ["stop"]); } [Test] @@ -132,7 +133,7 @@ public async Task GenerationOfMultipleImagesWorks() { Assert.That(image.ImageUri, Is.Not.Null); Assert.That(image.ImageBytes, Is.Null); - ValidateGeneratedImage(image.ImageUri, "stop"); + ValidateGeneratedImage(image.ImageUri, ["stop"]); } } @@ -161,7 +162,7 @@ public async Task GenerationOfMultipleImagesWithBytesResponseWorks() { Assert.That(image.ImageUri, Is.Null); Assert.That(image.ImageBytes, Is.Not.Null); - ValidateGeneratedImage(image.ImageBytes, "stop"); + ValidateGeneratedImage(image.ImageBytes, ["stop"]); } } @@ -222,7 +223,7 @@ public async Task GenerateImageEditWorks(ImageSourceKind imageSourceKind) Console.WriteLine(image.ImageUri.AbsoluteUri); - ValidateGeneratedImage(image.ImageUri, "cat", "Note that it likely depicts some sort of animal."); + ValidateGeneratedImage(image.ImageUri, ["cat", "owl", "animal"], "Note that it likely depicts some sort of animal."); } [Test] @@ -262,7 +263,7 @@ public async Task GenerateImageEditWithBytesResponseWorks(ImageSourceKind imageS Assert.That(image.ImageUri, Is.Null); Assert.That(image.ImageBytes, Is.Not.Null); - ValidateGeneratedImage(image.ImageBytes, "cat", "Note that it likely depicts some sort of animal."); + ValidateGeneratedImage(image.ImageBytes, ["cat", "owl", "animal"], "Note that it likely depicts some sort of animal."); } [Test] @@ -345,7 +346,7 @@ public async Task GenerateImageEditWithMaskFileWorks(ImageSourceKind imageSource Console.WriteLine(image.ImageUri.AbsoluteUri); - ValidateGeneratedImage(image.ImageUri, "cat", "Note that it likely depicts some sort of animal."); + ValidateGeneratedImage(image.ImageUri, ["cat", "owl", "animal"], "Note that it likely depicts some sort of animal."); } [Test] @@ -388,7 +389,7 @@ public async Task GenerateImageEditWithMaskFileWithBytesResponseWorks(ImageSourc Assert.That(image.ImageUri, Is.Null); Assert.That(image.ImageBytes, Is.Not.Null); - ValidateGeneratedImage(image.ImageBytes, "cat", "Note that it likely depicts some sort of animal."); + ValidateGeneratedImage(image.ImageBytes, ["cat", "owl", "animal"], "Note that it likely depicts some sort of animal."); } [Test] @@ -478,7 +479,7 @@ public async Task GenerateMultipleImageEditsWorks(ImageSourceKind imageSourceKin Assert.That(image.ImageUri, Is.Not.Null); Assert.That(image.ImageBytes, Is.Null); Console.WriteLine(image.ImageUri.AbsoluteUri); - ValidateGeneratedImage(image.ImageUri, "cat", "Note that it likely depicts some sort of animal."); + ValidateGeneratedImage(image.ImageUri, ["cat", "owl", "animal"], "Note that it likely depicts some sort of animal."); } } @@ -525,7 +526,7 @@ public async Task GenerateMultipleImageEditsWithBytesResponseWorks(ImageSourceKi { Assert.That(image.ImageUri, Is.Null); Assert.That(image.ImageBytes, Is.Not.Null); - ValidateGeneratedImage(image.ImageBytes, "cat", "Note that it likely depicts some sort of animal."); + ValidateGeneratedImage(image.ImageBytes, ["cat", "owl", "animal"], "Note that it likely depicts some sort of animal."); } } @@ -614,7 +615,7 @@ public async Task GenerateMultipleImageEditsWithMaskFileWorks(ImageSourceKind im Assert.That(image.ImageUri, Is.Not.Null); Assert.That(image.ImageBytes, Is.Null); Console.WriteLine(image.ImageUri.AbsoluteUri); - ValidateGeneratedImage(image.ImageUri, "cat", "Note that it likely depicts some sort of animal."); + ValidateGeneratedImage(image.ImageUri, ["cat", "owl", "animal"], "Note that it likely depicts some sort of animal."); } } @@ -664,7 +665,7 @@ public async Task GenerateMultipleImageEditsWithMaskFileWithBytesResponseWorks(I { Assert.That(image.ImageUri, Is.Null); Assert.That(image.ImageBytes, Is.Not.Null); - ValidateGeneratedImage(image.ImageBytes, "cat", "Note that it likely depicts some sort of animal."); + ValidateGeneratedImage(image.ImageBytes, ["cat", "owl", "animal"], "Note that it likely depicts some sort of animal."); } } @@ -753,7 +754,7 @@ public async Task GenerateImageVariationWorks(ImageSourceKind imageSourceKind) Console.WriteLine(image.ImageUri.AbsoluteUri); - ValidateGeneratedImage(image.ImageUri, "cat", "Note that it likely depicts some sort of animal."); + ValidateGeneratedImage(image.ImageUri, ["cat", "owl", "animal"], "Note that it likely depicts some sort of animal."); } [Test] @@ -792,7 +793,7 @@ public async Task GenerateImageVariationWithBytesResponseWorks(ImageSourceKind i Assert.That(image.ImageUri, Is.Null); Assert.That(image.ImageBytes, Is.Not.Null); - ValidateGeneratedImage(image.ImageBytes, "cat", "Note that it likely depicts some sort of animal."); + ValidateGeneratedImage(image.ImageBytes, ["cat", "owl", "animal"], "Note that it likely depicts some sort of animal."); } [Test] @@ -876,7 +877,7 @@ public async Task GenerateMultipleImageVariationsWorks(ImageSourceKind imageSour Assert.That(image.ImageUri, Is.Not.Null); Assert.That(image.ImageBytes, Is.Null); Console.WriteLine(image.ImageUri.AbsoluteUri); - ValidateGeneratedImage(image.ImageUri, "cat", "Note that it likely depicts some sort of animal."); + ValidateGeneratedImage(image.ImageUri, ["cat", "owl", "animal"], "Note that it likely depicts some sort of animal."); } } @@ -922,7 +923,7 @@ public async Task GenerateMultipleImageVariationsWithBytesResponseWorks(ImageSou { Assert.That(image.ImageUri, Is.Null); Assert.That(image.ImageBytes, Is.Not.Null); - ValidateGeneratedImage(image.ImageBytes, "cat", "Note that it likely depicts some sort of animal."); + ValidateGeneratedImage(image.ImageBytes, ["cat", "owl", "animal"], "Note that it likely depicts some sort of animal."); } } @@ -971,7 +972,7 @@ public void GenerateMultipleImageVariationsFromPathCanParseServiceError() #endregion - private void ValidateGeneratedImage(Uri imageUri, string expectedSubstring, string descriptionHint = null) + private void ValidateGeneratedImage(Uri imageUri, IEnumerable possibleExpectedSubstrings, string descriptionHint = null) { ChatClient chatClient = GetTestClient(TestScenario.Chat); IEnumerable messages = [ @@ -982,10 +983,13 @@ private void ValidateGeneratedImage(Uri imageUri, string expectedSubstring, stri ChatCompletionOptions chatOptions = new() { MaxOutputTokenCount = 2048 }; ClientResult result = chatClient.CompleteChat(messages, chatOptions); - Assert.That(result.Value.Content[0].Text.ToLowerInvariant(), Contains.Substring(expectedSubstring)); + Assert.That(result.Value?.Content, Has.Count.EqualTo(1)); + string contentText = result.Value.Content[0].Text.ToLowerInvariant(); + + Assert.That(possibleExpectedSubstrings.Any(possibleExpectedSubstring => contentText.Contains(possibleExpectedSubstring))); } - private void ValidateGeneratedImage(BinaryData imageBytes, string expectedSubstring, string descriptionHint = null) + private void ValidateGeneratedImage(BinaryData imageBytes, IEnumerable possibleExpectedSubstrings, string descriptionHint = null) { ChatClient chatClient = GetTestClient(TestScenario.Chat); IEnumerable messages = [ @@ -996,6 +1000,9 @@ private void ValidateGeneratedImage(BinaryData imageBytes, string expectedSubstr ChatCompletionOptions chatOptions = new() { MaxOutputTokenCount = 2048 }; ClientResult result = chatClient.CompleteChat(messages, chatOptions); - Assert.That(result.Value.Content[0].Text.ToLowerInvariant(), Contains.Substring(expectedSubstring)); + Assert.That(result.Value?.Content, Has.Count.EqualTo(1)); + string contentText = result.Value.Content[0].Text.ToLowerInvariant(); + + Assert.That(possibleExpectedSubstrings.Any(possibleExpectedSubstring => contentText.Contains(possibleExpectedSubstring))); } } diff --git a/tests/RealtimeConversation/ConversationTests.cs b/tests/RealtimeConversation/ConversationTests.cs index a38fdecf..d993c128 100644 --- a/tests/RealtimeConversation/ConversationTests.cs +++ b/tests/RealtimeConversation/ConversationTests.cs @@ -37,7 +37,7 @@ public async Task CanConfigureSession() }; await session.ConfigureSessionAsync(sessionOptions, CancellationToken); - ConversationSessionOptions responseOverrideOptions = new() + ConversationResponseOptions responseOverrideOptions = new() { ContentModalities = ConversationContentModalities.Text, }; @@ -137,6 +137,9 @@ await session.AddItemAsync( if (update is ConversationResponseFinishedUpdate responseFinishedUpdate) { Assert.That(responseFinishedUpdate.CreatedItems, Has.Count.GreaterThan(0)); + Assert.That(responseFinishedUpdate.Usage?.TotalTokenCount, Is.GreaterThan(0)); + Assert.That(responseFinishedUpdate.Usage.InputTokenCount, Is.GreaterThan(0)); + Assert.That(responseFinishedUpdate.Usage.OutputTokenCount, Is.GreaterThan(0)); gotResponseDone = true; break; } @@ -527,6 +530,78 @@ public async Task CanAddItems() Assert.That(itemCreatedCount, Is.EqualTo(items.Count + 1)); } + [Test] + public async Task CanUseOutOfBandResponses() + { + RealtimeConversationClient client = GetTestClient(); + using RealtimeConversationSession session = await client.StartConversationSessionAsync(CancellationToken); + await session.AddItemAsync( + ConversationItem.CreateUserMessage(["Hello! My name is Bob."]), + cancellationToken: CancellationToken); + await session.StartResponseAsync( + new ConversationResponseOptions() + { + ConversationSelection = ResponseConversationSelection.None, + ContentModalities = ConversationContentModalities.Text, + OverrideItems = + { + ConversationItem.CreateUserMessage(["Can you tell me what my name is?"]), + }, + }, + CancellationToken); + + StringBuilder firstResponseBuilder = new(); + StringBuilder secondResponseBuilder = new(); + + int completedResponseCount = 0; + + await foreach (ConversationUpdate update in session.ReceiveUpdatesAsync(CancellationToken)) + { + if (update is ConversationSessionStartedUpdate sessionStartedUpdate) + { + Assert.That(sessionStartedUpdate.SessionId, Is.Not.Null.And.Not.Empty); + } + + if (update is ConversationItemStreamingPartDeltaUpdate deltaUpdate) + { + // First response (out of band) should be text, second (in-band) should be text + audio + if (completedResponseCount == 0) + { + firstResponseBuilder.Append(deltaUpdate.Text); + Assert.That(deltaUpdate.AudioTranscript, Is.Null.Or.Empty); + } + else + { + secondResponseBuilder.Append(deltaUpdate.AudioTranscript); + Assert.That(deltaUpdate.Text, Is.Null.Or.Empty); + } + } + + if (update is ConversationResponseFinishedUpdate responseFinishedUpdate) + { + completedResponseCount++; + Assert.That(responseFinishedUpdate.CreatedItems, Has.Count.GreaterThan(0)); + if (completedResponseCount == 1) + { + // Verify that an in-band response *does* have the information + _ = session.StartResponseAsync(CancellationToken); + } + else if (completedResponseCount == 2) + { + break; + } + } + } + + string firstResponse = firstResponseBuilder.ToString().ToLower(); + Assert.That(firstResponse, Is.Not.Null.And.Not.Empty); + Assert.That(firstResponse, Does.Not.Contain("bob")); + + string secondResponse = secondResponseBuilder.ToString().ToLower(); + Assert.That(secondResponse, Is.Not.Null.And.Not.Empty); + Assert.That(secondResponse, Does.Contain("bob")); + } + public enum TestAudioSendType { WithAudioStreamHelper, diff --git a/tests/Utility/TestHelpers.cs b/tests/Utility/TestHelpers.cs index a781a91a..2bd54002 100644 --- a/tests/Utility/TestHelpers.cs +++ b/tests/Utility/TestHelpers.cs @@ -17,6 +17,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Text.RegularExpressions; [assembly: LevelOfParallelism(8)] @@ -49,7 +50,7 @@ public static T GetTestClient(TestScenario scenario, string overrideModel = n { options ??= new(); ApiKeyCredential credential = new(Environment.GetEnvironmentVariable("OPENAI_API_KEY")); - options.AddPolicy(GetDumpPolicy(), PipelinePosition.PerTry); + options.AddPolicy(GetDumpPolicy(), PipelinePosition.BeforeTransport); object clientObject = scenario switch { #pragma warning disable OPENAI001 @@ -81,36 +82,48 @@ private static PipelinePolicy GetDumpPolicy() { return new TestPipelinePolicy((message) => { - Console.WriteLine($"--- New request ---"); - IEnumerable headerPairs = message?.Request?.Headers?.Select(header => $"{header.Key}={(header.Key.ToLower().Contains("auth") ? "***" : header.Value)}"); - string headers = string.Join(',', headerPairs); - Console.WriteLine($"Headers: {headers}"); - Console.WriteLine($"{message?.Request?.Method} URI: {message?.Request?.Uri}"); - if (message.Request?.Content != null) + if (message.Request is not null && message.Response is null) { - string contentType = "Unknown Content Type"; - if (message.Request.Headers?.TryGetValue("Content-Type", out contentType) == true - && contentType == "application/json") + Console.WriteLine($"--- New request ---"); + IEnumerable headerPairs = message?.Request?.Headers?.Select(header => $"{header.Key}={(header.Key.ToLower().Contains("auth") ? "***" : header.Value)}"); + string headers = string.Join(',', headerPairs); + Console.WriteLine($"Headers: {headers}"); + Console.WriteLine($"{message?.Request?.Method} URI: {message?.Request?.Uri}"); + if (message.Request?.Content != null) { - using MemoryStream stream = new(); - message.Request.Content.WriteTo(stream, default); - stream.Position = 0; - using StreamReader reader = new(stream); - Console.WriteLine(reader.ReadToEnd()); - } - else - { - string length = message.Request.Content.TryComputeLength(out long numberLength) - ? $"{numberLength} bytes" - : "unknown length"; - Console.WriteLine($"<< Non-JSON content: {contentType} >> {length}"); + string contentType = "Unknown Content Type"; + if (message.Request.Headers?.TryGetValue("Content-Type", out contentType) == true + && contentType == "application/json") + { + using MemoryStream stream = new(); + message.Request.Content.WriteTo(stream, default); + stream.Position = 0; + using StreamReader reader = new(stream); + string requestDump = reader.ReadToEnd(); + requestDump = Regex.Replace(requestDump, @"""data"":[\\w\\r\\n]*""[^""]*""", @"""data"":""..."""); + Console.WriteLine(requestDump); + } + else + { + string length = message.Request.Content.TryComputeLength(out long numberLength) + ? $"{numberLength} bytes" + : "unknown length"; + Console.WriteLine($"<< Non-JSON content: {contentType} >> {length}"); + } } } if (message.Response != null) { - Console.WriteLine("--- Begin response content ---"); - Console.WriteLine(message.Response.Content?.ToString()); - Console.WriteLine("--- End of response content ---"); + if (message.BufferResponse) + { + Console.WriteLine("--- Begin response content ---"); + Console.WriteLine(message.Response.Content?.ToString()); + Console.WriteLine("--- End of response content ---"); + } + else + { + Console.WriteLine("--- Response (unbuffered, content not rendered) ---"); + } } }); } diff --git a/tests/Utility/TestPipelinePolicy.cs b/tests/Utility/TestPipelinePolicy.cs index 688c407e..c596295f 100644 --- a/tests/Utility/TestPipelinePolicy.cs +++ b/tests/Utility/TestPipelinePolicy.cs @@ -17,19 +17,15 @@ public TestPipelinePolicy(Action processMessageAction) public override void Process(PipelineMessage message, IReadOnlyList pipeline, int currentIndex) { - _processMessageAction(message); - if (currentIndex < pipeline.Count - 1) - { - pipeline[currentIndex + 1].Process(message, pipeline, currentIndex + 1); - } + _processMessageAction(message); // for request + ProcessNext(message, pipeline, currentIndex); + _processMessageAction(message); // for response } public override async ValueTask ProcessAsync(PipelineMessage message, IReadOnlyList pipeline, int currentIndex) { - _processMessageAction(message); - if (currentIndex < pipeline.Count - 1) - { - await pipeline[currentIndex + 1].ProcessAsync(message, pipeline, currentIndex + 1); - } + _processMessageAction(message); // for request + await ProcessNextAsync(message, pipeline, currentIndex); + _processMessageAction(message); // for response } } \ No newline at end of file