From 87b240d27dfeaa7408240ef8a8620a1b9989ff88 Mon Sep 17 00:00:00 2001 From: ShivangiReja <45216704+ShivangiReja@users.noreply.github.com> Date: Thu, 31 Jul 2025 15:13:03 -0700 Subject: [PATCH 1/2] Add UpdateChatCompletion method to ChatClient --- api/OpenAI.net8.0.cs | 8 + api/OpenAI.netstandard2.0.cs | 4 + specification/client/chat.client.tsp | 2 + src/Custom/Chat/ChatClient.Protocol.cs | 55 ---- src/Custom/Chat/ChatClient.cs | 31 +- src/Custom/Chat/Internal/GeneratorStubs.cs | 15 +- src/Generated/ChatClient.RestClient.cs | 29 -- src/Generated/ChatClient.cs | 56 ++++ ...ChatCompletionMessageList.Serialization.cs | 195 ------------- .../Chat/InternalChatCompletionMessageList.cs | 51 ---- ...ompletionMessageListDatum.Serialization.cs | 275 ------------------ .../InternalChatCompletionMessageListDatum.cs | 59 ---- ...dateChatCompletionRequest.Serialization.cs | 150 ++++++++++ .../InternalUpdateChatCompletionRequest.cs | 36 +++ tests/Chat/ChatTests.cs | 40 +++ 15 files changed, 336 insertions(+), 670 deletions(-) delete mode 100644 src/Custom/Chat/ChatClient.Protocol.cs delete mode 100644 src/Generated/Models/Chat/InternalChatCompletionMessageList.Serialization.cs delete mode 100644 src/Generated/Models/Chat/InternalChatCompletionMessageList.cs delete mode 100644 src/Generated/Models/Chat/InternalChatCompletionMessageListDatum.Serialization.cs delete mode 100644 src/Generated/Models/Chat/InternalChatCompletionMessageListDatum.cs create mode 100644 src/Generated/Models/Chat/InternalUpdateChatCompletionRequest.Serialization.cs create mode 100644 src/Generated/Models/Chat/InternalUpdateChatCompletionRequest.cs diff --git a/api/OpenAI.net8.0.cs b/api/OpenAI.net8.0.cs index 193e7c206..5dbd4ae53 100644 --- a/api/OpenAI.net8.0.cs +++ b/api/OpenAI.net8.0.cs @@ -1458,6 +1458,14 @@ public class ChatClient { public virtual AsyncCollectionResult GetChatCompletionsAsync(ChatCompletionCollectionOptions options = null, CancellationToken cancellationToken = default); [Experimental("OPENAI001")] public virtual AsyncCollectionResult GetChatCompletionsAsync(string after, int? limit, string order, IDictionary metadata, string model, RequestOptions options); + [Experimental("OPENAI001")] + public virtual ClientResult UpdateChatCompletion(string completionId, BinaryContent content, RequestOptions options = null); + [Experimental("OPENAI001")] + public virtual ClientResult UpdateChatCompletion(string completionId, IDictionary metadata, CancellationToken cancellationToken = default); + [Experimental("OPENAI001")] + public virtual Task UpdateChatCompletionAsync(string completionId, BinaryContent content, RequestOptions options = null); + [Experimental("OPENAI001")] + public virtual Task> UpdateChatCompletionAsync(string completionId, IDictionary metadata, CancellationToken cancellationToken = default); } public class ChatCompletion : IJsonModel, IPersistableModel { [Experimental("OPENAI001")] diff --git a/api/OpenAI.netstandard2.0.cs b/api/OpenAI.netstandard2.0.cs index 1eab54bbd..8a18d5ee1 100644 --- a/api/OpenAI.netstandard2.0.cs +++ b/api/OpenAI.netstandard2.0.cs @@ -1301,6 +1301,10 @@ public class ChatClient { public virtual CollectionResult GetChatCompletions(string after, int? limit, string order, IDictionary metadata, string model, RequestOptions options); public virtual AsyncCollectionResult GetChatCompletionsAsync(ChatCompletionCollectionOptions options = null, CancellationToken cancellationToken = default); public virtual AsyncCollectionResult GetChatCompletionsAsync(string after, int? limit, string order, IDictionary metadata, string model, RequestOptions options); + public virtual ClientResult UpdateChatCompletion(string completionId, BinaryContent content, RequestOptions options = null); + public virtual ClientResult UpdateChatCompletion(string completionId, IDictionary metadata, CancellationToken cancellationToken = default); + public virtual Task UpdateChatCompletionAsync(string completionId, BinaryContent content, RequestOptions options = null); + public virtual Task> UpdateChatCompletionAsync(string completionId, IDictionary metadata, CancellationToken cancellationToken = default); } public class ChatCompletion : IJsonModel, IPersistableModel { public IReadOnlyList Annotations { get; } diff --git a/specification/client/chat.client.tsp b/specification/client/chat.client.tsp index 0613867fb..7ef7057b0 100644 --- a/specification/client/chat.client.tsp +++ b/specification/client/chat.client.tsp @@ -17,3 +17,5 @@ using Azure.ClientGenerator.Core; @@visibility(ChatCompletionStreamResponseDelta.tool_calls, Lifecycle.Read); @@clientName(Chat.createChatCompletion, "CompleteChat"); + +@@scope(Chat.getChatCompletionMessages, "!csharp"); diff --git a/src/Custom/Chat/ChatClient.Protocol.cs b/src/Custom/Chat/ChatClient.Protocol.cs deleted file mode 100644 index 30d6ab2ac..000000000 --- a/src/Custom/Chat/ChatClient.Protocol.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System.ClientModel; -using System.ClientModel.Primitives; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Threading.Tasks; - -namespace OpenAI.Chat; - -/// The service client for the OpenAI Chat Completions endpoint. -[CodeGenSuppress("GetChatCompletionMessagesAsync", typeof(string), typeof(string), typeof(int?), typeof(string), typeof(RequestOptions))] -[CodeGenSuppress("GetChatCompletionMessages", typeof(string), typeof(string), typeof(int?), typeof(string), typeof(RequestOptions))] -[CodeGenSuppress("UpdateChatCompletionAsync", typeof(string), typeof(BinaryContent), typeof(RequestOptions))] -[CodeGenSuppress("UpdateChatCompletion", typeof(string), typeof(BinaryContent), typeof(RequestOptions))] -public partial class ChatClient -{ - // CUSTOM: Added Experimental attribute. - [Experimental("OPENAI001")] - public virtual ClientResult GetChatCompletion(string completionId, RequestOptions options) - { - Argument.AssertNotNullOrEmpty(completionId, nameof(completionId)); - - using PipelineMessage message = CreateGetChatCompletionRequest(completionId, options); - return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options)); - } - - // CUSTOM: Added Experimental attribute. - [Experimental("OPENAI001")] - public virtual async Task GetChatCompletionAsync(string completionId, RequestOptions options) - { - Argument.AssertNotNullOrEmpty(completionId, nameof(completionId)); - - using PipelineMessage message = CreateGetChatCompletionRequest(completionId, options); - return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); - } - - // CUSTOM: Added Experimental attribute. - [Experimental("OPENAI001")] - public virtual ClientResult DeleteChatCompletion(string completionId, RequestOptions options) - { - Argument.AssertNotNullOrEmpty(completionId, nameof(completionId)); - - using PipelineMessage message = CreateDeleteChatCompletionRequest(completionId, options); - return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options)); - } - - // CUSTOM: Added Experimental attribute. - [Experimental("OPENAI001")] - public virtual async Task DeleteChatCompletionAsync(string completionId, RequestOptions options) - { - Argument.AssertNotNullOrEmpty(completionId, nameof(completionId)); - - using PipelineMessage message = CreateDeleteChatCompletionRequest(completionId, options); - return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); - } -} diff --git a/src/Custom/Chat/ChatClient.cs b/src/Custom/Chat/ChatClient.cs index 4ea4275b8..d488af943 100644 --- a/src/Custom/Chat/ChatClient.cs +++ b/src/Custom/Chat/ChatClient.cs @@ -1,4 +1,3 @@ -using OpenAI.Evals; using OpenAI.Telemetry; using System; using System.ClientModel; @@ -20,10 +19,6 @@ namespace OpenAI.Chat; [CodeGenSuppress("ChatClient", typeof(ClientPipeline), typeof(Uri))] [CodeGenSuppress("CompleteChat", typeof(ChatCompletionOptions), typeof(CancellationToken))] [CodeGenSuppress("CompleteChatAsync", typeof(ChatCompletionOptions), typeof(CancellationToken))] -[CodeGenSuppress("GetChatCompletionMessages", typeof(string), typeof(string), typeof(int?), typeof(OpenAI.VectorStores.VectorStoreCollectionOrder?), typeof(CancellationToken))] -[CodeGenSuppress("GetChatCompletionMessagesAsync", typeof(string), typeof(string), typeof(int?), typeof(OpenAI.VectorStores.VectorStoreCollectionOrder?), typeof(CancellationToken))] -[CodeGenSuppress("UpdateChatCompletion", typeof(string), typeof(IDictionary), typeof(CancellationToken))] -[CodeGenSuppress("UpdateChatCompletionAsync", typeof(string), typeof(IDictionary), typeof(CancellationToken))] public partial class ChatClient { private readonly string _model; @@ -309,6 +304,32 @@ public virtual ClientResult GetChatCompletion(string completionI return ClientResult.FromValue(ChatCompletion.FromClientResult(result), result.GetRawResponse()); } + // CUSTOM: + // - Call FromClientResult. + [Experimental("OPENAI001")] + public virtual ClientResult UpdateChatCompletion(string completionId, IDictionary metadata, CancellationToken cancellationToken = default) + { + Argument.AssertNotNullOrEmpty(completionId, nameof(completionId)); + Argument.AssertNotNull(metadata, nameof(metadata)); + + InternalUpdateChatCompletionRequest spreadModel = new InternalUpdateChatCompletionRequest(metadata, null); + ClientResult result = this.UpdateChatCompletion(completionId, spreadModel, cancellationToken.CanBeCanceled ? new RequestOptions { CancellationToken = cancellationToken } : null); + return ClientResult.FromValue(ChatCompletion.FromClientResult(result), result.GetRawResponse()); + } + + // CUSTOM: + // - Call FromClientResult. + [Experimental("OPENAI001")] + public virtual async Task> UpdateChatCompletionAsync(string completionId, IDictionary metadata, CancellationToken cancellationToken = default) + { + Argument.AssertNotNullOrEmpty(completionId, nameof(completionId)); + Argument.AssertNotNull(metadata, nameof(metadata)); + + InternalUpdateChatCompletionRequest spreadModel = new InternalUpdateChatCompletionRequest(metadata, null); + ClientResult result = await this.UpdateChatCompletionAsync(completionId, spreadModel, cancellationToken.CanBeCanceled ? new RequestOptions { CancellationToken = cancellationToken } : null).ConfigureAwait(false); + return ClientResult.FromValue(ChatCompletion.FromClientResult(result), result.GetRawResponse()); + } + // CUSTOM: // - Added Experimental attribute. // - Call FromClientResult. diff --git a/src/Custom/Chat/Internal/GeneratorStubs.cs b/src/Custom/Chat/Internal/GeneratorStubs.cs index 9e5acc63e..9730bd6e2 100644 --- a/src/Custom/Chat/Internal/GeneratorStubs.cs +++ b/src/Custom/Chat/Internal/GeneratorStubs.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.ClientModel; namespace OpenAI.Chat; @@ -50,6 +50,19 @@ internal partial class InternalChatCompletionRequestMessageContentPartRefusal { [CodeGenType("CreateChatCompletionRequestModel")] internal readonly partial struct InternalCreateChatCompletionRequestModel { } +[CodeGenType("UpdateChatCompletionRequest")] +internal partial class InternalUpdateChatCompletionRequest +{ + public static implicit operator BinaryContent(InternalUpdateChatCompletionRequest internalUpdateChatCompletionRequest) + { + if (internalUpdateChatCompletionRequest == null) + { + return null; + } + return BinaryContent.Create(internalUpdateChatCompletionRequest, ModelSerializationExtensions.WireOptions); + } +} + [CodeGenType("CreateChatCompletionRequestToolChoice")] internal readonly partial struct InternalCreateChatCompletionRequestToolChoice { } diff --git a/src/Generated/ChatClient.RestClient.cs b/src/Generated/ChatClient.RestClient.cs index 898dda5a3..b328d6d64 100644 --- a/src/Generated/ChatClient.RestClient.cs +++ b/src/Generated/ChatClient.RestClient.cs @@ -122,34 +122,5 @@ internal virtual PipelineMessage CreateDeleteChatCompletionRequest(string comple message.Apply(options); return message; } - - internal virtual PipelineMessage CreateGetChatCompletionMessagesRequest(string completionId, string after, int? limit, string order, RequestOptions options) - { - PipelineMessage message = Pipeline.CreateMessage(); - message.ResponseClassifier = PipelineMessageClassifier200; - PipelineRequest request = message.Request; - request.Method = "GET"; - ClientUriBuilder uri = new ClientUriBuilder(); - uri.Reset(_endpoint); - uri.AppendPath("/chat/completions/", false); - uri.AppendPath(completionId, true); - uri.AppendPath("/messages", false); - if (after != null) - { - uri.AppendQuery("after", after, true); - } - if (limit != null) - { - uri.AppendQuery("limit", TypeFormatters.ConvertToString(limit, null), true); - } - if (order != null) - { - uri.AppendQuery("order", order, true); - } - request.Uri = uri.ToUri(); - request.Headers.Set("Accept", "application/json"); - message.Apply(options); - return message; - } } } diff --git a/src/Generated/ChatClient.cs b/src/Generated/ChatClient.cs index 7dcf1b723..b4b0e4db4 100644 --- a/src/Generated/ChatClient.cs +++ b/src/Generated/ChatClient.cs @@ -90,5 +90,61 @@ public virtual async Task CompleteChatAsync(BinaryContent content, using PipelineMessage message = CreateCompleteChatRequest(content, options); return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); } + + [Experimental("OPENAI001")] + public virtual ClientResult GetChatCompletion(string completionId, RequestOptions options) + { + Argument.AssertNotNullOrEmpty(completionId, nameof(completionId)); + + using PipelineMessage message = CreateGetChatCompletionRequest(completionId, options); + return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options)); + } + + [Experimental("OPENAI001")] + public virtual async Task GetChatCompletionAsync(string completionId, RequestOptions options) + { + Argument.AssertNotNullOrEmpty(completionId, nameof(completionId)); + + using PipelineMessage message = CreateGetChatCompletionRequest(completionId, options); + return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); + } + + [Experimental("OPENAI001")] + public virtual ClientResult UpdateChatCompletion(string completionId, BinaryContent content, RequestOptions options = null) + { + Argument.AssertNotNullOrEmpty(completionId, nameof(completionId)); + Argument.AssertNotNull(content, nameof(content)); + + using PipelineMessage message = CreateUpdateChatCompletionRequest(completionId, content, options); + return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options)); + } + + [Experimental("OPENAI001")] + public virtual async Task UpdateChatCompletionAsync(string completionId, BinaryContent content, RequestOptions options = null) + { + Argument.AssertNotNullOrEmpty(completionId, nameof(completionId)); + Argument.AssertNotNull(content, nameof(content)); + + using PipelineMessage message = CreateUpdateChatCompletionRequest(completionId, content, options); + return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); + } + + [Experimental("OPENAI001")] + public virtual ClientResult DeleteChatCompletion(string completionId, RequestOptions options) + { + Argument.AssertNotNullOrEmpty(completionId, nameof(completionId)); + + using PipelineMessage message = CreateDeleteChatCompletionRequest(completionId, options); + return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options)); + } + + [Experimental("OPENAI001")] + public virtual async Task DeleteChatCompletionAsync(string completionId, RequestOptions options) + { + Argument.AssertNotNullOrEmpty(completionId, nameof(completionId)); + + using PipelineMessage message = CreateDeleteChatCompletionRequest(completionId, options); + return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); + } } } diff --git a/src/Generated/Models/Chat/InternalChatCompletionMessageList.Serialization.cs b/src/Generated/Models/Chat/InternalChatCompletionMessageList.Serialization.cs deleted file mode 100644 index 4318e9032..000000000 --- a/src/Generated/Models/Chat/InternalChatCompletionMessageList.Serialization.cs +++ /dev/null @@ -1,195 +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 InternalChatCompletionMessageList : IJsonModel - { - internal InternalChatCompletionMessageList() : this(null, null, null, null, default, null) - { - } - - 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(InternalChatCompletionMessageList)} does not support writing '{format}' format."); - } - if (_additionalBinaryDataProperties?.ContainsKey("object") != true) - { - writer.WritePropertyName("object"u8); - writer.WriteStringValue(Object); - } - if (_additionalBinaryDataProperties?.ContainsKey("data") != true) - { - writer.WritePropertyName("data"u8); - writer.WriteStartArray(); - foreach (InternalChatCompletionMessageListDatum item in Data) - { - writer.WriteObjectValue(item, options); - } - writer.WriteEndArray(); - } - 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); - } - // Plugin customization: remove options.Format != "W" check - if (_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 - } - } - } - - InternalChatCompletionMessageList IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); - - protected virtual InternalChatCompletionMessageList 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(InternalChatCompletionMessageList)} does not support reading '{format}' format."); - } - using JsonDocument document = JsonDocument.ParseValue(ref reader); - return DeserializeInternalChatCompletionMessageList(document.RootElement, options); - } - - internal static InternalChatCompletionMessageList DeserializeInternalChatCompletionMessageList(JsonElement element, ModelReaderWriterOptions options) - { - if (element.ValueKind == JsonValueKind.Null) - { - return null; - } - string @object = default; - IList data = default; - string firstId = default; - string lastId = default; - bool hasMore = default; - IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); - foreach (var prop in element.EnumerateObject()) - { - if (prop.NameEquals("object"u8)) - { - @object = prop.Value.GetString(); - continue; - } - if (prop.NameEquals("data"u8)) - { - List array = new List(); - foreach (var item in prop.Value.EnumerateArray()) - { - array.Add(InternalChatCompletionMessageListDatum.DeserializeInternalChatCompletionMessageListDatum(item, options)); - } - data = array; - continue; - } - if (prop.NameEquals("first_id"u8)) - { - firstId = prop.Value.GetString(); - continue; - } - if (prop.NameEquals("last_id"u8)) - { - lastId = prop.Value.GetString(); - continue; - } - if (prop.NameEquals("has_more"u8)) - { - hasMore = prop.Value.GetBoolean(); - continue; - } - // Plugin customization: remove options.Format != "W" check - additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); - } - return new InternalChatCompletionMessageList( - @object, - data, - firstId, - lastId, - hasMore, - 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, OpenAIContext.Default); - default: - throw new FormatException($"The model {nameof(InternalChatCompletionMessageList)} does not support writing '{options.Format}' format."); - } - } - - InternalChatCompletionMessageList IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); - - protected virtual InternalChatCompletionMessageList 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 DeserializeInternalChatCompletionMessageList(document.RootElement, options); - } - default: - throw new FormatException($"The model {nameof(InternalChatCompletionMessageList)} does not support reading '{options.Format}' format."); - } - } - - string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; - - public static explicit operator InternalChatCompletionMessageList(ClientResult result) - { - using PipelineResponse response = result.GetRawResponse(); - using JsonDocument document = JsonDocument.Parse(response.Content); - return DeserializeInternalChatCompletionMessageList(document.RootElement, ModelSerializationExtensions.WireOptions); - } - } -} diff --git a/src/Generated/Models/Chat/InternalChatCompletionMessageList.cs b/src/Generated/Models/Chat/InternalChatCompletionMessageList.cs deleted file mode 100644 index 9f836c305..000000000 --- a/src/Generated/Models/Chat/InternalChatCompletionMessageList.cs +++ /dev/null @@ -1,51 +0,0 @@ -// - -#nullable disable - -using System; -using System.Collections.Generic; -using System.Linq; -using OpenAI; - -namespace OpenAI.Chat -{ - internal partial class InternalChatCompletionMessageList - { - private protected IDictionary _additionalBinaryDataProperties; - - internal InternalChatCompletionMessageList(IEnumerable data, string firstId, string lastId, bool hasMore) - { - Data = data.ToList(); - FirstId = firstId; - LastId = lastId; - HasMore = hasMore; - } - - internal InternalChatCompletionMessageList(string @object, IList data, string firstId, string lastId, bool hasMore, IDictionary additionalBinaryDataProperties) - { - // Plugin customization: ensure initialization of collections - Object = @object; - Data = data ?? new ChangeTrackingList(); - FirstId = firstId; - LastId = lastId; - HasMore = hasMore; - _additionalBinaryDataProperties = additionalBinaryDataProperties; - } - - public string Object { get; } = "list"; - - internal IList Data { get; } - - public string FirstId { get; } - - public string LastId { get; } - - public bool HasMore { get; } - - internal IDictionary SerializedAdditionalRawData - { - get => _additionalBinaryDataProperties; - set => _additionalBinaryDataProperties = value; - } - } -} diff --git a/src/Generated/Models/Chat/InternalChatCompletionMessageListDatum.Serialization.cs b/src/Generated/Models/Chat/InternalChatCompletionMessageListDatum.Serialization.cs deleted file mode 100644 index 3290fffd8..000000000 --- a/src/Generated/Models/Chat/InternalChatCompletionMessageListDatum.Serialization.cs +++ /dev/null @@ -1,275 +0,0 @@ -// - -#nullable disable - -using System; -using System.ClientModel.Primitives; -using System.Collections.Generic; -using System.Text.Json; -using OpenAI; - -namespace OpenAI.Chat -{ - internal partial class InternalChatCompletionMessageListDatum : IJsonModel - { - internal InternalChatCompletionMessageListDatum() : this(null, null, null, null, null, null, null, default, null) - { - } - - 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(InternalChatCompletionMessageListDatum)} does not support writing '{format}' format."); - } - if (_additionalBinaryDataProperties?.ContainsKey("content") != true) - { - if (Optional.IsDefined(Content)) - { - writer.WritePropertyName("content"u8); - writer.WriteStringValue(Content); - } - else - { - writer.WriteNull("content"u8); - } - } - if (_additionalBinaryDataProperties?.ContainsKey("refusal") != true) - { - if (Optional.IsDefined(Refusal)) - { - writer.WritePropertyName("refusal"u8); - writer.WriteStringValue(Refusal); - } - else - { - writer.WriteNull("refusal"u8); - } - } - // Plugin customization: remove options.Format != "W" check - if (Optional.IsCollectionDefined(ToolCalls) && _additionalBinaryDataProperties?.ContainsKey("tool_calls") != true) - { - writer.WritePropertyName("tool_calls"u8); - writer.WriteStartArray(); - foreach (ChatToolCall item in ToolCalls) - { - writer.WriteObjectValue(item, options); - } - writer.WriteEndArray(); - } - if (Optional.IsCollectionDefined(Annotations) && _additionalBinaryDataProperties?.ContainsKey("annotations") != true) - { - writer.WritePropertyName("annotations"u8); - writer.WriteStartArray(); - foreach (ChatMessageAnnotation item in Annotations) - { - writer.WriteObjectValue(item, options); - } - writer.WriteEndArray(); - } - if (Optional.IsDefined(FunctionCall) && _additionalBinaryDataProperties?.ContainsKey("function_call") != true) - { - writer.WritePropertyName("function_call"u8); - writer.WriteObjectValue(FunctionCall, options); - } - if (Optional.IsDefined(Audio) && _additionalBinaryDataProperties?.ContainsKey("audio") != true) - { - writer.WritePropertyName("audio"u8); - writer.WriteObjectValue(Audio, options); - } - if (_additionalBinaryDataProperties?.ContainsKey("id") != true) - { - writer.WritePropertyName("id"u8); - writer.WriteStringValue(Id); - } - if (_additionalBinaryDataProperties?.ContainsKey("role") != true) - { - writer.WritePropertyName("role"u8); - writer.WriteStringValue(Role.ToSerialString()); - } - // Plugin customization: remove options.Format != "W" check - if (_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 - } - } - } - - InternalChatCompletionMessageListDatum IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); - - protected virtual InternalChatCompletionMessageListDatum 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(InternalChatCompletionMessageListDatum)} does not support reading '{format}' format."); - } - using JsonDocument document = JsonDocument.ParseValue(ref reader); - return DeserializeInternalChatCompletionMessageListDatum(document.RootElement, options); - } - - internal static InternalChatCompletionMessageListDatum DeserializeInternalChatCompletionMessageListDatum(JsonElement element, ModelReaderWriterOptions options) - { - if (element.ValueKind == JsonValueKind.Null) - { - return null; - } - string content = default; - string refusal = default; - IReadOnlyList toolCalls = default; - IList annotations = default; - InternalChatCompletionResponseMessageFunctionCall functionCall = default; - ChatOutputAudio audio = default; - string id = default; - ChatMessageRole role = default; - IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); - foreach (var prop in element.EnumerateObject()) - { - if (prop.NameEquals("content"u8)) - { - if (prop.Value.ValueKind == JsonValueKind.Null) - { - content = null; - continue; - } - content = prop.Value.GetString(); - continue; - } - if (prop.NameEquals("refusal"u8)) - { - if (prop.Value.ValueKind == JsonValueKind.Null) - { - refusal = null; - continue; - } - refusal = prop.Value.GetString(); - continue; - } - if (prop.NameEquals("tool_calls"u8)) - { - if (prop.Value.ValueKind == JsonValueKind.Null) - { - continue; - } - List array = new List(); - foreach (var item in prop.Value.EnumerateArray()) - { - array.Add(ChatToolCall.DeserializeChatToolCall(item, options)); - } - toolCalls = array; - continue; - } - if (prop.NameEquals("annotations"u8)) - { - if (prop.Value.ValueKind == JsonValueKind.Null) - { - continue; - } - List array = new List(); - foreach (var item in prop.Value.EnumerateArray()) - { - array.Add(ChatMessageAnnotation.DeserializeChatMessageAnnotation(item, options)); - } - annotations = array; - continue; - } - if (prop.NameEquals("function_call"u8)) - { - if (prop.Value.ValueKind == JsonValueKind.Null) - { - continue; - } - functionCall = InternalChatCompletionResponseMessageFunctionCall.DeserializeInternalChatCompletionResponseMessageFunctionCall(prop.Value, options); - 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("id"u8)) - { - id = prop.Value.GetString(); - continue; - } - if (prop.NameEquals("role"u8)) - { - role = prop.Value.GetString().ToChatMessageRole(); - continue; - } - // Plugin customization: remove options.Format != "W" check - additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); - } - return new InternalChatCompletionMessageListDatum( - content, - refusal, - toolCalls ?? new ChangeTrackingList(), - annotations ?? new ChangeTrackingList(), - functionCall, - audio, - id, - role, - 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, OpenAIContext.Default); - default: - throw new FormatException($"The model {nameof(InternalChatCompletionMessageListDatum)} does not support writing '{options.Format}' format."); - } - } - - InternalChatCompletionMessageListDatum IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); - - protected virtual InternalChatCompletionMessageListDatum 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 DeserializeInternalChatCompletionMessageListDatum(document.RootElement, options); - } - default: - throw new FormatException($"The model {nameof(InternalChatCompletionMessageListDatum)} does not support reading '{options.Format}' format."); - } - } - - string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; - } -} diff --git a/src/Generated/Models/Chat/InternalChatCompletionMessageListDatum.cs b/src/Generated/Models/Chat/InternalChatCompletionMessageListDatum.cs deleted file mode 100644 index ccf4e8d15..000000000 --- a/src/Generated/Models/Chat/InternalChatCompletionMessageListDatum.cs +++ /dev/null @@ -1,59 +0,0 @@ -// - -#nullable disable - -using System; -using System.Collections.Generic; -using OpenAI; - -namespace OpenAI.Chat -{ - internal partial class InternalChatCompletionMessageListDatum - { - private protected IDictionary _additionalBinaryDataProperties; - - internal InternalChatCompletionMessageListDatum(string content, string refusal, string id, ChatMessageRole role) - { - Content = content; - Refusal = refusal; - ToolCalls = new ChangeTrackingList(); - Annotations = new ChangeTrackingList(); - Id = id; - Role = role; - } - - internal InternalChatCompletionMessageListDatum(string content, string refusal, IReadOnlyList toolCalls, IList annotations, InternalChatCompletionResponseMessageFunctionCall functionCall, ChatOutputAudio audio, string id, ChatMessageRole role, IDictionary additionalBinaryDataProperties) - { - // Plugin customization: ensure initialization of collections - Content = content; - Refusal = refusal; - ToolCalls = toolCalls ?? new ChangeTrackingList(); - Annotations = annotations ?? new ChangeTrackingList(); - FunctionCall = functionCall; - Audio = audio; - Id = id; - Role = role; - _additionalBinaryDataProperties = additionalBinaryDataProperties; - } - - public string Content { get; } - - public string Refusal { get; } - - public IReadOnlyList ToolCalls { get; } - - public IList Annotations { get; } - - internal InternalChatCompletionResponseMessageFunctionCall FunctionCall { get; } - - public ChatOutputAudio Audio { get; } - - public string Id { get; } - - internal IDictionary SerializedAdditionalRawData - { - get => _additionalBinaryDataProperties; - set => _additionalBinaryDataProperties = value; - } - } -} diff --git a/src/Generated/Models/Chat/InternalUpdateChatCompletionRequest.Serialization.cs b/src/Generated/Models/Chat/InternalUpdateChatCompletionRequest.Serialization.cs new file mode 100644 index 000000000..edfbf01a9 --- /dev/null +++ b/src/Generated/Models/Chat/InternalUpdateChatCompletionRequest.Serialization.cs @@ -0,0 +1,150 @@ +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; +using OpenAI; + +namespace OpenAI.Chat +{ + internal partial class InternalUpdateChatCompletionRequest : IJsonModel + { + internal InternalUpdateChatCompletionRequest() : this(null, null) + { + } + + 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(InternalUpdateChatCompletionRequest)} does not support writing '{format}' format."); + } + if (_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(); + } + // Plugin customization: remove options.Format != "W" check + if (_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 + } + } + } + + InternalUpdateChatCompletionRequest IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + protected virtual InternalUpdateChatCompletionRequest 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(InternalUpdateChatCompletionRequest)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeInternalUpdateChatCompletionRequest(document.RootElement, options); + } + + internal static InternalUpdateChatCompletionRequest DeserializeInternalUpdateChatCompletionRequest(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + IDictionary metadata = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("metadata"u8)) + { + 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; + } + // Plugin customization: remove options.Format != "W" check + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + return new InternalUpdateChatCompletionRequest(metadata, 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, OpenAIContext.Default); + default: + throw new FormatException($"The model {nameof(InternalUpdateChatCompletionRequest)} does not support writing '{options.Format}' format."); + } + } + + InternalUpdateChatCompletionRequest IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + protected virtual InternalUpdateChatCompletionRequest 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 DeserializeInternalUpdateChatCompletionRequest(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(InternalUpdateChatCompletionRequest)} does not support reading '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/src/Generated/Models/Chat/InternalUpdateChatCompletionRequest.cs b/src/Generated/Models/Chat/InternalUpdateChatCompletionRequest.cs new file mode 100644 index 000000000..120890eb5 --- /dev/null +++ b/src/Generated/Models/Chat/InternalUpdateChatCompletionRequest.cs @@ -0,0 +1,36 @@ +// + +#nullable disable + +using System; +using System.Collections.Generic; +using OpenAI; + +namespace OpenAI.Chat +{ + internal partial class InternalUpdateChatCompletionRequest + { + private protected IDictionary _additionalBinaryDataProperties; + + internal InternalUpdateChatCompletionRequest(IDictionary metadata) + { + // Plugin customization: ensure initialization of collections + Metadata = metadata ?? new ChangeTrackingDictionary(); + } + + internal InternalUpdateChatCompletionRequest(IDictionary metadata, IDictionary additionalBinaryDataProperties) + { + // Plugin customization: ensure initialization of collections + Metadata = metadata ?? new ChangeTrackingDictionary(); + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + public IDictionary Metadata { get; } + + internal IDictionary SerializedAdditionalRawData + { + get => _additionalBinaryDataProperties; + set => _additionalBinaryDataProperties = value; + } + } +} diff --git a/tests/Chat/ChatTests.cs b/tests/Chat/ChatTests.cs index 6b63c4fea..cf286eb64 100644 --- a/tests/Chat/ChatTests.cs +++ b/tests/Chat/ChatTests.cs @@ -1541,6 +1541,46 @@ [new UserChatMessage("Say `this is a test`.")], }); } + [Test] + public async Task UpdateChatCompletionWorks() + { + ChatClient client = GetTestClient(); + + var testMetadataKey = $"test_key_{Guid.NewGuid():N}"; + var initialOptions = new ChatCompletionOptions + { + StoredOutputEnabled = true, + Metadata = { [testMetadataKey] = "initial_value" } + }; + + ChatCompletion chatCompletion = await client.CompleteChatAsync( + [new UserChatMessage("Say `this is a test`.")], + initialOptions); + + await Task.Delay(5000); + + var newMetadata = new Dictionary + { + [testMetadataKey] = "updated_value", + ["updated_by"] = "unit_test" + }; + + ChatCompletion updated = await client.UpdateChatCompletionAsync(chatCompletion.Id, newMetadata); + + Assert.That(updated, Is.Not.Null); + Assert.That(updated.Id, Is.EqualTo(chatCompletion.Id)); + + ChatCompletionDeletionResult deletionResult = await client.DeleteChatCompletionAsync(chatCompletion.Id); + Assert.That(deletionResult.Deleted, Is.True); + + await Task.Delay(5000); + + Assert.ThrowsAsync(async () => + { + _ = await client.GetChatCompletionAsync(chatCompletion.Id); + }); + } + private List FileIdsToDelete = []; private void Validate(T item) { From 9698f1cc26d29f0b3a86afa8867f3c749f1312e0 Mon Sep 17 00:00:00 2001 From: ShivangiReja <45216704+ShivangiReja@users.noreply.github.com> Date: Thu, 31 Jul 2025 17:10:33 -0700 Subject: [PATCH 2/2] Fix generation --- api/OpenAI.net8.0.cs | 21 ++++- api/OpenAI.netstandard2.0.cs | 20 ++++- src/Generated/ChatClient.cs | 45 +++++++---- ...CompletionMessagesAsyncCollectionResult.cs | 68 ++++++++++++++++ ...pletionMessagesAsyncCollectionResultOfT.cs | 78 +++++++++++++++++++ ...tChatCompletionMessagesCollectionResult.cs | 68 ++++++++++++++++ ...atCompletionMessagesCollectionResultOfT.cs | 73 +++++++++++++++++ 7 files changed, 354 insertions(+), 19 deletions(-) create mode 100644 src/Generated/ChatClientGetChatCompletionMessagesAsyncCollectionResult.cs create mode 100644 src/Generated/ChatClientGetChatCompletionMessagesAsyncCollectionResultOfT.cs create mode 100644 src/Generated/ChatClientGetChatCompletionMessagesCollectionResult.cs create mode 100644 src/Generated/ChatClientGetChatCompletionMessagesCollectionResultOfT.cs diff --git a/api/OpenAI.net8.0.cs b/api/OpenAI.net8.0.cs index 9089112d0..d9e42a0b3 100644 --- a/api/OpenAI.net8.0.cs +++ b/api/OpenAI.net8.0.cs @@ -1542,7 +1542,7 @@ public class ChatCompletionDeletionResult : IJsonModel, IPersistableModel { public string AfterId { get; set; } - public ChatCompletionCollectionOrder? Order { get; set; } + public ChatCompletionMessageCollectionOrder? Order { get; set; } public int? PageSizeLimit { get; set; } protected virtual ChatCompletionMessageCollectionOptions JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options); protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options); @@ -1550,11 +1550,26 @@ public class ChatCompletionMessageCollectionOptions : IJsonModel { + public ChatCompletionMessageCollectionOrder(string value); + public static ChatCompletionMessageCollectionOrder Ascending { get; } + public static ChatCompletionMessageCollectionOrder Descending { get; } + public readonly bool Equals(ChatCompletionMessageCollectionOrder other); + [EditorBrowsable(EditorBrowsableState.Never)] + public override readonly bool Equals(object obj); + [EditorBrowsable(EditorBrowsableState.Never)] + public override readonly int GetHashCode(); + public static bool operator ==(ChatCompletionMessageCollectionOrder left, ChatCompletionMessageCollectionOrder right); + public static implicit operator ChatCompletionMessageCollectionOrder(string value); + public static bool operator !=(ChatCompletionMessageCollectionOrder left, ChatCompletionMessageCollectionOrder right); + public override readonly string ToString(); + } + [Experimental("OPENAI001")] public class ChatCompletionMessageListDatum : IJsonModel, IPersistableModel { - public IList Annotations { get; } - public ChatOutputAudio Audio { get; } + public IReadOnlyList Annotations { get; } public string Content { get; } public string Id { get; } + public ChatOutputAudio OutputAudio { get; } public string Refusal { get; } public IReadOnlyList ToolCalls { get; } protected virtual ChatCompletionMessageListDatum JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options); diff --git a/api/OpenAI.netstandard2.0.cs b/api/OpenAI.netstandard2.0.cs index af44295ef..2306f43be 100644 --- a/api/OpenAI.netstandard2.0.cs +++ b/api/OpenAI.netstandard2.0.cs @@ -1367,18 +1367,32 @@ public class ChatCompletionDeletionResult : IJsonModel, IPersistableModel { public string AfterId { get; set; } - public ChatCompletionCollectionOrder? Order { get; set; } + public ChatCompletionMessageCollectionOrder? Order { get; set; } public int? PageSizeLimit { get; set; } protected virtual ChatCompletionMessageCollectionOptions JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options); protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options); protected virtual ChatCompletionMessageCollectionOptions PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options); protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options); } + public readonly partial struct ChatCompletionMessageCollectionOrder : IEquatable { + public ChatCompletionMessageCollectionOrder(string value); + public static ChatCompletionMessageCollectionOrder Ascending { get; } + public static ChatCompletionMessageCollectionOrder Descending { get; } + public readonly bool Equals(ChatCompletionMessageCollectionOrder other); + [EditorBrowsable(EditorBrowsableState.Never)] + public override readonly bool Equals(object obj); + [EditorBrowsable(EditorBrowsableState.Never)] + public override readonly int GetHashCode(); + public static bool operator ==(ChatCompletionMessageCollectionOrder left, ChatCompletionMessageCollectionOrder right); + public static implicit operator ChatCompletionMessageCollectionOrder(string value); + public static bool operator !=(ChatCompletionMessageCollectionOrder left, ChatCompletionMessageCollectionOrder right); + public override readonly string ToString(); + } public class ChatCompletionMessageListDatum : IJsonModel, IPersistableModel { - public IList Annotations { get; } - public ChatOutputAudio Audio { get; } + public IReadOnlyList Annotations { get; } public string Content { get; } public string Id { get; } + public ChatOutputAudio OutputAudio { get; } public string Refusal { get; } public IReadOnlyList ToolCalls { get; } protected virtual ChatCompletionMessageListDatum JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options); diff --git a/src/Generated/ChatClient.cs b/src/Generated/ChatClient.cs index b108247d5..dbd262bee 100644 --- a/src/Generated/ChatClient.cs +++ b/src/Generated/ChatClient.cs @@ -10,7 +10,6 @@ using System.Threading; using System.Threading.Tasks; using OpenAI; -using OpenAI.VectorStores; namespace OpenAI.Chat { @@ -149,39 +148,59 @@ public virtual async Task DeleteChatCompletionAsync(string complet } [Experimental("OPENAI001")] - public virtual ClientResult GetChatCompletionMessages(string completionId, string after, int? limit, string order, RequestOptions options) + public virtual CollectionResult GetChatCompletionMessages(string completionId, string after, int? limit, string order, RequestOptions options) { Argument.AssertNotNullOrEmpty(completionId, nameof(completionId)); - using PipelineMessage message = CreateGetChatCompletionMessagesRequest(completionId, after, limit, order, options); - return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options)); + return new ChatClientGetChatCompletionMessagesCollectionResult( + this, + completionId, + after, + limit, + order, + options); } [Experimental("OPENAI001")] - public virtual async Task GetChatCompletionMessagesAsync(string completionId, string after, int? limit, string order, RequestOptions options) + public virtual AsyncCollectionResult GetChatCompletionMessagesAsync(string completionId, string after, int? limit, string order, RequestOptions options) { Argument.AssertNotNullOrEmpty(completionId, nameof(completionId)); - using PipelineMessage message = CreateGetChatCompletionMessagesRequest(completionId, after, limit, order, options); - return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); + return new ChatClientGetChatCompletionMessagesAsyncCollectionResult( + this, + completionId, + after, + limit, + order, + options); } [Experimental("OPENAI001")] - public virtual ClientResult GetChatCompletionMessages(string completionId, string after = default, int? limit = default, VectorStoreCollectionOrder? order = default, CancellationToken cancellationToken = default) + public virtual CollectionResult GetChatCompletionMessages(string completionId, ChatCompletionCollectionOptions options = default, CancellationToken cancellationToken = default) { Argument.AssertNotNullOrEmpty(completionId, nameof(completionId)); - ClientResult result = GetChatCompletionMessages(completionId, after, limit, order?.ToString(), cancellationToken.CanBeCanceled ? new RequestOptions { CancellationToken = cancellationToken } : null); - return ClientResult.FromValue((InternalChatCompletionMessageList)result, result.GetRawResponse()); + return new ChatClientGetChatCompletionMessagesCollectionResultOfT( + this, + completionId, + options?.AfterId, + options?.PageSizeLimit, + options?.Order?.ToString(), + cancellationToken.CanBeCanceled ? new RequestOptions { CancellationToken = cancellationToken } : null); } [Experimental("OPENAI001")] - public virtual async Task> GetChatCompletionMessagesAsync(string completionId, string after = default, int? limit = default, VectorStoreCollectionOrder? order = default, CancellationToken cancellationToken = default) + public virtual AsyncCollectionResult GetChatCompletionMessagesAsync(string completionId, ChatCompletionMessageCollectionOptions options = default, CancellationToken cancellationToken = default) { Argument.AssertNotNullOrEmpty(completionId, nameof(completionId)); - ClientResult result = await GetChatCompletionMessagesAsync(completionId, after, limit, order?.ToString(), cancellationToken.CanBeCanceled ? new RequestOptions { CancellationToken = cancellationToken } : null).ConfigureAwait(false); - return ClientResult.FromValue((InternalChatCompletionMessageList)result, result.GetRawResponse()); + return new ChatClientGetChatCompletionMessagesAsyncCollectionResultOfT( + this, + completionId, + options?.AfterId, + options?.PageSizeLimit, + options?.Order?.ToString(), + cancellationToken.CanBeCanceled ? new RequestOptions { CancellationToken = cancellationToken } : null); } } } diff --git a/src/Generated/ChatClientGetChatCompletionMessagesAsyncCollectionResult.cs b/src/Generated/ChatClientGetChatCompletionMessagesAsyncCollectionResult.cs new file mode 100644 index 000000000..a0e6fcc6b --- /dev/null +++ b/src/Generated/ChatClientGetChatCompletionMessagesAsyncCollectionResult.cs @@ -0,0 +1,68 @@ +// + +#nullable disable + +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using OpenAI; + +namespace OpenAI.Chat +{ + internal partial class ChatClientGetChatCompletionMessagesAsyncCollectionResult : AsyncCollectionResult + { + private readonly ChatClient _client; + private readonly string _completionId; + private readonly string _after; + private readonly int? _limit; + private readonly string _order; + private readonly RequestOptions _options; + + public ChatClientGetChatCompletionMessagesAsyncCollectionResult(ChatClient client, string completionId, string after, int? limit, string order, RequestOptions options) + { + Argument.AssertNotNullOrEmpty(completionId, nameof(completionId)); + + _client = client; + _completionId = completionId; + _after = after; + _limit = limit; + _order = order; + _options = options; + } + + public override async IAsyncEnumerable GetRawPagesAsync() + { + PipelineMessage message = _client.CreateGetChatCompletionMessagesRequest(_completionId, _after, _limit, _order, _options); + string nextToken = null; + while (true) + { + ClientResult result = ClientResult.FromResponse(await _client.Pipeline.ProcessMessageAsync(message, _options).ConfigureAwait(false)); + yield return result; + + // Plugin customization: add hasMore assignment + bool hasMore = ((InternalChatCompletionMessageList)result).HasMore; + nextToken = ((InternalChatCompletionMessageList)result).LastId; + // Plugin customization: add hasMore == false check to pagination condition + if (nextToken == null || !hasMore) + { + yield break; + } + message = _client.CreateGetChatCompletionMessagesRequest(_completionId, nextToken, _limit, _order, _options); + } + } + + public override ContinuationToken GetContinuationToken(ClientResult page) + { + string nextPage = ((InternalChatCompletionMessageList)page).LastId; + if (nextPage != null) + { + return ContinuationToken.FromBytes(BinaryData.FromString(nextPage)); + } + else + { + return null; + } + } + } +} diff --git a/src/Generated/ChatClientGetChatCompletionMessagesAsyncCollectionResultOfT.cs b/src/Generated/ChatClientGetChatCompletionMessagesAsyncCollectionResultOfT.cs new file mode 100644 index 000000000..c52b4bbe2 --- /dev/null +++ b/src/Generated/ChatClientGetChatCompletionMessagesAsyncCollectionResultOfT.cs @@ -0,0 +1,78 @@ +// + +#nullable disable + +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Threading.Tasks; +using OpenAI; + +namespace OpenAI.Chat +{ + internal partial class ChatClientGetChatCompletionMessagesAsyncCollectionResultOfT : AsyncCollectionResult + { + private readonly ChatClient _client; + private readonly string _completionId; + private readonly string _after; + private readonly int? _limit; + private readonly string _order; + private readonly RequestOptions _options; + + public ChatClientGetChatCompletionMessagesAsyncCollectionResultOfT(ChatClient client, string completionId, string after, int? limit, string order, RequestOptions options) + { + Argument.AssertNotNullOrEmpty(completionId, nameof(completionId)); + + _client = client; + _completionId = completionId; + _after = after; + _limit = limit; + _order = order; + _options = options; + } + + public override async IAsyncEnumerable GetRawPagesAsync() + { + PipelineMessage message = _client.CreateGetChatCompletionMessagesRequest(_completionId, _after, _limit, _order, _options); + string nextToken = null; + while (true) + { + ClientResult result = ClientResult.FromResponse(await _client.Pipeline.ProcessMessageAsync(message, _options).ConfigureAwait(false)); + yield return result; + + // Plugin customization: add hasMore assignment + bool hasMore = ((InternalChatCompletionMessageList)result).HasMore; + nextToken = ((InternalChatCompletionMessageList)result).LastId; + // Plugin customization: add hasMore == false check to pagination condition + if (nextToken == null || !hasMore) + { + yield break; + } + message = _client.CreateGetChatCompletionMessagesRequest(_completionId, nextToken, _limit, _order, _options); + } + } + + public override ContinuationToken GetContinuationToken(ClientResult page) + { + string nextPage = ((InternalChatCompletionMessageList)page).LastId; + if (nextPage != null) + { + return ContinuationToken.FromBytes(BinaryData.FromString(nextPage)); + } + else + { + return null; + } + } + + protected override async IAsyncEnumerable GetValuesFromPageAsync(ClientResult page) + { + foreach (ChatCompletionMessageListDatum item in ((InternalChatCompletionMessageList)page).Data) + { + yield return item; + await Task.Yield(); + } + } + } +} diff --git a/src/Generated/ChatClientGetChatCompletionMessagesCollectionResult.cs b/src/Generated/ChatClientGetChatCompletionMessagesCollectionResult.cs new file mode 100644 index 000000000..a692fa336 --- /dev/null +++ b/src/Generated/ChatClientGetChatCompletionMessagesCollectionResult.cs @@ -0,0 +1,68 @@ +// + +#nullable disable + +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using OpenAI; + +namespace OpenAI.Chat +{ + internal partial class ChatClientGetChatCompletionMessagesCollectionResult : CollectionResult + { + private readonly ChatClient _client; + private readonly string _completionId; + private readonly string _after; + private readonly int? _limit; + private readonly string _order; + private readonly RequestOptions _options; + + public ChatClientGetChatCompletionMessagesCollectionResult(ChatClient client, string completionId, string after, int? limit, string order, RequestOptions options) + { + Argument.AssertNotNullOrEmpty(completionId, nameof(completionId)); + + _client = client; + _completionId = completionId; + _after = after; + _limit = limit; + _order = order; + _options = options; + } + + public override IEnumerable GetRawPages() + { + PipelineMessage message = _client.CreateGetChatCompletionMessagesRequest(_completionId, _after, _limit, _order, _options); + string nextToken = null; + while (true) + { + ClientResult result = ClientResult.FromResponse(_client.Pipeline.ProcessMessage(message, _options)); + yield return result; + + // Plugin customization: add hasMore assignment + bool hasMore = ((InternalChatCompletionMessageList)result).HasMore; + nextToken = ((InternalChatCompletionMessageList)result).LastId; + // Plugin customization: add hasMore == false check to pagination condition + if (nextToken == null || !hasMore) + { + yield break; + } + message = _client.CreateGetChatCompletionMessagesRequest(_completionId, nextToken, _limit, _order, _options); + } + } + + public override ContinuationToken GetContinuationToken(ClientResult page) + { + string nextPage = ((InternalChatCompletionMessageList)page).LastId; + if (nextPage != null) + { + return ContinuationToken.FromBytes(BinaryData.FromString(nextPage)); + } + else + { + return null; + } + } + } +} diff --git a/src/Generated/ChatClientGetChatCompletionMessagesCollectionResultOfT.cs b/src/Generated/ChatClientGetChatCompletionMessagesCollectionResultOfT.cs new file mode 100644 index 000000000..f7e3019d8 --- /dev/null +++ b/src/Generated/ChatClientGetChatCompletionMessagesCollectionResultOfT.cs @@ -0,0 +1,73 @@ +// + +#nullable disable + +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using OpenAI; + +namespace OpenAI.Chat +{ + internal partial class ChatClientGetChatCompletionMessagesCollectionResultOfT : CollectionResult + { + private readonly ChatClient _client; + private readonly string _completionId; + private readonly string _after; + private readonly int? _limit; + private readonly string _order; + private readonly RequestOptions _options; + + public ChatClientGetChatCompletionMessagesCollectionResultOfT(ChatClient client, string completionId, string after, int? limit, string order, RequestOptions options) + { + Argument.AssertNotNullOrEmpty(completionId, nameof(completionId)); + + _client = client; + _completionId = completionId; + _after = after; + _limit = limit; + _order = order; + _options = options; + } + + public override IEnumerable GetRawPages() + { + PipelineMessage message = _client.CreateGetChatCompletionMessagesRequest(_completionId, _after, _limit, _order, _options); + string nextToken = null; + while (true) + { + ClientResult result = ClientResult.FromResponse(_client.Pipeline.ProcessMessage(message, _options)); + yield return result; + + // Plugin customization: add hasMore assignment + bool hasMore = ((InternalChatCompletionMessageList)result).HasMore; + nextToken = ((InternalChatCompletionMessageList)result).LastId; + // Plugin customization: add hasMore == false check to pagination condition + if (nextToken == null || !hasMore) + { + yield break; + } + message = _client.CreateGetChatCompletionMessagesRequest(_completionId, nextToken, _limit, _order, _options); + } + } + + public override ContinuationToken GetContinuationToken(ClientResult page) + { + string nextPage = ((InternalChatCompletionMessageList)page).LastId; + if (nextPage != null) + { + return ContinuationToken.FromBytes(BinaryData.FromString(nextPage)); + } + else + { + return null; + } + } + + protected override IEnumerable GetValuesFromPage(ClientResult page) + { + return ((InternalChatCompletionMessageList)page).Data; + } + } +}