From d7db62368058d7a2f3e9ec3d36a1cb8c9b5ebfed Mon Sep 17 00:00:00 2001 From: Jose Arriaga Maldonado Date: Tue, 29 Jul 2025 18:24:16 -0700 Subject: [PATCH 1/4] Fix ReasoningResponseItem's Status property not generating correctly --- .../Responses/Items/ReasoningResponseItem.cs | 8 +++-- src/Custom/Responses/Items/ReasoningStatus.cs | 2 +- .../ReasoningResponseItem.Serialization.cs | 21 +++++++++-- .../Models/Responses/ReasoningResponseItem.cs | 6 ++-- .../ReasoningStatus.Serialization.cs | 36 +++++++++++++++++++ 5 files changed, 65 insertions(+), 8 deletions(-) create mode 100644 src/Generated/Models/Responses/ReasoningStatus.Serialization.cs diff --git a/src/Custom/Responses/Items/ReasoningResponseItem.cs b/src/Custom/Responses/Items/ReasoningResponseItem.cs index a84d7f0d7..6c9d12145 100644 --- a/src/Custom/Responses/Items/ReasoningResponseItem.cs +++ b/src/Custom/Responses/Items/ReasoningResponseItem.cs @@ -19,13 +19,15 @@ public partial class ReasoningResponseItem // CUSTOM: Enable reuse as an input model public ReasoningResponseItem(IEnumerable summaryParts) - : this(id: null, summaryParts) - { } + : this(id: null, status: null, summaryParts) + { + } // CUSTOM: Facilitate typical single-item summary text input model use public ReasoningResponseItem(string summaryText) : this(summaryParts: [new ReasoningSummaryTextPart(summaryText)]) - { } + { + } // CUSTOM: Provide convenience for typical single-item or text-concatenation scenario public string GetSummaryText() diff --git a/src/Custom/Responses/Items/ReasoningStatus.cs b/src/Custom/Responses/Items/ReasoningStatus.cs index 55779e49f..34059ad6a 100644 --- a/src/Custom/Responses/Items/ReasoningStatus.cs +++ b/src/Custom/Responses/Items/ReasoningStatus.cs @@ -6,7 +6,7 @@ namespace OpenAI.Responses; // - Added Experimental attribute. // - Renamed. [Experimental("OPENAI001")] -[CodeGenType("ReasoningItemStatus")] +[CodeGenType("ReasoningItemResourceStatus")] public enum ReasoningStatus { InProgress, diff --git a/src/Generated/Models/Responses/ReasoningResponseItem.Serialization.cs b/src/Generated/Models/Responses/ReasoningResponseItem.Serialization.cs index f0650cbf5..7fb174ea8 100644 --- a/src/Generated/Models/Responses/ReasoningResponseItem.Serialization.cs +++ b/src/Generated/Models/Responses/ReasoningResponseItem.Serialization.cs @@ -12,7 +12,7 @@ namespace OpenAI.Responses { public partial class ReasoningResponseItem : IJsonModel { - internal ReasoningResponseItem() : this(InternalItemType.Reasoning, null, null, null, null) + internal ReasoningResponseItem() : this(InternalItemType.Reasoning, null, null, null, default, null) { } @@ -36,6 +36,11 @@ protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWri writer.WritePropertyName("encrypted_content"u8); writer.WriteStringValue(EncryptedContent); } + if (_additionalBinaryDataProperties?.ContainsKey("status") != true) + { + writer.WritePropertyName("status"u8); + writer.WriteStringValue(Status.Value.ToSerialString()); + } if (_additionalBinaryDataProperties?.ContainsKey("summary") != true) { writer.WritePropertyName("summary"u8); @@ -71,6 +76,7 @@ internal static ReasoningResponseItem DeserializeReasoningResponseItem(JsonEleme string id = default; IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); string encryptedContent = default; + ReasoningStatus? status = default; IReadOnlyList summaryParts = default; foreach (var prop in element.EnumerateObject()) { @@ -94,6 +100,11 @@ internal static ReasoningResponseItem DeserializeReasoningResponseItem(JsonEleme encryptedContent = prop.Value.GetString(); continue; } + if (prop.NameEquals("status"u8)) + { + status = prop.Value.GetString().ToReasoningStatus(); + continue; + } if (prop.NameEquals("summary"u8)) { List array = new List(); @@ -107,7 +118,13 @@ internal static ReasoningResponseItem DeserializeReasoningResponseItem(JsonEleme // Plugin customization: remove options.Format != "W" check additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); } - return new ReasoningResponseItem(kind, id, additionalBinaryDataProperties, encryptedContent, summaryParts); + return new ReasoningResponseItem( + kind, + id, + additionalBinaryDataProperties, + encryptedContent, + status, + summaryParts); } BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); diff --git a/src/Generated/Models/Responses/ReasoningResponseItem.cs b/src/Generated/Models/Responses/ReasoningResponseItem.cs index 86f2b8f17..f62f62987 100644 --- a/src/Generated/Models/Responses/ReasoningResponseItem.cs +++ b/src/Generated/Models/Responses/ReasoningResponseItem.cs @@ -13,15 +13,17 @@ namespace OpenAI.Responses [Experimental("OPENAI001")] public partial class ReasoningResponseItem : ResponseItem { - internal ReasoningResponseItem(string id, IEnumerable summaryParts) : base(InternalItemType.Reasoning, id) + internal ReasoningResponseItem(string id, ReasoningStatus? status, IEnumerable summaryParts) : base(InternalItemType.Reasoning, id) { + Status = status; SummaryParts = summaryParts.ToList(); } - internal ReasoningResponseItem(InternalItemType kind, string id, IDictionary additionalBinaryDataProperties, string encryptedContent, IReadOnlyList summaryParts) : base(kind, id, additionalBinaryDataProperties) + internal ReasoningResponseItem(InternalItemType kind, string id, IDictionary additionalBinaryDataProperties, string encryptedContent, ReasoningStatus? status, IReadOnlyList summaryParts) : base(kind, id, additionalBinaryDataProperties) { // Plugin customization: ensure initialization of collections EncryptedContent = encryptedContent; + Status = status; SummaryParts = summaryParts ?? new ChangeTrackingList(); } diff --git a/src/Generated/Models/Responses/ReasoningStatus.Serialization.cs b/src/Generated/Models/Responses/ReasoningStatus.Serialization.cs new file mode 100644 index 000000000..199f186f9 --- /dev/null +++ b/src/Generated/Models/Responses/ReasoningStatus.Serialization.cs @@ -0,0 +1,36 @@ +// + +#nullable disable + +using System; + +namespace OpenAI.Responses +{ + internal static partial class ReasoningStatusExtensions + { + public static string ToSerialString(this ReasoningStatus value) => value switch + { + ReasoningStatus.InProgress => "in_progress", + ReasoningStatus.Completed => "completed", + ReasoningStatus.Incomplete => "incomplete", + _ => throw new ArgumentOutOfRangeException(nameof(value), value, "Unknown ReasoningStatus value.") + }; + + public static ReasoningStatus ToReasoningStatus(this string value) + { + if (StringComparer.OrdinalIgnoreCase.Equals(value, "in_progress")) + { + return ReasoningStatus.InProgress; + } + if (StringComparer.OrdinalIgnoreCase.Equals(value, "completed")) + { + return ReasoningStatus.Completed; + } + if (StringComparer.OrdinalIgnoreCase.Equals(value, "incomplete")) + { + return ReasoningStatus.Incomplete; + } + throw new ArgumentOutOfRangeException(nameof(value), value, "Unknown ReasoningStatus value."); + } + } +} From 37f2afcdbfc65ffa7a66eab5c97473afb10ca424 Mon Sep 17 00:00:00 2001 From: Jose Arriaga Maldonado Date: Tue, 29 Jul 2025 18:53:39 -0700 Subject: [PATCH 2/4] Fix serialization --- codegen/generator/src/OpenAILibraryVisitor.cs | 1 + .../Models/Responses/ReasoningResponseItem.Serialization.cs | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/codegen/generator/src/OpenAILibraryVisitor.cs b/codegen/generator/src/OpenAILibraryVisitor.cs index 07e20715f..626fa1dab 100644 --- a/codegen/generator/src/OpenAILibraryVisitor.cs +++ b/codegen/generator/src/OpenAILibraryVisitor.cs @@ -43,6 +43,7 @@ public class OpenAILibraryVisitor : ScmLibraryVisitor ["FunctionCallResponseItem"] = [_readonlyStatusReplacementInfo], ["FunctionCallOutputResponseItem"] = [_readonlyStatusReplacementInfo], ["MessageResponseItem"] = [_readonlyStatusReplacementInfo], + ["ReasoningResponseItem"] = [_readonlyStatusReplacementInfo], ["WebSearchCallResponseItem"] = [_readonlyStatusReplacementInfo], }; diff --git a/src/Generated/Models/Responses/ReasoningResponseItem.Serialization.cs b/src/Generated/Models/Responses/ReasoningResponseItem.Serialization.cs index 7fb174ea8..1bb70e1bd 100644 --- a/src/Generated/Models/Responses/ReasoningResponseItem.Serialization.cs +++ b/src/Generated/Models/Responses/ReasoningResponseItem.Serialization.cs @@ -36,7 +36,8 @@ protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWri writer.WritePropertyName("encrypted_content"u8); writer.WriteStringValue(EncryptedContent); } - if (_additionalBinaryDataProperties?.ContainsKey("status") != true) + // Plugin customization: apply Optional.Is*Defined() check based on type name dictionary lookup + if (Optional.IsDefined(Status) && _additionalBinaryDataProperties?.ContainsKey("status") != true) { writer.WritePropertyName("status"u8); writer.WriteStringValue(Status.Value.ToSerialString()); From b6e4f0a180b25e72815a91b1b65837f78c7db6af Mon Sep 17 00:00:00 2001 From: Jose Arriaga Maldonado Date: Wed, 30 Jul 2025 10:18:01 -0700 Subject: [PATCH 3/4] Sync latest and fix --- src/Custom/Responses/Items/ReasoningResponseItem.cs | 2 +- src/Custom/Responses/OpenAIResponsesModelFactory.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Custom/Responses/Items/ReasoningResponseItem.cs b/src/Custom/Responses/Items/ReasoningResponseItem.cs index 6c9d12145..f1545919b 100644 --- a/src/Custom/Responses/Items/ReasoningResponseItem.cs +++ b/src/Custom/Responses/Items/ReasoningResponseItem.cs @@ -11,7 +11,7 @@ public partial class ReasoningResponseItem { // CUSTOM: Retain optionality of OpenAPI read-only property value [CodeGenMember("Status")] - public ReasoningStatus? Status { get; internal set; } + public ReasoningStatus? Status { get; } // CUSTOM: Rename for collection clarity [CodeGenMember("Summary")] diff --git a/src/Custom/Responses/OpenAIResponsesModelFactory.cs b/src/Custom/Responses/OpenAIResponsesModelFactory.cs index 42cdbd292..e8c9b65a9 100644 --- a/src/Custom/Responses/OpenAIResponsesModelFactory.cs +++ b/src/Custom/Responses/OpenAIResponsesModelFactory.cs @@ -102,9 +102,9 @@ public static ReasoningResponseItem ReasoningResponseItem( id: id, additionalBinaryDataProperties: null, encryptedContent: encryptedContent, + status: status, summaryParts: summaryParts.ToList()); - item.Status = status; return item; } @@ -129,9 +129,9 @@ public static ReasoningResponseItem ReasoningResponseItem( id: id, additionalBinaryDataProperties: null, encryptedContent: encryptedContent, + status: status, summaryParts: summaryParts); - item.Status = status; return item; } From 198d6467bdd95cf816c4eb41282be6c9e7b40e60 Mon Sep 17 00:00:00 2001 From: Jose Arriaga Maldonado Date: Wed, 30 Jul 2025 23:51:43 -0700 Subject: [PATCH 4/4] Export API --- api/OpenAI.net8.0.cs | 6 ++++++ src/Custom/Audio/AudioClient.cs | 1 + src/Custom/Chat/ChatClient.cs | 1 + src/Custom/Embeddings/EmbeddingClient.cs | 2 ++ src/Custom/Images/ImageClient.cs | 4 +++- src/Custom/Moderations/ModerationClient.cs | 2 ++ 6 files changed, 15 insertions(+), 1 deletion(-) diff --git a/api/OpenAI.net8.0.cs b/api/OpenAI.net8.0.cs index a651ed6bc..96794f558 100644 --- a/api/OpenAI.net8.0.cs +++ b/api/OpenAI.net8.0.cs @@ -1056,6 +1056,7 @@ public class AudioClient { public AudioClient(string model, ApiKeyCredential credential, OpenAIClientOptions options); public AudioClient(string model, ApiKeyCredential credential); public AudioClient(string model, string apiKey); + [Experimental("OPENAI001")] public string Model { get; } public ClientPipeline Pipeline { get; } public virtual ClientResult GenerateSpeech(BinaryContent content, RequestOptions options = null); @@ -1404,6 +1405,7 @@ public class ChatClient { public ChatClient(string model, ApiKeyCredential credential, OpenAIClientOptions options); public ChatClient(string model, ApiKeyCredential credential); public ChatClient(string model, string apiKey); + [Experimental("OPENAI001")] public string Model { get; } public ClientPipeline Pipeline { get; } public virtual ClientResult CompleteChat(params ChatMessage[] messages); @@ -2279,6 +2281,7 @@ public class EmbeddingClient { public EmbeddingClient(string model, ApiKeyCredential credential, OpenAIClientOptions options); public EmbeddingClient(string model, ApiKeyCredential credential); public EmbeddingClient(string model, string apiKey); + [Experimental("OPENAI001")] public string Model { get; } public ClientPipeline Pipeline { get; } public virtual ClientResult GenerateEmbedding(string input, EmbeddingGenerationOptions options = null, CancellationToken cancellationToken = default); @@ -3242,6 +3245,7 @@ public class ImageClient { public ImageClient(string model, ApiKeyCredential credential, OpenAIClientOptions options); public ImageClient(string model, ApiKeyCredential credential); public ImageClient(string model, string apiKey); + [Experimental("OPENAI001")] public string Model { get; } public ClientPipeline Pipeline { get; } public virtual ClientResult GenerateImage(string prompt, ImageGenerationOptions options = null, CancellationToken cancellationToken = default); @@ -3429,6 +3433,7 @@ public class ModerationClient { public ModerationClient(string model, ApiKeyCredential credential, OpenAIClientOptions options); public ModerationClient(string model, ApiKeyCredential credential); public ModerationClient(string model, string apiKey); + [Experimental("OPENAI001")] public string Model { get; } public ClientPipeline Pipeline { get; } public virtual ClientResult ClassifyText(BinaryContent content, RequestOptions options = null); @@ -4610,6 +4615,7 @@ public class OpenAIResponseClient { public virtual CollectionResult GetResponseStreaming(string responseId, int? startingAfter = null, CancellationToken cancellationToken = default); public virtual AsyncCollectionResult GetResponseStreamingAsync(string responseId, int? startingAfter = null, CancellationToken cancellationToken = default); } + [Experimental("OPENAI001")] public static class OpenAIResponsesModelFactory { public static MessageResponseItem MessageResponseItem(string id = null, MessageRole role = MessageRole.Assistant, MessageStatus? status = null); public static OpenAIResponse OpenAIResponse(string id = null, DateTimeOffset createdAt = default, ResponseStatus? status = null, ResponseError error = null, ResponseTokenUsage usage = null, string endUserId = null, ResponseReasoningOptions reasoningOptions = null, int? maxOutputTokenCount = null, ResponseTextOptions textOptions = null, ResponseTruncationMode? truncationMode = null, ResponseIncompleteStatusDetails incompleteStatusDetails = null, IEnumerable outputItems = null, bool parallelToolCallsEnabled = false, ResponseToolChoice toolChoice = null, string model = null, IDictionary metadata = null, float? temperature = null, float? topP = null, string previousResponseId = null, bool? background = null, string instructions = null, IEnumerable tools = null); diff --git a/src/Custom/Audio/AudioClient.cs b/src/Custom/Audio/AudioClient.cs index 7563d15a8..37f48fe73 100644 --- a/src/Custom/Audio/AudioClient.cs +++ b/src/Custom/Audio/AudioClient.cs @@ -91,6 +91,7 @@ protected internal AudioClient(ClientPipeline pipeline, string model, OpenAIClie /// /// Gets the name of the model used in requests sent to the service. /// + [Experimental("OPENAI001")] public string Model => _model; #region GenerateSpeech diff --git a/src/Custom/Chat/ChatClient.cs b/src/Custom/Chat/ChatClient.cs index 0402c5973..5daf86c49 100644 --- a/src/Custom/Chat/ChatClient.cs +++ b/src/Custom/Chat/ChatClient.cs @@ -103,6 +103,7 @@ protected internal ChatClient(ClientPipeline pipeline, string model, OpenAIClien /// /// Gets the name of the model used in requests sent to the service. /// + [Experimental("OPENAI001")] public string Model => _model; /// Generates a completion for the given chat. diff --git a/src/Custom/Embeddings/EmbeddingClient.cs b/src/Custom/Embeddings/EmbeddingClient.cs index cf99c7405..82ff54919 100644 --- a/src/Custom/Embeddings/EmbeddingClient.cs +++ b/src/Custom/Embeddings/EmbeddingClient.cs @@ -2,6 +2,7 @@ using System.ClientModel; using System.ClientModel.Primitives; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Text.Json; @@ -92,6 +93,7 @@ protected internal EmbeddingClient(ClientPipeline pipeline, string model, OpenAI /// /// Gets the name of the model used in requests sent to the service. /// + [Experimental("OPENAI001")] public string Model => _model; // CUSTOM: Added to simplify generating a single embedding from a string input. diff --git a/src/Custom/Images/ImageClient.cs b/src/Custom/Images/ImageClient.cs index b18629061..e18b4ad59 100644 --- a/src/Custom/Images/ImageClient.cs +++ b/src/Custom/Images/ImageClient.cs @@ -1,6 +1,7 @@ using System; using System.ClientModel; using System.ClientModel.Primitives; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Threading; @@ -86,10 +87,11 @@ protected internal ImageClient(ClientPipeline pipeline, string model, OpenAIClie Pipeline = pipeline; _endpoint = OpenAIClient.GetEndpoint(options); } - + /// /// Gets the name of the model used in requests sent to the service. /// + [Experimental("OPENAI001")] public string Model => _model; #region GenerateImages diff --git a/src/Custom/Moderations/ModerationClient.cs b/src/Custom/Moderations/ModerationClient.cs index e450ec874..bf728ed95 100644 --- a/src/Custom/Moderations/ModerationClient.cs +++ b/src/Custom/Moderations/ModerationClient.cs @@ -2,6 +2,7 @@ using System.ClientModel; using System.ClientModel.Primitives; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Text.Json; @@ -92,6 +93,7 @@ protected internal ModerationClient(ClientPipeline pipeline, string model, OpenA /// /// Gets the name of the model used in requests sent to the service. /// + [Experimental("OPENAI001")] public string Model => _model; /// Classifies if the text input is potentially harmful across several categories.