From f4ab277ae377d4213f230f0620b0fe628eaa0cd3 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Tue, 25 Jun 2024 16:17:48 -0700 Subject: [PATCH 01/72] Add project reference to SCM; move to new paging types --- OpenAI.sln | 10 +- README.md | 14 +- .../Assistants/AssistantClient.Convenience.cs | 24 +-- src/Custom/Assistants/AssistantClient.cs | 30 ++-- .../AssistantPageCollection.Protocol.cs | 62 ++++++++ .../Assistants/AssistantPageCollection.cs | 54 +++++++ .../AsyncStreamingUpdateCollection.cs | 2 +- .../Streaming/StreamingUpdateCollection.cs | 2 +- src/Custom/Chat/ChatClient.cs | 8 +- ...StreamingChatCompletionUpdateCollection.cs | 2 +- ...StreamingChatCompletionUpdateCollection.cs | 2 +- src/Custom/Common/InternalListHelpers.cs | 54 +++---- src/Custom/Common/OpenAIPageToken.cs | 52 +++++++ src/Custom/Common/PageableResultHelpers.cs | 146 +++++++++--------- .../VectorStoreClient.Convenience.cs | 8 +- src/Custom/VectorStores/VectorStoreClient.cs | 14 +- src/OpenAI.csproj | 2 +- 17 files changed, 330 insertions(+), 156 deletions(-) create mode 100644 src/Custom/Assistants/AssistantPageCollection.Protocol.cs create mode 100644 src/Custom/Assistants/AssistantPageCollection.cs create mode 100644 src/Custom/Common/OpenAIPageToken.cs diff --git a/OpenAI.sln b/OpenAI.sln index d6350d85f..3d2ce81e7 100644 --- a/OpenAI.sln +++ b/OpenAI.sln @@ -6,7 +6,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenAI", "src\OpenAI.csproj EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenAI.Examples", "examples\OpenAI.Examples.csproj", "{1F1CD1D4-9932-4B73-99D8-C252A67D4B46}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenAI.Tests", "tests\OpenAI.Tests.csproj", "{6F156401-2544-41D7-B204-3148C51C1D09}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenAI.Tests", "tests\OpenAI.Tests.csproj", "{6F156401-2544-41D7-B204-3148C51C1D09}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.ClientModel", "..\azure-sdk-for-net\sdk\core\System.ClientModel\src\System.ClientModel.csproj", "{8269B350-8875-49F9-A9EA-DEF8718FEBE4}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -26,6 +28,10 @@ Global {6F156401-2544-41D7-B204-3148C51C1D09}.Debug|Any CPU.Build.0 = Debug|Any CPU {6F156401-2544-41D7-B204-3148C51C1D09}.Release|Any CPU.ActiveCfg = Release|Any CPU {6F156401-2544-41D7-B204-3148C51C1D09}.Release|Any CPU.Build.0 = Release|Any CPU + {8269B350-8875-49F9-A9EA-DEF8718FEBE4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8269B350-8875-49F9-A9EA-DEF8718FEBE4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8269B350-8875-49F9-A9EA-DEF8718FEBE4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8269B350-8875-49F9-A9EA-DEF8718FEBE4}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -33,4 +39,4 @@ Global GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {A97F4B90-2591-4689-B1F8-5F21FE6D6CAE} EndGlobalSection -EndGlobal \ No newline at end of file +EndGlobal diff --git a/README.md b/README.md index 017165071..d124cace5 100644 --- a/README.md +++ b/README.md @@ -115,11 +115,11 @@ When you request a chat completion, the default behavior is for the server to ge The client library offers a convenient approach to working with streaming chat completions. If you wanted to re-write the example from the previous section using streaming, rather than calling the `ChatClient`'s `CompleteChat` method, you would call its `CompleteChatStreaming` method instead: ```csharp -ResultCollection updates +ResultValueCollection updates = client.CompleteChatStreaming("Say 'this is a test.'"); ``` -Notice that the returned value is a `ResultCollection` instance, which can be enumerated to process the streaming response chunks as they arrive: +Notice that the returned value is a `ResultValueCollection` instance, which can be enumerated to process the streaming response chunks as they arrive: ```csharp Console.WriteLine($"[ASSISTANT]:"); @@ -132,10 +132,10 @@ foreach (StreamingChatCompletionUpdate update in updates) } ``` -Alternatively, you can do this asynchronously by calling the `CompleteChatStreamingAsync` method to get an `AsyncResultCollection` and enumerate it using `await foreach`: +Alternatively, you can do this asynchronously by calling the `CompleteChatStreamingAsync` method to get an `AsyncResultValueCollection` and enumerate it using `await foreach`: ```csharp -AsyncResultCollection updates +AsyncResultValueCollection updates = client.CompleteChatStreamingAsync("Say 'this is a test.'"); Console.WriteLine($"[ASSISTANT]:"); @@ -528,7 +528,7 @@ Finally, you can use the `AssistantClient`'s `GetMessages` method to retrieve th For illustrative purposes, you could print the messages to the console and also save any images produced by the assistant to local storage: ```csharp -PageableCollection messages = assistantClient.GetMessages(threadRun.ThreadId, ListOrder.OldestFirst); +PageCollection messages = assistantClient.GetMessages(threadRun.ThreadId, ListOrder.OldestFirst); foreach (ThreadMessage message in messages) { @@ -640,10 +640,10 @@ AssistantThread thread = assistantClient.CreateThread(new ThreadCreationOptions( }); ``` -With the assistant and thread prepared, use the `CreateRunStreaming` method to get an enumerable `ResultCollection`. You can then iterate over this collection with `foreach`. For async calling patterns, use `CreateRunStreamingAsync` and iterate over the `AsyncResultCollection` with `await foreach`, instead. Note that streaming variants also exist for `CreateThreadAndRunStreaming` and `SubmitToolOutputsToRunStreaming`. +With the assistant and thread prepared, use the `CreateRunStreaming` method to get an enumerable `ResultValueCollection`. You can then iterate over this collection with `foreach`. For async calling patterns, use `CreateRunStreamingAsync` and iterate over the `AsyncResultValueCollection` with `await foreach`, instead. Note that streaming variants also exist for `CreateThreadAndRunStreaming` and `SubmitToolOutputsToRunStreaming`. ```csharp -ResultCollection streamingUpdates = assistantClient.CreateRunStreaming( +ResultValueCollection streamingUpdates = assistantClient.CreateRunStreaming( thread, assistant, new RunCreationOptions() diff --git a/src/Custom/Assistants/AssistantClient.Convenience.cs b/src/Custom/Assistants/AssistantClient.Convenience.cs index 510bbee5f..e69b2a95f 100644 --- a/src/Custom/Assistants/AssistantClient.Convenience.cs +++ b/src/Custom/Assistants/AssistantClient.Convenience.cs @@ -134,7 +134,7 @@ public virtual ClientResult CreateMessage( /// timestamp. /// /// A collection of messages that can be enumerated using await foreach. - public virtual AsyncPageableCollection GetMessagesAsync( + public virtual AsyncPageCollection GetMessagesAsync( AssistantThread thread, ListOrder? resultOrder = default) { @@ -152,7 +152,7 @@ public virtual AsyncPageableCollection GetMessagesAsync( /// timestamp. /// /// A collection of messages that can be enumerated using foreach. - public virtual PageableCollection GetMessages( + public virtual PageCollection GetMessages( AssistantThread thread, ListOrder? resultOrder = default) { @@ -240,7 +240,7 @@ public virtual ClientResult CreateRun(AssistantThread thread, Assista /// The thread that the run should evaluate. /// The assistant that should be used when evaluating the thread. /// Additional options for the run. - public virtual AsyncResultCollection CreateRunStreamingAsync( + public virtual AsyncResultValueCollection CreateRunStreamingAsync( AssistantThread thread, Assistant assistant, RunCreationOptions options = null) @@ -253,7 +253,7 @@ public virtual AsyncResultCollection CreateRunStreamingAsync( /// The thread that the run should evaluate. /// The assistant that should be used when evaluating the thread. /// Additional options for the run. - public virtual ResultCollection CreateRunStreaming( + public virtual ResultValueCollection CreateRunStreaming( AssistantThread thread, Assistant assistant, RunCreationOptions options = null) @@ -291,7 +291,7 @@ public virtual ClientResult CreateThreadAndRun( /// The assistant that the new run should use. /// Options for the new thread that will be created. /// Additional options to apply to the run that will begin. - public virtual AsyncResultCollection CreateThreadAndRunStreamingAsync( + public virtual AsyncResultValueCollection CreateThreadAndRunStreamingAsync( Assistant assistant, ThreadCreationOptions threadOptions = null, RunCreationOptions runOptions = null) @@ -303,7 +303,7 @@ public virtual AsyncResultCollection CreateThreadAndRunStreamin /// The assistant that the new run should use. /// Options for the new thread that will be created. /// Additional options to apply to the run that will begin. - public virtual ResultCollection CreateThreadAndRunStreaming( + public virtual ResultValueCollection CreateThreadAndRunStreaming( Assistant assistant, ThreadCreationOptions threadOptions = null, RunCreationOptions runOptions = null) @@ -318,7 +318,7 @@ public virtual ResultCollection CreateThreadAndRunStreaming( /// timestamp. /// /// A collection of runs that can be enumerated using await foreach. - public virtual AsyncPageableCollection GetRunsAsync( + public virtual AsyncPageCollection GetRunsAsync( AssistantThread thread, ListOrder? resultOrder = default) { @@ -336,7 +336,7 @@ public virtual AsyncPageableCollection GetRunsAsync( /// timestamp. /// /// A collection of runs that can be enumerated using foreach. - public virtual PageableCollection GetRuns( + public virtual PageCollection GetRuns( AssistantThread thread, ListOrder? resultOrder = default) { @@ -394,7 +394,7 @@ public virtual ClientResult SubmitToolOutputsToRun( /// /// The tool outputs, corresponding to instances from the run. /// - public virtual AsyncResultCollection SubmitToolOutputsToRunStreamingAsync( + public virtual AsyncResultValueCollection SubmitToolOutputsToRunStreamingAsync( ThreadRun run, IEnumerable toolOutputs) => SubmitToolOutputsToRunStreamingAsync(run?.ThreadId, run?.Id, toolOutputs); @@ -406,7 +406,7 @@ public virtual AsyncResultCollection SubmitToolOutputsToRunStre /// /// The tool outputs, corresponding to instances from the run. /// - public virtual ResultCollection SubmitToolOutputsToRunStreaming( + public virtual ResultValueCollection SubmitToolOutputsToRunStreaming( ThreadRun run, IEnumerable toolOutputs) => SubmitToolOutputsToRunStreaming(run?.ThreadId, run?.Id, toolOutputs); @@ -436,7 +436,7 @@ public virtual ClientResult CancelRun(ThreadRun run) /// timestamp. /// /// A collection of run steps that can be enumerated using await foreach. - public virtual PageableCollection GetRunSteps( + public virtual PageCollection GetRunSteps( ThreadRun run, ListOrder? resultOrder = default) { @@ -454,7 +454,7 @@ public virtual PageableCollection GetRunSteps( /// timestamp. /// /// A collection of run steps that can be enumerated using foreach. - public virtual AsyncPageableCollection GetRunStepsAsync( + public virtual AsyncPageCollection GetRunStepsAsync( ThreadRun run, ListOrder? resultOrder = default) { diff --git a/src/Custom/Assistants/AssistantClient.cs b/src/Custom/Assistants/AssistantClient.cs index 155409142..209ae3e85 100644 --- a/src/Custom/Assistants/AssistantClient.cs +++ b/src/Custom/Assistants/AssistantClient.cs @@ -7,7 +7,7 @@ using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; -using static OpenAI.InternalListHelpers; +//using static OpenAI.InternalListHelpers; namespace OpenAI.Assistants; @@ -111,7 +111,7 @@ public virtual ClientResult CreateAssistant(string model, AssistantCr /// /// A token that can be used to cancel this method call. /// A collection of assistants that can be enumerated using await foreach. - public virtual AsyncPageableCollection GetAssistantsAsync(ListOrder? resultOrder = null, CancellationToken cancellationToken = default) + public virtual AsyncPageCollection GetAssistantsAsync(ListOrder? resultOrder = null, CancellationToken cancellationToken = default) { return CreateAsyncPageable((continuationToken, pageSize) => GetAssistantsAsync(pageSize, resultOrder?.ToString(), continuationToken, null, cancellationToken.ToRequestOptions())); @@ -126,7 +126,7 @@ public virtual AsyncPageableCollection GetAssistantsAsync(ListOrder? /// /// A token that can be used to cancel this method call. /// A collection of assistants that can be enumerated using foreach. - public virtual PageableCollection GetAssistants(ListOrder? resultOrder = null, CancellationToken cancellationToken = default) + public virtual PageCollection GetAssistants(ListOrder? resultOrder = null, CancellationToken cancellationToken = default) { return CreatePageable((continuationToken, pageSize) => GetAssistants(pageSize, resultOrder?.ToString(), continuationToken, null, cancellationToken.ToRequestOptions())); @@ -345,7 +345,7 @@ public virtual ClientResult CreateMessage( /// /// A token that can be used to cancel this method call. /// A collection of messages that can be enumerated using await foreach. - public virtual AsyncPageableCollection GetMessagesAsync( + public virtual AsyncPageCollection GetMessagesAsync( string threadId, ListOrder? resultOrder = null, CancellationToken cancellationToken = default) @@ -366,7 +366,7 @@ public virtual AsyncPageableCollection GetMessagesAsync( /// /// A token that can be used to cancel this method call. /// A collection of messages that can be enumerated using foreach. - public virtual PageableCollection GetMessages( + public virtual PageCollection GetMessages( string threadId, ListOrder? resultOrder = null, CancellationToken cancellationToken = default) @@ -531,7 +531,7 @@ public virtual ClientResult CreateRun(string threadId, string assista /// The ID of the assistant that should be used when evaluating the thread. /// Additional options for the run. /// A token that can be used to cancel this method call. - public virtual AsyncResultCollection CreateRunStreamingAsync( + public virtual AsyncResultValueCollection CreateRunStreamingAsync( string threadId, string assistantId, RunCreationOptions options = null, @@ -559,7 +559,7 @@ await CreateRunAsync(threadId, options.ToBinaryContent(), cancellationToken.ToRe /// The ID of the assistant that should be used when evaluating the thread. /// Additional options for the run. /// A token that can be used to cancel this method call. - public virtual ResultCollection CreateRunStreaming( + public virtual ResultValueCollection CreateRunStreaming( string threadId, string assistantId, RunCreationOptions options = null, @@ -626,7 +626,7 @@ public virtual ClientResult CreateThreadAndRun( /// Options for the new thread that will be created. /// Additional options to apply to the run that will begin. /// A token that can be used to cancel this method call. - public virtual AsyncResultCollection CreateThreadAndRunStreamingAsync( + public virtual AsyncResultValueCollection CreateThreadAndRunStreamingAsync( string assistantId, ThreadCreationOptions threadOptions = null, RunCreationOptions runOptions = null, @@ -652,7 +652,7 @@ await CreateThreadAndRunAsync(protocolContent, cancellationToken.ToRequestOption /// Options for the new thread that will be created. /// Additional options to apply to the run that will begin. /// A token that can be used to cancel this method call. - public virtual ResultCollection CreateThreadAndRunStreaming( + public virtual ResultValueCollection CreateThreadAndRunStreaming( string assistantId, ThreadCreationOptions threadOptions = null, RunCreationOptions runOptions = null, @@ -679,7 +679,7 @@ public virtual ResultCollection CreateThreadAndRunStreaming( /// /// A token that can be used to cancel this method call. /// A collection of runs that can be enumerated using await foreach. - public virtual AsyncPageableCollection GetRunsAsync( + public virtual AsyncPageCollection GetRunsAsync( string threadId, ListOrder? resultOrder = default, CancellationToken cancellationToken = default) @@ -700,7 +700,7 @@ public virtual AsyncPageableCollection GetRunsAsync( /// /// A token that can be used to cancel this method call. /// A collection of runs that can be enumerated using foreach. - public virtual PageableCollection GetRuns( + public virtual PageCollection GetRuns( string threadId, ListOrder? resultOrder = default, CancellationToken cancellationToken = default) @@ -801,7 +801,7 @@ public virtual ClientResult SubmitToolOutputsToRun( /// The tool outputs, corresponding to instances from the run. /// /// A token that can be used to cancel this method call. - public virtual AsyncResultCollection SubmitToolOutputsToRunStreamingAsync( + public virtual AsyncResultValueCollection SubmitToolOutputsToRunStreamingAsync( string threadId, string runId, IEnumerable toolOutputs, @@ -829,7 +829,7 @@ await SubmitToolOutputsToRunAsync(threadId, runId, content, cancellationToken.To /// The tool outputs, corresponding to instances from the run. /// /// A token that can be used to cancel this method call. - public virtual ResultCollection SubmitToolOutputsToRunStreaming( + public virtual ResultValueCollection SubmitToolOutputsToRunStreaming( string threadId, string runId, IEnumerable toolOutputs, @@ -889,7 +889,7 @@ public virtual ClientResult CancelRun(string threadId, string runId, /// /// A token that can be used to cancel this method call. /// A collection of run steps that can be enumerated using await foreach. - public virtual AsyncPageableCollection GetRunStepsAsync( + public virtual AsyncPageCollection GetRunStepsAsync( string threadId, string runId, ListOrder? resultOrder = default, @@ -913,7 +913,7 @@ public virtual AsyncPageableCollection GetRunStepsAsync( /// /// A token that can be used to cancel this method call. /// A collection of run steps that can be enumerated using foreach. - public virtual PageableCollection GetRunSteps( + public virtual PageCollection GetRunSteps( string threadId, string runId, ListOrder? resultOrder = default, diff --git a/src/Custom/Assistants/AssistantPageCollection.Protocol.cs b/src/Custom/Assistants/AssistantPageCollection.Protocol.cs new file mode 100644 index 000000000..8f38120ff --- /dev/null +++ b/src/Custom/Assistants/AssistantPageCollection.Protocol.cs @@ -0,0 +1,62 @@ +using OpenAI.Assistants; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Collections; +using System.Collections.Generic; +using System.Text.Json; + +#nullable enable + +namespace OpenAI; + +#pragma warning disable OPENAI001 +internal class ProtocolAssistantPageCollection : IEnumerable +{ + private readonly AssistantClient _client; + + private readonly int? _limit; + private readonly string? _order; + private readonly string? _after; + private readonly string? _before; + + private readonly RequestOptions? _options; + + public ProtocolAssistantPageCollection(AssistantClient client, int? limit, string order, string after, string before, RequestOptions options) + { + _client = client; + + _limit = limit; + _order = order; + _after = after; + _before = before; + + _options = options; + } + + public IEnumerator GetEnumerator() + { + string? after = _after; + bool hasMore = false; + + do + { + ClientResult result = _client.GetAssistantsPage( + limit: _limit, + order: _order, + after: after, + before: _before, + options: _options); + + yield return result; + + PipelineResponse response = result.GetRawResponse(); + using JsonDocument doc = JsonDocument.Parse(response.Content); + hasMore = doc.RootElement.GetProperty("has_more"u8).GetBoolean(); + after = doc.RootElement.GetProperty("last_id"u8).GetString(); + + } while (hasMore); + } + + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); +} +#pragma warning restore OPENAI001 \ No newline at end of file diff --git a/src/Custom/Assistants/AssistantPageCollection.cs b/src/Custom/Assistants/AssistantPageCollection.cs new file mode 100644 index 000000000..159864d2a --- /dev/null +++ b/src/Custom/Assistants/AssistantPageCollection.cs @@ -0,0 +1,54 @@ +using OpenAI.Assistants; +using System.ClientModel; +using System.ClientModel.Primitives; +using System; + +#nullable enable + +namespace OpenAI; + +#pragma warning disable OPENAI001 +internal class AssistantPageCollection : PageCollection +{ + private readonly AssistantClient _client; + + private readonly int? _limit; + private readonly string? _order; + private readonly string? _after; + private readonly string? _before; + + // service method constructor + public AssistantPageCollection(AssistantClient client, int? limit, string? order, string? after, string? before) + { + _client = client; + + _limit = limit; + _order = order; + _after = after; + _before = before; + + FirstPageToken = BinaryData.FromString(after ?? string.Empty); + } + + public override BinaryData FirstPageToken { get; } + + public override ClientPage GetPage(BinaryData pageToken, RequestOptions? options) + { + OpenAIPageToken token = OpenAIPageToken.FromBytes(pageToken); + + ClientResult result = _client.GetAssistantsPage( + limit: _limit, + order: _order, + after: token.After, + before: _before, + options: options); + + PipelineResponse response = result.GetRawResponse(); + InternalListAssistantsResponse list = ModelReaderWriter.Read(response.Content)!; + + BinaryData? nextPageToken = OpenAIPageToken.GetNextPageToken(list.HasMore, list.LastId); + return ClientPage.Create(list.Data, pageToken, nextPageToken, response); + } + +} +#pragma warning restore OPENAI001 \ No newline at end of file diff --git a/src/Custom/Assistants/Streaming/AsyncStreamingUpdateCollection.cs b/src/Custom/Assistants/Streaming/AsyncStreamingUpdateCollection.cs index c7640f02f..325611128 100644 --- a/src/Custom/Assistants/Streaming/AsyncStreamingUpdateCollection.cs +++ b/src/Custom/Assistants/Streaming/AsyncStreamingUpdateCollection.cs @@ -15,7 +15,7 @@ namespace OpenAI.Assistants; /// /// Implementation of collection abstraction over streaming assistant updates. /// -internal class AsyncStreamingUpdateCollection : AsyncResultCollection +internal class AsyncStreamingUpdateCollection : AsyncResultValueCollection { private readonly Func> _getResultAsync; diff --git a/src/Custom/Assistants/Streaming/StreamingUpdateCollection.cs b/src/Custom/Assistants/Streaming/StreamingUpdateCollection.cs index 85f51273e..4f9b511f8 100644 --- a/src/Custom/Assistants/Streaming/StreamingUpdateCollection.cs +++ b/src/Custom/Assistants/Streaming/StreamingUpdateCollection.cs @@ -13,7 +13,7 @@ namespace OpenAI.Assistants; /// /// Implementation of collection abstraction over streaming assistant updates. /// -internal class StreamingUpdateCollection : ResultCollection +internal class StreamingUpdateCollection : ResultValueCollection { private readonly Func _getResult; diff --git a/src/Custom/Chat/ChatClient.cs b/src/Custom/Chat/ChatClient.cs index 0c509b393..788035217 100644 --- a/src/Custom/Chat/ChatClient.cs +++ b/src/Custom/Chat/ChatClient.cs @@ -132,7 +132,7 @@ public virtual ClientResult CompleteChat(params ChatMessage[] me /// Additional options for the chat completion request. /// A token that can be used to cancel this method call. /// A streaming result with incremental chat completion updates. - public virtual AsyncResultCollection CompleteChatStreamingAsync(IEnumerable messages, ChatCompletionOptions options = null, CancellationToken cancellationToken = default) + public virtual AsyncResultValueCollection CompleteChatStreamingAsync(IEnumerable messages, ChatCompletionOptions options = null, CancellationToken cancellationToken = default) { Argument.AssertNotNull(messages, nameof(messages)); @@ -156,7 +156,7 @@ async Task getResultAsync() => /// /// The messages to provide as input for chat completion. /// A streaming result with incremental chat completion updates. - public virtual AsyncResultCollection CompleteChatStreamingAsync(params ChatMessage[] messages) + public virtual AsyncResultValueCollection CompleteChatStreamingAsync(params ChatMessage[] messages) => CompleteChatStreamingAsync(messages, default(ChatCompletionOptions)); /// @@ -171,7 +171,7 @@ public virtual AsyncResultCollection CompleteChat /// Additional options for the chat completion request. /// A token that can be used to cancel this method call. /// A streaming result with incremental chat completion updates. - public virtual ResultCollection CompleteChatStreaming(IEnumerable messages, ChatCompletionOptions options = null, CancellationToken cancellationToken = default) + public virtual ResultValueCollection CompleteChatStreaming(IEnumerable messages, ChatCompletionOptions options = null, CancellationToken cancellationToken = default) { Argument.AssertNotNull(messages, nameof(messages)); @@ -193,7 +193,7 @@ public virtual ResultCollection CompleteChatStrea /// /// The messages to provide as input for chat completion. /// A streaming result with incremental chat completion updates. - public virtual ResultCollection CompleteChatStreaming(params ChatMessage[] messages) + public virtual ResultValueCollection CompleteChatStreaming(params ChatMessage[] messages) => CompleteChatStreaming(messages, default(ChatCompletionOptions)); private void CreateChatCompletionOptions(IEnumerable messages, ref ChatCompletionOptions options, bool stream = false) diff --git a/src/Custom/Chat/Internal/AsyncStreamingChatCompletionUpdateCollection.cs b/src/Custom/Chat/Internal/AsyncStreamingChatCompletionUpdateCollection.cs index 55bbeb7d8..689a5ed2d 100644 --- a/src/Custom/Chat/Internal/AsyncStreamingChatCompletionUpdateCollection.cs +++ b/src/Custom/Chat/Internal/AsyncStreamingChatCompletionUpdateCollection.cs @@ -15,7 +15,7 @@ namespace OpenAI.Chat; /// /// Implementation of collection abstraction over streaming chat updates. /// -internal class AsyncStreamingChatCompletionUpdateCollection : AsyncResultCollection +internal class AsyncStreamingChatCompletionUpdateCollection : AsyncResultValueCollection { private readonly Func> _getResultAsync; diff --git a/src/Custom/Chat/Internal/StreamingChatCompletionUpdateCollection.cs b/src/Custom/Chat/Internal/StreamingChatCompletionUpdateCollection.cs index 0e51009e7..c6990fe39 100644 --- a/src/Custom/Chat/Internal/StreamingChatCompletionUpdateCollection.cs +++ b/src/Custom/Chat/Internal/StreamingChatCompletionUpdateCollection.cs @@ -14,7 +14,7 @@ namespace OpenAI.Chat; /// /// Implementation of collection abstraction over streaming chat updates. /// -internal class StreamingChatCompletionUpdateCollection : ResultCollection +internal class StreamingChatCompletionUpdateCollection : ResultValueCollection { private readonly Func _getResult; diff --git a/src/Custom/Common/InternalListHelpers.cs b/src/Custom/Common/InternalListHelpers.cs index 4537ad780..46372992f 100644 --- a/src/Custom/Common/InternalListHelpers.cs +++ b/src/Custom/Common/InternalListHelpers.cs @@ -5,33 +5,33 @@ namespace OpenAI; -internal static class InternalListHelpers -{ - internal delegate Task AsyncListResponseFunc(string continuationToken, int? pageSize); - internal delegate ClientResult ListResponseFunc(string continuationToken, int? pageSize); +//internal static class InternalListHelpers +//{ +// internal delegate Task AsyncListResponseFunc(string continuationToken, int? pageSize); +// internal delegate ClientResult ListResponseFunc(string continuationToken, int? pageSize); - internal static AsyncPageableCollection CreateAsyncPageable(AsyncListResponseFunc listResponseFunc) - where U : IJsonModel, IInternalListResponse - { - async Task> pageFunc(string continuationToken, int? pageSize) - => GetPageFromProtocol(await listResponseFunc(continuationToken, pageSize).ConfigureAwait(false)); - return PageableResultHelpers.Create((pageSize) => pageFunc(null, pageSize), pageFunc); - } +// internal static AsyncPageCollection CreateAsyncPageable(AsyncListResponseFunc listResponseFunc) +// where U : IJsonModel, IInternalListResponse +// { +// async Task> pageFunc(string continuationToken, int? pageSize) +// => GetPageFromProtocol(await listResponseFunc(continuationToken, pageSize).ConfigureAwait(false)); +// return PageableResultHelpers.Create((pageSize) => pageFunc(null, pageSize), pageFunc); +// } - internal static PageableCollection CreatePageable(ListResponseFunc listResponseFunc) - where U : IJsonModel, IInternalListResponse - { - ResultPage pageFunc(string continuationToken, int? pageSize) - => GetPageFromProtocol(listResponseFunc(continuationToken, pageSize)); - return PageableResultHelpers.Create((pageSize) => pageFunc(null, pageSize), pageFunc); - } +// internal static PageCollection CreatePageable(ListResponseFunc listResponseFunc) +// where U : IJsonModel, IInternalListResponse +// { +// ClientPage pageFunc(string continuationToken, int? pageSize) +// => GetPageFromProtocol(listResponseFunc(continuationToken, pageSize)); +// return PageableResultHelpers.Create((pageSize) => pageFunc(null, pageSize), pageFunc); +// } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static ResultPage GetPageFromProtocol(ClientResult protocolResult) - where UInternalList : IJsonModel, IInternalListResponse - { - PipelineResponse response = protocolResult.GetRawResponse(); - IInternalListResponse values = ModelReaderWriter.Read(response.Content); - return ResultPage.Create(values.Data, values.HasMore ? values.LastId : null, response); - } -} +// [MethodImpl(MethodImplOptions.AggressiveInlining)] +// private static ClientPage GetPageFromProtocol(ClientResult protocolResult) +// where UInternalList : IJsonModel, IInternalListResponse +// { +// PipelineResponse response = protocolResult.GetRawResponse(); +// IInternalListResponse values = ModelReaderWriter.Read(response.Content); +// return ClientPage.Create(values.Data, values.HasMore ? values.LastId : null, response); +// } +//} diff --git a/src/Custom/Common/OpenAIPageToken.cs b/src/Custom/Common/OpenAIPageToken.cs new file mode 100644 index 000000000..351bda711 --- /dev/null +++ b/src/Custom/Common/OpenAIPageToken.cs @@ -0,0 +1,52 @@ +using System; +using System.ClientModel.Primitives; + +#nullable enable + +namespace OpenAI; + +internal class OpenAIPageToken +{ + public OpenAIPageToken(int? pageSize, + string? order, + string? after, + string? before, + string? lastSeenId) + { + PageSize = pageSize; + Order = order; + After = after; + Before = before; + LastSeenId = lastSeenId; + } + + public int? PageSize { get; } + + public string? Order { get; } + + public string? After { get; } + + public string? Before { get; } + + public string? LastSeenId { get; } + + public BinaryData ToBytes() + { + throw new NotImplementedException(); + } + + public static OpenAIPageToken FromBytes(BinaryData data) + { + throw new NotImplementedException(); + } + + public static BinaryData? GetNextPageToken(bool hasMore, string? lastId) + { + if (!hasMore || lastId is null) + { + return null; + } + + throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/src/Custom/Common/PageableResultHelpers.cs b/src/Custom/Common/PageableResultHelpers.cs index 23290c932..fc58a8823 100644 --- a/src/Custom/Common/PageableResultHelpers.cs +++ b/src/Custom/Common/PageableResultHelpers.cs @@ -7,87 +7,87 @@ namespace OpenAI; -internal class PageableResultHelpers -{ - public static PageableCollection Create(Func> firstPageFunc, Func>? nextPageFunc, int? pageSize = default) where T : notnull - { - ResultPage first(string? _, int? pageSizeHint) => firstPageFunc(pageSizeHint); - return new FuncPageable(first, nextPageFunc, pageSize); - } +//internal class PageableResultHelpers +//{ +// public static PageCollection Create(Func> firstPageFunc, Func>? nextPageFunc, int? pageSize = default) where T : notnull +// { +// ClientPage first(string? _, int? pageSizeHint) => firstPageFunc(pageSizeHint); +// return new FuncPageable(first, nextPageFunc, pageSize); +// } - public static AsyncPageableCollection Create(Func>> firstPageFunc, Func>>? nextPageFunc, int? pageSize = default) where T : notnull - { - Task> first(string? _, int? pageSizeHint) => firstPageFunc(pageSizeHint); - return new FuncAsyncPageable(first, nextPageFunc, pageSize); - } +// public static AsyncPageCollection Create(Func>> firstPageFunc, Func>>? nextPageFunc, int? pageSize = default) where T : notnull +// { +// Task> first(string? _, int? pageSizeHint) => firstPageFunc(pageSizeHint); +// return new FuncAsyncPageable(first, nextPageFunc, pageSize); +// } - private class FuncAsyncPageable : AsyncPageableCollection where T : notnull - { - private readonly Func>> _firstPageFunc; - private readonly Func>>? _nextPageFunc; - private readonly int? _defaultPageSize; +// private class FuncAsyncPageable : AsyncPageCollection where T : notnull +// { +// private readonly Func>> _firstPageFunc; +// private readonly Func>>? _nextPageFunc; +// private readonly int? _defaultPageSize; - public FuncAsyncPageable(Func>> firstPageFunc, Func>>? nextPageFunc, int? defaultPageSize = default) - { - _firstPageFunc = firstPageFunc; - _nextPageFunc = nextPageFunc; - _defaultPageSize = defaultPageSize; - } +// public FuncAsyncPageable(Func>> firstPageFunc, Func>>? nextPageFunc, int? defaultPageSize = default) +// { +// _firstPageFunc = firstPageFunc; +// _nextPageFunc = nextPageFunc; +// _defaultPageSize = defaultPageSize; +// } - public override async IAsyncEnumerable> AsPages(string? continuationToken = default, int? pageSizeHint = default) - { - Func>>? pageFunc = string.IsNullOrEmpty(continuationToken) ? _firstPageFunc : _nextPageFunc; +// public override async IAsyncEnumerable> AsPages(string? continuationToken = default, int? pageSizeHint = default) +// { +// Func>>? pageFunc = string.IsNullOrEmpty(continuationToken) ? _firstPageFunc : _nextPageFunc; - if (pageFunc == null) - { - yield break; - } +// if (pageFunc == null) +// { +// yield break; +// } - int? pageSize = pageSizeHint ?? _defaultPageSize; - do - { - ResultPage page = await pageFunc(continuationToken, pageSize).ConfigureAwait(false); - SetRawResponse(page.GetRawResponse()); - yield return page; - continuationToken = page.ContinuationToken; - pageFunc = _nextPageFunc; - } - while (!string.IsNullOrEmpty(continuationToken) && pageFunc != null); - } - } +// int? pageSize = pageSizeHint ?? _defaultPageSize; +// do +// { +// ClientPage page = await pageFunc(continuationToken, pageSize).ConfigureAwait(false); +// SetRawResponse(page.GetRawResponse()); +// yield return page; +// continuationToken = page.ContinuationToken; +// pageFunc = _nextPageFunc; +// } +// while (!string.IsNullOrEmpty(continuationToken) && pageFunc != null); +// } +// } - private class FuncPageable : PageableCollection where T : notnull - { - private readonly Func> _firstPageFunc; - private readonly Func>? _nextPageFunc; - private readonly int? _defaultPageSize; +// private class FuncPageable : PageCollection where T : notnull +// { +// private readonly Func> _firstPageFunc; +// private readonly Func>? _nextPageFunc; +// private readonly int? _defaultPageSize; - public FuncPageable(Func> firstPageFunc, Func>? nextPageFunc, int? defaultPageSize = default) - { - _firstPageFunc = firstPageFunc; - _nextPageFunc = nextPageFunc; - _defaultPageSize = defaultPageSize; - } +// public FuncPageable(Func> firstPageFunc, Func>? nextPageFunc, int? defaultPageSize = default) +// { +// _firstPageFunc = firstPageFunc; +// _nextPageFunc = nextPageFunc; +// _defaultPageSize = defaultPageSize; +// } - public override IEnumerable> AsPages(string? continuationToken = default, int? pageSizeHint = default) - { - Func>? pageFunc = string.IsNullOrEmpty(continuationToken) ? _firstPageFunc : _nextPageFunc; +// public override IEnumerable> AsPages(string? continuationToken = default, int? pageSizeHint = default) +// { +// Func>? pageFunc = string.IsNullOrEmpty(continuationToken) ? _firstPageFunc : _nextPageFunc; - if (pageFunc == null) - { - yield break; - } +// if (pageFunc == null) +// { +// yield break; +// } - int? pageSize = pageSizeHint ?? _defaultPageSize; - do - { - ResultPage page = pageFunc(continuationToken, pageSize); - SetRawResponse(page.GetRawResponse()); - yield return page; - continuationToken = page.ContinuationToken; - pageFunc = _nextPageFunc; - } - while (!string.IsNullOrEmpty(continuationToken) && pageFunc != null); - } - } -} +// int? pageSize = pageSizeHint ?? _defaultPageSize; +// do +// { +// ClientPage page = pageFunc(continuationToken, pageSize); +// SetRawResponse(page.GetRawResponse()); +// yield return page; +// continuationToken = page.ContinuationToken; +// pageFunc = _nextPageFunc; +// } +// while (!string.IsNullOrEmpty(continuationToken) && pageFunc != null); +// } +// } +//} diff --git a/src/Custom/VectorStores/VectorStoreClient.Convenience.cs b/src/Custom/VectorStores/VectorStoreClient.Convenience.cs index 3917b5171..bb328b09b 100644 --- a/src/Custom/VectorStores/VectorStoreClient.Convenience.cs +++ b/src/Custom/VectorStores/VectorStoreClient.Convenience.cs @@ -98,7 +98,7 @@ public virtual ClientResult AddFileToVectorStore(Vec /// A collection of instances that can be asynchronously enumerated via /// await foreach. /// - public virtual AsyncPageableCollection GetFileAssociationsAsync( + public virtual AsyncPageCollection GetFileAssociationsAsync( VectorStore vectorStore, ListOrder? resultOrder = null, VectorStoreFileStatusFilter? filter = null) @@ -122,7 +122,7 @@ public virtual AsyncPageableCollection GetFileAssoci /// A collection of instances that can be synchronously enumerated via /// foreach. /// - public virtual PageableCollection GetFileAssociations( + public virtual PageCollection GetFileAssociations( VectorStore vectorStore, ListOrder? resultOrder = null, VectorStoreFileStatusFilter? filter = null) @@ -243,7 +243,7 @@ public virtual ClientResult CancelBatchFileJob(VectorSt /// A collection of instances that can be asynchronously enumerated via /// await foreach. /// - public virtual AsyncPageableCollection GetFileAssociationsAsync( + public virtual AsyncPageCollection GetFileAssociationsAsync( VectorStoreBatchFileJob batchJob, ListOrder? resultOrder = null, VectorStoreFileStatusFilter? filter = null) @@ -265,7 +265,7 @@ public virtual AsyncPageableCollection GetFileAssoci /// A collection of instances that can be synchronously enumerated via /// foreach. /// - public virtual PageableCollection GetFileAssociations( + public virtual PageCollection GetFileAssociations( VectorStoreBatchFileJob batchJob, ListOrder? resultOrder = null, VectorStoreFileStatusFilter? filter = null) diff --git a/src/Custom/VectorStores/VectorStoreClient.cs b/src/Custom/VectorStores/VectorStoreClient.cs index e12c35737..cfb29ed62 100644 --- a/src/Custom/VectorStores/VectorStoreClient.cs +++ b/src/Custom/VectorStores/VectorStoreClient.cs @@ -8,7 +8,7 @@ using System.Diagnostics.CodeAnalysis; using System.Threading; using System.Threading.Tasks; -using static OpenAI.InternalListHelpers; +//using static OpenAI.InternalListHelpers; namespace OpenAI.VectorStores; @@ -148,7 +148,7 @@ public virtual ClientResult DeleteVectorStore(string vectorStoreId, Cancel /// A collection of instances that can be asynchronously enumerated via /// await foreach. /// - public virtual AsyncPageableCollection GetVectorStoresAsync(ListOrder? resultOrder = null, CancellationToken cancellationToken = default) + public virtual AsyncPageCollection GetVectorStoresAsync(ListOrder? resultOrder = null, CancellationToken cancellationToken = default) { return CreateAsyncPageable((continuationToken, pageSize) => GetVectorStoresAsync(pageSize, resultOrder?.ToString(), continuationToken, null, cancellationToken.ToRequestOptions())); @@ -165,7 +165,7 @@ public virtual AsyncPageableCollection GetVectorStoresAsync(ListOrd /// /// A collection of instances that can be synchronously enumerated via foreach. /// - public virtual PageableCollection GetVectorStores(ListOrder? resultOrder = null, CancellationToken cancellationToken = default) + public virtual PageCollection GetVectorStores(ListOrder? resultOrder = null, CancellationToken cancellationToken = default) { return CreatePageable((continuationToken, pageSize) => GetVectorStores(pageSize, resultOrder?.ToString(), continuationToken, null, cancellationToken.ToRequestOptions())); @@ -226,7 +226,7 @@ public virtual ClientResult AddFileToVectorStore(str /// A collection of instances that can be asynchronously enumerated via /// await foreach. /// - public virtual AsyncPageableCollection GetFileAssociationsAsync( + public virtual AsyncPageCollection GetFileAssociationsAsync( string vectorStoreId, ListOrder? resultOrder = null, VectorStoreFileStatusFilter? filter = null, @@ -257,7 +257,7 @@ public virtual AsyncPageableCollection GetFileAssoci /// A collection of instances that can be synchronously enumerated via /// foreach. /// - public virtual PageableCollection GetFileAssociations(string vectorStoreId, ListOrder? resultOrder = null, VectorStoreFileStatusFilter? filter = null, CancellationToken cancellationToken = default) + public virtual PageCollection GetFileAssociations(string vectorStoreId, ListOrder? resultOrder = null, VectorStoreFileStatusFilter? filter = null, CancellationToken cancellationToken = default) { Argument.AssertNotNullOrEmpty(vectorStoreId, nameof(vectorStoreId)); return CreatePageable( @@ -487,7 +487,7 @@ public virtual ClientResult CancelBatchFileJob(string v /// A collection of instances that can be asynchronously enumerated via /// await foreach. /// - public virtual AsyncPageableCollection GetFileAssociationsAsync( + public virtual AsyncPageCollection GetFileAssociationsAsync( string vectorStoreId, string batchJobId, ListOrder? resultOrder = null, @@ -524,7 +524,7 @@ public virtual AsyncPageableCollection GetFileAssoci /// A collection of instances that can be synchronously enumerated via /// foreach. /// - public virtual PageableCollection GetFileAssociations( + public virtual PageCollection GetFileAssociations( string vectorStoreId, string batchJobId, ListOrder? resultOrder = null, diff --git a/src/OpenAI.csproj b/src/OpenAI.csproj index 8f61f3af6..125e5032b 100644 --- a/src/OpenAI.csproj +++ b/src/OpenAI.csproj @@ -60,7 +60,7 @@ - + From 38dd09ddf45768266de257002710c236b9abcded Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Tue, 25 Jun 2024 16:39:35 -0700 Subject: [PATCH 02/72] wire return values and stub out implementations --- .../Assistants/AssistantClient.Protocol.cs | 17 ++++++-- src/Custom/Assistants/AssistantClient.cs | 43 +++++++++++-------- src/Custom/VectorStores/VectorStoreClient.cs | 41 +++++++++++------- 3 files changed, 64 insertions(+), 37 deletions(-) diff --git a/src/Custom/Assistants/AssistantClient.Protocol.cs b/src/Custom/Assistants/AssistantClient.Protocol.cs index e6912702e..0ce420320 100644 --- a/src/Custom/Assistants/AssistantClient.Protocol.cs +++ b/src/Custom/Assistants/AssistantClient.Protocol.cs @@ -1,6 +1,7 @@ using System; using System.ClientModel; using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Threading.Tasks; namespace OpenAI.Assistants; @@ -63,10 +64,12 @@ public virtual ClientResult CreateAssistant(BinaryContent content, RequestOption /// The request options, which can override default behaviors of the client pipeline on a per-call basis. /// Service returned a non-success status code. /// The response returned from the service. - public virtual async Task GetAssistantsAsync(int? limit, string order, string after, string before, RequestOptions options) + public virtual IAsyncEnumerable GetAssistantsAsync(int? limit, string order, string after, string before, RequestOptions options) { - using PipelineMessage message = CreateGetAssistantsRequest(limit, order, after, before, options); - return ClientResult.FromResponse(await _pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); + throw new NotImplementedException(); + //return new ProtocolAssistantPageCollection(this, limit, order, after, before, options); + //using PipelineMessage message = CreateGetAssistantsRequest(limit, order, after, before, options); + //return ClientResult.FromResponse(await _pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); } /// @@ -93,7 +96,13 @@ public virtual async Task GetAssistantsAsync(int? limit, string or /// The request options, which can override default behaviors of the client pipeline on a per-call basis. /// Service returned a non-success status code. /// The response returned from the service. - public virtual ClientResult GetAssistants(int? limit, string order, string after, string before, RequestOptions options) + public virtual IEnumerable GetAssistants(int? limit, string order, string after, string before, RequestOptions options) + { + return new ProtocolAssistantPageCollection(this, limit, order, after, before, options); + } + + // This needs to be internal now + internal virtual ClientResult GetAssistantsPage(int? limit, string order, string after, string before, RequestOptions options) { using PipelineMessage message = CreateGetAssistantsRequest(limit, order, after, before, options); return ClientResult.FromResponse(_pipeline.ProcessMessage(message, options)); diff --git a/src/Custom/Assistants/AssistantClient.cs b/src/Custom/Assistants/AssistantClient.cs index 209ae3e85..61f592c95 100644 --- a/src/Custom/Assistants/AssistantClient.cs +++ b/src/Custom/Assistants/AssistantClient.cs @@ -113,8 +113,9 @@ public virtual ClientResult CreateAssistant(string model, AssistantCr /// A collection of assistants that can be enumerated using await foreach. public virtual AsyncPageCollection GetAssistantsAsync(ListOrder? resultOrder = null, CancellationToken cancellationToken = default) { - return CreateAsyncPageable((continuationToken, pageSize) - => GetAssistantsAsync(pageSize, resultOrder?.ToString(), continuationToken, null, cancellationToken.ToRequestOptions())); + throw new NotImplementedException(); + //return CreateAsyncPageable((continuationToken, pageSize) + // => GetAssistantsAsync(pageSize, resultOrder?.ToString(), continuationToken, null, cancellationToken.ToRequestOptions())); } /// @@ -124,12 +125,14 @@ public virtual AsyncPageCollection GetAssistantsAsync(ListOrder? resu /// The order that results should appear in the list according to their created_at /// timestamp. /// + /// The number of values to return in a single page in the page collection. + /// The id of the item preceeding the first item in the collection. + /// The id of the item following the last item in the collection. /// A token that can be used to cancel this method call. /// A collection of assistants that can be enumerated using foreach. - public virtual PageCollection GetAssistants(ListOrder? resultOrder = null, CancellationToken cancellationToken = default) + public virtual PageCollection GetAssistants(ListOrder? resultOrder, int? pageSize, string afterId = default, string beforeId = default, CancellationToken cancellationToken = default) { - return CreatePageable((continuationToken, pageSize) - => GetAssistants(pageSize, resultOrder?.ToString(), continuationToken, null, cancellationToken.ToRequestOptions())); + return new AssistantPageCollection(this, pageSize, resultOrder?.ToString(), afterId, beforeId); } /// @@ -352,8 +355,9 @@ public virtual AsyncPageCollection GetMessagesAsync( { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); - return CreateAsyncPageable((continuationToken, pageSize) - => GetMessagesAsync(threadId, pageSize, resultOrder?.ToString(), continuationToken, null, cancellationToken.ToRequestOptions())); + throw new NotImplementedException(); + //return CreateAsyncPageable((continuationToken, pageSize) + // => GetMessagesAsync(threadId, pageSize, resultOrder?.ToString(), continuationToken, null, cancellationToken.ToRequestOptions())); } /// @@ -373,8 +377,9 @@ public virtual PageCollection GetMessages( { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); - return CreatePageable((continuationToken, pageSize) - => GetMessages(threadId, pageSize, resultOrder?.ToString(), continuationToken, null, cancellationToken.ToRequestOptions())); + throw new NotImplementedException(); + //return CreatePageable((continuationToken, pageSize) + // => GetMessages(threadId, pageSize, resultOrder?.ToString(), continuationToken, null, cancellationToken.ToRequestOptions())); } /// @@ -686,8 +691,9 @@ public virtual AsyncPageCollection GetRunsAsync( { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); - return CreateAsyncPageable((continuationToken, pageSize) - => GetRunsAsync(threadId, pageSize, resultOrder?.ToString(), continuationToken, null, cancellationToken.ToRequestOptions())); + throw new NotImplementedException(); + //return CreateAsyncPageable((continuationToken, pageSize) + // => GetRunsAsync(threadId, pageSize, resultOrder?.ToString(), continuationToken, null, cancellationToken.ToRequestOptions())); } /// @@ -707,8 +713,9 @@ public virtual PageCollection GetRuns( { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); - return CreatePageable((continuationToken, pageSize) - => GetRuns(threadId, pageSize, resultOrder?.ToString(), continuationToken, null, cancellationToken.ToRequestOptions())); + throw new NotImplementedException(); + //return CreatePageable((continuationToken, pageSize) + // => GetRuns(threadId, pageSize, resultOrder?.ToString(), continuationToken, null, cancellationToken.ToRequestOptions())); } /// @@ -898,8 +905,9 @@ public virtual AsyncPageCollection GetRunStepsAsync( Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); Argument.AssertNotNullOrEmpty(runId, nameof(runId)); - return CreateAsyncPageable((continuationToken, pageSize) - => GetRunStepsAsync(threadId, runId, pageSize, resultOrder?.ToString(), continuationToken, null, cancellationToken.ToRequestOptions())); + throw new NotImplementedException(); + //return CreateAsyncPageable((continuationToken, pageSize) + // => GetRunStepsAsync(threadId, runId, pageSize, resultOrder?.ToString(), continuationToken, null, cancellationToken.ToRequestOptions())); } /// @@ -922,8 +930,9 @@ public virtual PageCollection GetRunSteps( Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); Argument.AssertNotNullOrEmpty(runId, nameof(runId)); - return CreatePageable((continuationToken, pageSize) - => GetRunSteps(threadId, runId, pageSize, resultOrder?.ToString(), continuationToken, null, cancellationToken.ToRequestOptions())); + throw new NotImplementedException(); + //return CreatePageable((continuationToken, pageSize) + // => GetRunSteps(threadId, runId, pageSize, resultOrder?.ToString(), continuationToken, null, cancellationToken.ToRequestOptions())); } /// diff --git a/src/Custom/VectorStores/VectorStoreClient.cs b/src/Custom/VectorStores/VectorStoreClient.cs index cfb29ed62..4acbc19e6 100644 --- a/src/Custom/VectorStores/VectorStoreClient.cs +++ b/src/Custom/VectorStores/VectorStoreClient.cs @@ -150,8 +150,9 @@ public virtual ClientResult DeleteVectorStore(string vectorStoreId, Cancel /// public virtual AsyncPageCollection GetVectorStoresAsync(ListOrder? resultOrder = null, CancellationToken cancellationToken = default) { - return CreateAsyncPageable((continuationToken, pageSize) - => GetVectorStoresAsync(pageSize, resultOrder?.ToString(), continuationToken, null, cancellationToken.ToRequestOptions())); + throw new NotImplementedException(); + //return CreateAsyncPageable((continuationToken, pageSize) + // => GetVectorStoresAsync(pageSize, resultOrder?.ToString(), continuationToken, null, cancellationToken.ToRequestOptions())); } /// @@ -167,8 +168,10 @@ public virtual AsyncPageCollection GetVectorStoresAsync(ListOrder? /// public virtual PageCollection GetVectorStores(ListOrder? resultOrder = null, CancellationToken cancellationToken = default) { - return CreatePageable((continuationToken, pageSize) - => GetVectorStores(pageSize, resultOrder?.ToString(), continuationToken, null, cancellationToken.ToRequestOptions())); + throw new NotImplementedException(); + + //return CreatePageable((continuationToken, pageSize) + // => GetVectorStores(pageSize, resultOrder?.ToString(), continuationToken, null, cancellationToken.ToRequestOptions())); } /// @@ -233,9 +236,11 @@ public virtual AsyncPageCollection GetFileAssociatio CancellationToken cancellationToken = default) { Argument.AssertNotNullOrEmpty(vectorStoreId, nameof(vectorStoreId)); - return CreateAsyncPageable( - (continuationToken, pageSize) => GetFileAssociationsAsync( - vectorStoreId, pageSize, resultOrder?.ToString(), continuationToken, null, filter?.ToString(), cancellationToken.ToRequestOptions())); + + throw new NotImplementedException(); + //return CreateAsyncPageable( + // (continuationToken, pageSize) => GetFileAssociationsAsync( + // vectorStoreId, pageSize, resultOrder?.ToString(), continuationToken, null, filter?.ToString(), cancellationToken.ToRequestOptions())); } /// @@ -260,9 +265,11 @@ public virtual AsyncPageCollection GetFileAssociatio public virtual PageCollection GetFileAssociations(string vectorStoreId, ListOrder? resultOrder = null, VectorStoreFileStatusFilter? filter = null, CancellationToken cancellationToken = default) { Argument.AssertNotNullOrEmpty(vectorStoreId, nameof(vectorStoreId)); - return CreatePageable( - (continuationToken, pageSize) => GetFileAssociations( - vectorStoreId, pageSize, resultOrder?.ToString(), continuationToken, null, filter?.ToString(), cancellationToken.ToRequestOptions())); + + throw new NotImplementedException(); + //return CreatePageable( + // (continuationToken, pageSize) => GetFileAssociations( + // vectorStoreId, pageSize, resultOrder?.ToString(), continuationToken, null, filter?.ToString(), cancellationToken.ToRequestOptions())); } /// @@ -497,9 +504,10 @@ public virtual AsyncPageCollection GetFileAssociatio Argument.AssertNotNullOrEmpty(vectorStoreId, nameof(vectorStoreId)); Argument.AssertNotNullOrEmpty(batchJobId, nameof(batchJobId)); - return CreateAsyncPageable( - (continuationToken, pageSize) => GetFileAssociationsAsync - (vectorStoreId, batchJobId, pageSize, resultOrder?.ToString(), continuationToken, null, filter?.ToString(), cancellationToken.ToRequestOptions())); + throw new NotImplementedException(); + //return CreateAsyncPageable( + // (continuationToken, pageSize) => GetFileAssociationsAsync + // (vectorStoreId, batchJobId, pageSize, resultOrder?.ToString(), continuationToken, null, filter?.ToString(), cancellationToken.ToRequestOptions())); } /// @@ -534,8 +542,9 @@ public virtual PageCollection GetFileAssociations( Argument.AssertNotNullOrEmpty(vectorStoreId, nameof(vectorStoreId)); Argument.AssertNotNullOrEmpty(batchJobId, nameof(batchJobId)); - return CreatePageable( - (continuationToken, pageSize) => GetFileAssociations - (vectorStoreId, batchJobId, pageSize, resultOrder?.ToString(), continuationToken, null, filter?.ToString(), cancellationToken.ToRequestOptions())); + throw new NotImplementedException(); + //return CreatePageable( + // (continuationToken, pageSize) => GetFileAssociations + // (vectorStoreId, batchJobId, pageSize, resultOrder?.ToString(), continuationToken, null, filter?.ToString(), cancellationToken.ToRequestOptions())); } } From 17c4078974d7e93613cbbb934b0b84a367794ecc Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Tue, 25 Jun 2024 17:22:37 -0700 Subject: [PATCH 03/72] update page collection to use new page token contract --- .../Assistants/AssistantPageCollection.cs | 25 ++--- src/Custom/Common/OpenAIPageToken.cs | 92 ++++++++++++++++--- 2 files changed, 85 insertions(+), 32 deletions(-) diff --git a/src/Custom/Assistants/AssistantPageCollection.cs b/src/Custom/Assistants/AssistantPageCollection.cs index 159864d2a..229e2edb0 100644 --- a/src/Custom/Assistants/AssistantPageCollection.cs +++ b/src/Custom/Assistants/AssistantPageCollection.cs @@ -12,22 +12,11 @@ internal class AssistantPageCollection : PageCollection { private readonly AssistantClient _client; - private readonly int? _limit; - private readonly string? _order; - private readonly string? _after; - private readonly string? _before; - // service method constructor public AssistantPageCollection(AssistantClient client, int? limit, string? order, string? after, string? before) { _client = client; - - _limit = limit; - _order = order; - _after = after; - _before = before; - - FirstPageToken = BinaryData.FromString(after ?? string.Empty); + FirstPageToken = OpenAIPageToken.FromListOptions(limit, order, after, before); } public override BinaryData FirstPageToken { get; } @@ -37,18 +26,20 @@ public override ClientPage GetPage(BinaryData pageToken, RequestOptio OpenAIPageToken token = OpenAIPageToken.FromBytes(pageToken); ClientResult result = _client.GetAssistantsPage( - limit: _limit, - order: _order, + limit: token.Limit, + order: token.Order, after: token.After, - before: _before, + before: token.Before, options: options); PipelineResponse response = result.GetRawResponse(); InternalListAssistantsResponse list = ModelReaderWriter.Read(response.Content)!; - BinaryData? nextPageToken = OpenAIPageToken.GetNextPageToken(list.HasMore, list.LastId); + BinaryData? nextPageToken = OpenAIPageToken.GetNextPageToken( + token, + list.HasMore, + list.LastId); return ClientPage.Create(list.Data, pageToken, nextPageToken, response); } - } #pragma warning restore OPENAI001 \ No newline at end of file diff --git a/src/Custom/Common/OpenAIPageToken.cs b/src/Custom/Common/OpenAIPageToken.cs index 351bda711..66d532664 100644 --- a/src/Custom/Common/OpenAIPageToken.cs +++ b/src/Custom/Common/OpenAIPageToken.cs @@ -1,5 +1,7 @@ using System; -using System.ClientModel.Primitives; +using System.Diagnostics; +using System.IO; +using System.Text.Json; #nullable enable @@ -7,20 +9,15 @@ namespace OpenAI; internal class OpenAIPageToken { - public OpenAIPageToken(int? pageSize, - string? order, - string? after, - string? before, - string? lastSeenId) + public OpenAIPageToken(int? limit, string? order, string? after, string? before) { - PageSize = pageSize; + Limit = limit; Order = order; After = after; Before = before; - LastSeenId = lastSeenId; } - public int? PageSize { get; } + public int? Limit { get; } public string? Order { get; } @@ -28,25 +25,90 @@ public OpenAIPageToken(int? pageSize, public string? Before { get; } - public string? LastSeenId { get; } - public BinaryData ToBytes() { - throw new NotImplementedException(); + using MemoryStream stream = new(); + using Utf8JsonWriter writer = new(stream); + + if (Limit.HasValue) + { + writer.WriteNumber("limit", Limit.Value); + } + + if (Order is not null) + { + writer.WriteString("order", Order); + } + + if (After is not null) + { + writer.WriteString("after", After); + } + + if (Before is not null) + { + writer.WriteString("before", Before); + } + + writer.Flush(); + stream.Position = 0; + return BinaryData.FromStream(stream); } + public static BinaryData FromListOptions(int? limit, string? order, string? after, string? before) + => new OpenAIPageToken(limit, order, after, before).ToBytes(); + public static OpenAIPageToken FromBytes(BinaryData data) { - throw new NotImplementedException(); + Utf8JsonReader reader = new(data); + + int? limit = null; + string? order = null; + string? after = null; + string? before = null; + + while (reader.Read()) + { + Debug.Assert(reader.TokenType == JsonTokenType.PropertyName); + string propertyName = reader.GetString()!; + + switch (propertyName) + { + case "limit": + reader.Read(); + Debug.Assert(reader.TokenType == JsonTokenType.Number); + limit = reader.GetInt32(); + break; + case "order": + reader.Read(); + Debug.Assert(reader.TokenType == JsonTokenType.String); + order = reader.GetString(); + break; + case "after": + reader.Read(); + Debug.Assert(reader.TokenType == JsonTokenType.String); + after = reader.GetString(); + break; + case "before": + reader.Read(); + Debug.Assert(reader.TokenType == JsonTokenType.String); + before = reader.GetString(); + break; + default: + throw new JsonException($"Unrecognized property '{propertyName}'."); + } + } + + return new(limit, order, after, before); } - public static BinaryData? GetNextPageToken(bool hasMore, string? lastId) + public static BinaryData? GetNextPageToken(OpenAIPageToken token, bool hasMore, string? lastId) { if (!hasMore || lastId is null) { return null; } - throw new NotImplementedException(); + return new OpenAIPageToken(token.Limit, token.Order, lastId, token.Before).ToBytes(); } } \ No newline at end of file From 9cf0447f9f81f9a8d12606d1c222c41356a41691 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Tue, 25 Jun 2024 17:40:15 -0700 Subject: [PATCH 04/72] Update tests and samples --- .../Example01_RetrievalAugmentedGeneration.cs | 4 +- ...ple01_RetrievalAugmentedGenerationAsync.cs | 4 +- .../Assistants/Example02_FunctionCalling.cs | 4 +- .../Example02_FunctionCallingAsync.cs | 4 +- .../Example02b_FunctionCallingStreaming.cs | 3 +- .../Example03_ListAssistantsWithPagination.cs | 4 +- ...ple03_ListAssistantsWithPaginationAsync.cs | 4 +- examples/Assistants/Example04_AllTheTools.cs | 8 ++-- .../Example05_AssistantsWithVision.cs | 2 +- .../Example05_AssistantsWithVisionAsync.cs | 2 +- .../Chat/Example02_SimpleChatStreaming.cs | 2 +- .../Example02_SimpleChatStreamingAsync.cs | 2 +- .../Example04_FunctionCallingStreaming.cs | 2 +- ...Example04_FunctionCallingStreamingAsync.cs | 2 +- src/Custom/Assistants/AssistantClient.cs | 7 +++- tests/Assistants/AssistantTests.cs | 42 ++++++++++--------- tests/Assistants/VectorStoreTests.cs | 12 +++--- tests/Chat/ChatClientTests.cs | 10 ++--- 18 files changed, 61 insertions(+), 57 deletions(-) diff --git a/examples/Assistants/Example01_RetrievalAugmentedGeneration.cs b/examples/Assistants/Example01_RetrievalAugmentedGeneration.cs index fb9189ac9..9d792269d 100644 --- a/examples/Assistants/Example01_RetrievalAugmentedGeneration.cs +++ b/examples/Assistants/Example01_RetrievalAugmentedGeneration.cs @@ -98,10 +98,10 @@ public void Example01_RetrievalAugmentedGeneration() } while (!threadRun.Status.IsTerminal); // Finally, we'll print out the full history for the thread that includes the augmented generation - PageableCollection messages + PageCollection messages = assistantClient.GetMessages(threadRun.ThreadId, ListOrder.OldestFirst); - foreach (ThreadMessage message in messages) + foreach (ThreadMessage message in messages.GetAllValues()) { Console.Write($"[{message.Role.ToString().ToUpper()}]: "); foreach (MessageContent contentItem in message.Content) diff --git a/examples/Assistants/Example01_RetrievalAugmentedGenerationAsync.cs b/examples/Assistants/Example01_RetrievalAugmentedGenerationAsync.cs index 6cde83f33..03f1e7aff 100644 --- a/examples/Assistants/Example01_RetrievalAugmentedGenerationAsync.cs +++ b/examples/Assistants/Example01_RetrievalAugmentedGenerationAsync.cs @@ -99,10 +99,10 @@ public async Task Example01_RetrievalAugmentedGenerationAsync() } while (!threadRun.Status.IsTerminal); // Finally, we'll print out the full history for the thread that includes the augmented generation - AsyncPageableCollection messages + AsyncPageCollection messages = assistantClient.GetMessagesAsync(threadRun.ThreadId, ListOrder.OldestFirst); - await foreach (ThreadMessage message in messages) + await foreach (ThreadMessage message in messages.GetAllValuesAsync()) { Console.Write($"[{message.Role.ToString().ToUpper()}]: "); foreach (MessageContent contentItem in message.Content) diff --git a/examples/Assistants/Example02_FunctionCalling.cs b/examples/Assistants/Example02_FunctionCalling.cs index a60491379..50f62df73 100644 --- a/examples/Assistants/Example02_FunctionCalling.cs +++ b/examples/Assistants/Example02_FunctionCalling.cs @@ -151,10 +151,10 @@ string GetCurrentWeather(string location, string unit = "celsius") // With the run complete, list the messages and display their content if (run.Status == RunStatus.Completed) { - PageableCollection messages + PageCollection messages = client.GetMessages(run.ThreadId, resultOrder: ListOrder.OldestFirst); - foreach (ThreadMessage message in messages) + foreach (ThreadMessage message in messages.GetAllValues()) { Console.WriteLine($"[{message.Role.ToString().ToUpper()}]: "); foreach (MessageContent contentItem in message.Content) diff --git a/examples/Assistants/Example02_FunctionCallingAsync.cs b/examples/Assistants/Example02_FunctionCallingAsync.cs index 08bbd0bde..96d2e43eb 100644 --- a/examples/Assistants/Example02_FunctionCallingAsync.cs +++ b/examples/Assistants/Example02_FunctionCallingAsync.cs @@ -151,10 +151,10 @@ string GetCurrentWeather(string location, string unit = "celsius") // With the run complete, list the messages and display their content if (run.Status == RunStatus.Completed) { - AsyncPageableCollection messages + AsyncPageCollection messages = client.GetMessagesAsync(run.ThreadId, resultOrder: ListOrder.OldestFirst); - await foreach (ThreadMessage message in messages) + await foreach (ThreadMessage message in messages.GetAllValuesAsync()) { Console.WriteLine($"[{message.Role.ToString().ToUpper()}]: "); foreach (MessageContent contentItem in message.Content) diff --git a/examples/Assistants/Example02b_FunctionCallingStreaming.cs b/examples/Assistants/Example02b_FunctionCallingStreaming.cs index cb3bf7343..06ae7df7d 100644 --- a/examples/Assistants/Example02b_FunctionCallingStreaming.cs +++ b/examples/Assistants/Example02b_FunctionCallingStreaming.cs @@ -91,8 +91,7 @@ public async Task Example02b_FunctionCallingStreaming() #endregion #region Step 3 - Initiate a streaming run - // TODO: replace this with finalized enumerable result pattern - AsyncResultCollection asyncUpdates + AsyncResultValueCollection asyncUpdates = client.CreateRunStreamingAsync(thread, assistant); ThreadRun currentRun = null; diff --git a/examples/Assistants/Example03_ListAssistantsWithPagination.cs b/examples/Assistants/Example03_ListAssistantsWithPagination.cs index 1c49470c4..39533ccb9 100644 --- a/examples/Assistants/Example03_ListAssistantsWithPagination.cs +++ b/examples/Assistants/Example03_ListAssistantsWithPagination.cs @@ -1,7 +1,7 @@ using NUnit.Framework; using OpenAI.Assistants; using System; -using System.ClientModel; +using System.Collections.Generic; namespace OpenAI.Examples; @@ -16,7 +16,7 @@ public void Example03_ListAssistantsWithPagination() int count = 0; - PageableCollection assistants = client.GetAssistants(); + IEnumerable assistants = client.GetAssistants().GetAllValues(); foreach (Assistant assistant in assistants) { Console.WriteLine($"[{count,3}] {assistant.Id} {assistant.CreatedAt:s} {assistant.Name}"); diff --git a/examples/Assistants/Example03_ListAssistantsWithPaginationAsync.cs b/examples/Assistants/Example03_ListAssistantsWithPaginationAsync.cs index 145dcfeab..477e53add 100644 --- a/examples/Assistants/Example03_ListAssistantsWithPaginationAsync.cs +++ b/examples/Assistants/Example03_ListAssistantsWithPaginationAsync.cs @@ -1,7 +1,7 @@ using NUnit.Framework; using OpenAI.Assistants; using System; -using System.ClientModel; +using System.Collections.Generic; using System.Threading.Tasks; namespace OpenAI.Examples; @@ -17,7 +17,7 @@ public async Task Example03_ListAssistantsWithPaginationAsync() int count = 0; - AsyncPageableCollection assistants = client.GetAssistantsAsync(); + IAsyncEnumerable assistants = client.GetAssistantsAsync().GetAllValuesAsync(); await foreach (Assistant assistant in assistants) { Console.WriteLine($"[{count,3}] {assistant.Id} {assistant.CreatedAt:s} {assistant.Name}"); diff --git a/examples/Assistants/Example04_AllTheTools.cs b/examples/Assistants/Example04_AllTheTools.cs index 30c8fc9fd..bbaa45131 100644 --- a/examples/Assistants/Example04_AllTheTools.cs +++ b/examples/Assistants/Example04_AllTheTools.cs @@ -137,10 +137,10 @@ static string GetNameOfFamilyMember(string relation) // With the run complete, list the messages and display their content if (run.Status == RunStatus.Completed) { - PageableCollection messages + PageCollection messages = client.GetMessages(run.ThreadId, resultOrder: ListOrder.OldestFirst); - foreach (ThreadMessage message in messages) + foreach (ThreadMessage message in messages.GetAllValues()) { Console.WriteLine($"[{message.Role.ToString().ToUpper()}]: "); foreach (MessageContent contentItem in message.Content) @@ -171,8 +171,8 @@ PageableCollection messages #endregion #region List run steps for details about tool calls - PageableCollection runSteps = client.GetRunSteps(run, resultOrder: ListOrder.OldestFirst); - foreach (RunStep step in runSteps) + PageCollection runSteps = client.GetRunSteps(run, resultOrder: ListOrder.OldestFirst); + foreach (RunStep step in runSteps.GetAllValues()) { Console.WriteLine($"Run step: {step.Status}"); foreach (RunStepToolCall toolCall in step.Details.ToolCalls) diff --git a/examples/Assistants/Example05_AssistantsWithVision.cs b/examples/Assistants/Example05_AssistantsWithVision.cs index e73222261..f1e2a64a9 100644 --- a/examples/Assistants/Example05_AssistantsWithVision.cs +++ b/examples/Assistants/Example05_AssistantsWithVision.cs @@ -44,7 +44,7 @@ public void Example05_AssistantsWithVision() } }); - ResultCollection streamingUpdates = assistantClient.CreateRunStreaming( + ResultValueCollection streamingUpdates = assistantClient.CreateRunStreaming( thread, assistant, new RunCreationOptions() diff --git a/examples/Assistants/Example05_AssistantsWithVisionAsync.cs b/examples/Assistants/Example05_AssistantsWithVisionAsync.cs index 68e50ed50..df27d894d 100644 --- a/examples/Assistants/Example05_AssistantsWithVisionAsync.cs +++ b/examples/Assistants/Example05_AssistantsWithVisionAsync.cs @@ -45,7 +45,7 @@ public async Task Example05_AssistantsWithVisionAsync() } }); - AsyncResultCollection streamingUpdates = assistantClient.CreateRunStreamingAsync( + AsyncResultValueCollection streamingUpdates = assistantClient.CreateRunStreamingAsync( thread, assistant, new RunCreationOptions() diff --git a/examples/Chat/Example02_SimpleChatStreaming.cs b/examples/Chat/Example02_SimpleChatStreaming.cs index cad64d9b0..1c6c75c41 100644 --- a/examples/Chat/Example02_SimpleChatStreaming.cs +++ b/examples/Chat/Example02_SimpleChatStreaming.cs @@ -12,7 +12,7 @@ public void Example02_SimpleChatStreaming() { ChatClient client = new(model: "gpt-4o", Environment.GetEnvironmentVariable("OPENAI_API_KEY")); - ResultCollection updates + ResultValueCollection updates = client.CompleteChatStreaming("Say 'this is a test.'"); Console.WriteLine($"[ASSISTANT]:"); diff --git a/examples/Chat/Example02_SimpleChatStreamingAsync.cs b/examples/Chat/Example02_SimpleChatStreamingAsync.cs index 123b5e887..11afc0222 100644 --- a/examples/Chat/Example02_SimpleChatStreamingAsync.cs +++ b/examples/Chat/Example02_SimpleChatStreamingAsync.cs @@ -13,7 +13,7 @@ public async Task Example02_SimpleChatStreamingAsync() { ChatClient client = new(model: "gpt-4o", Environment.GetEnvironmentVariable("OPENAI_API_KEY")); - AsyncResultCollection updates + AsyncResultValueCollection updates = client.CompleteChatStreamingAsync("Say 'this is a test.'"); Console.WriteLine($"[ASSISTANT]:"); diff --git a/examples/Chat/Example04_FunctionCallingStreaming.cs b/examples/Chat/Example04_FunctionCallingStreaming.cs index e0e799d89..50ad08f31 100644 --- a/examples/Chat/Example04_FunctionCallingStreaming.cs +++ b/examples/Chat/Example04_FunctionCallingStreaming.cs @@ -38,7 +38,7 @@ public void Example04_FunctionCallingStreaming() Dictionary indexToFunctionName = []; Dictionary indexToFunctionArguments = []; StringBuilder contentBuilder = new(); - ResultCollection chatUpdates + ResultValueCollection chatUpdates = client.CompleteChatStreaming(messages, options); foreach (StreamingChatCompletionUpdate chatUpdate in chatUpdates) diff --git a/examples/Chat/Example04_FunctionCallingStreamingAsync.cs b/examples/Chat/Example04_FunctionCallingStreamingAsync.cs index dc3eae564..d585424a0 100644 --- a/examples/Chat/Example04_FunctionCallingStreamingAsync.cs +++ b/examples/Chat/Example04_FunctionCallingStreamingAsync.cs @@ -39,7 +39,7 @@ public async Task Example04_FunctionCallingStreamingAsync() Dictionary indexToFunctionName = []; Dictionary indexToFunctionArguments = []; StringBuilder contentBuilder = new(); - AsyncResultCollection chatUpdates + AsyncResultValueCollection chatUpdates = client.CompleteChatStreamingAsync(messages, options); await foreach (StreamingChatCompletionUpdate chatUpdate in chatUpdates) diff --git a/src/Custom/Assistants/AssistantClient.cs b/src/Custom/Assistants/AssistantClient.cs index 61f592c95..c842e4ee1 100644 --- a/src/Custom/Assistants/AssistantClient.cs +++ b/src/Custom/Assistants/AssistantClient.cs @@ -109,9 +109,12 @@ public virtual ClientResult CreateAssistant(string model, AssistantCr /// The order that results should appear in the list according to their created_at /// timestamp. /// + /// The number of values to return in a single page in the page collection. + /// The id of the item preceeding the first item in the collection. + /// The id of the item following the last item in the collection. /// A token that can be used to cancel this method call. /// A collection of assistants that can be enumerated using await foreach. - public virtual AsyncPageCollection GetAssistantsAsync(ListOrder? resultOrder = null, CancellationToken cancellationToken = default) + public virtual AsyncPageCollection GetAssistantsAsync(ListOrder? resultOrder = default, int? pageSize = default, string afterId = default, string beforeId = default, CancellationToken cancellationToken = default) { throw new NotImplementedException(); //return CreateAsyncPageable((continuationToken, pageSize) @@ -130,7 +133,7 @@ public virtual AsyncPageCollection GetAssistantsAsync(ListOrder? resu /// The id of the item following the last item in the collection. /// A token that can be used to cancel this method call. /// A collection of assistants that can be enumerated using foreach. - public virtual PageCollection GetAssistants(ListOrder? resultOrder, int? pageSize, string afterId = default, string beforeId = default, CancellationToken cancellationToken = default) + public virtual PageCollection GetAssistants(ListOrder? resultOrder = default, int? pageSize = default, string afterId = default, string beforeId = default, CancellationToken cancellationToken = default) { return new AssistantPageCollection(this, pageSize, resultOrder?.ToString(), afterId, beforeId); } diff --git a/tests/Assistants/AssistantTests.cs b/tests/Assistants/AssistantTests.cs index 8ee92f319..f0066fb8f 100644 --- a/tests/Assistants/AssistantTests.cs +++ b/tests/Assistants/AssistantTests.cs @@ -51,7 +51,7 @@ public void BasicAssistantOperationsWork() }, }); Assert.That(modifiedAssistant.Id, Is.EqualTo(assistant.Id)); - PageableCollection recentAssistants = client.GetAssistants(); + IEnumerable recentAssistants = client.GetAssistants().GetAllValues(); Assistant listedAssistant = recentAssistants.FirstOrDefault(pageItem => pageItem.Id == assistant.Id); Assert.That(listedAssistant, Is.Not.Null); Assert.That(listedAssistant.Metadata.TryGetValue(s_cleanupMetadataKey, out string newMetadataValue) && newMetadataValue == "goodbye!"); @@ -128,7 +128,7 @@ public void BasicMessageOperationsWork() }); Assert.That(message.Metadata.TryGetValue("messageMetadata", out metadataValue) && metadataValue == "newValue"); - PageableCollection messagePage = client.GetMessages(thread); + IEnumerable messagePage = client.GetMessages(thread).GetAllValues(); Assert.That(messagePage.Count, Is.EqualTo(1)); Assert.That(messagePage.First().Id, Is.EqualTo(message.Id)); Assert.That(messagePage.First().Metadata.TryGetValue("messageMetadata", out metadataValue) && metadataValue == "newValue"); @@ -159,7 +159,7 @@ public void ThreadWithInitialMessagesWorks() }; AssistantThread thread = client.CreateThread(options); Validate(thread); - PageableCollection messages = client.GetMessages(thread, resultOrder: ListOrder.OldestFirst); + IEnumerable messages = client.GetMessages(thread, resultOrder: ListOrder.OldestFirst).GetAllValues(); Assert.That(messages.Count, Is.EqualTo(2)); Assert.That(messages.First().Role, Is.EqualTo(MessageRole.User)); Assert.That(messages.First().Content?.Count, Is.EqualTo(1)); @@ -179,7 +179,7 @@ public void BasicRunOperationsWork() Validate(assistant); AssistantThread thread = client.CreateThread(); Validate(thread); - PageableCollection runs = client.GetRuns(thread); + IEnumerable runs = client.GetRuns(thread).GetAllValues(); Assert.That(runs.Count, Is.EqualTo(0)); ThreadMessage message = client.CreateMessage(thread.Id, MessageRole.User, ["Hello, assistant!"]); Validate(message); @@ -189,11 +189,11 @@ public void BasicRunOperationsWork() Assert.That(run.CreatedAt, Is.GreaterThan(s_2024)); ThreadRun retrievedRun = client.GetRun(thread.Id, run.Id); Assert.That(retrievedRun.Id, Is.EqualTo(run.Id)); - runs = client.GetRuns(thread); + runs = client.GetRuns(thread).GetAllValues(); Assert.That(runs.Count, Is.EqualTo(1)); Assert.That(runs.First().Id, Is.EqualTo(run.Id)); - PageableCollection messages = client.GetMessages(thread); + IEnumerable messages = client.GetMessages(thread).GetAllValues(); Assert.That(messages.Count, Is.GreaterThanOrEqualTo(1)); for (int i = 0; i < 10 && !run.Status.IsTerminal; i++) { @@ -207,7 +207,7 @@ public void BasicRunOperationsWork() Assert.That(run.FailedAt, Is.Null); Assert.That(run.IncompleteDetails, Is.Null); - messages = client.GetMessages(thread); + messages = client.GetMessages(thread).GetAllValues(); Assert.That(messages.Count, Is.EqualTo(2)); Assert.That(messages.ElementAt(0).Role, Is.EqualTo(MessageRole.Assistant)); @@ -267,7 +267,10 @@ public void BasicRunStepFunctionalityWorks() Assert.That(run.Status, Is.EqualTo(RunStatus.Completed)); Assert.That(run.Usage?.TotalTokens, Is.GreaterThan(0)); - PageableCollection runSteps = client.GetRunSteps(run); + PageCollection pages = client.GetRunSteps(run); + ClientPage firstPage = pages.First(); + + IEnumerable runSteps = pages.GetAllValues(); Assert.That(runSteps.Count, Is.GreaterThan(1)); Assert.Multiple(() => { @@ -280,7 +283,7 @@ public void BasicRunStepFunctionalityWorks() RunStepDetails details = runSteps.First().Details; Assert.That(details?.CreatedMessageId, Is.Not.Null.And.Not.Empty); - string rawContent = runSteps.GetRawResponse().Content.ToString(); + string rawContent = firstPage.GetRawResponse().Content.ToString(); details = runSteps.ElementAt(1).Details; Assert.Multiple(() => { @@ -387,7 +390,7 @@ public void FunctionToolsWork() } Assert.That(run.Status, Is.EqualTo(RunStatus.Completed)); - PageableCollection messages = client.GetMessages(run.ThreadId, resultOrder: ListOrder.NewestFirst); + IEnumerable messages = client.GetMessages(run.ThreadId, resultOrder: ListOrder.NewestFirst).GetAllValues(); Assert.That(messages.Count, Is.GreaterThan(1)); Assert.That(messages.First().Role, Is.EqualTo(MessageRole.Assistant)); Assert.That(messages.First().Content?[0], Is.Not.Null); @@ -410,7 +413,7 @@ public async Task StreamingRunWorks() Stopwatch stopwatch = Stopwatch.StartNew(); void Print(string message) => Console.WriteLine($"[{stopwatch.ElapsedMilliseconds,6}] {message}"); - AsyncResultCollection streamingResult + AsyncResultValueCollection streamingResult = client.CreateRunStreamingAsync(thread.Id, assistant.Id); Print(">>> Connected <<<"); @@ -457,7 +460,7 @@ public async Task StreamingToolCall() void Print(string message) => Console.WriteLine($"[{stopwatch.ElapsedMilliseconds,6}] {message}"); Print(" >>> Beginning call ... "); - AsyncResultCollection asyncResults = client.CreateThreadAndRunStreamingAsync( + AsyncResultValueCollection asyncResults = client.CreateThreadAndRunStreamingAsync( assistant, new() { @@ -596,7 +599,7 @@ This file describes the favorite foods of several people. } while (run?.Status.IsTerminal == false); Assert.That(run.Status, Is.EqualTo(RunStatus.Completed)); - PageableCollection messages = client.GetMessages(thread, resultOrder: ListOrder.NewestFirst); + IEnumerable messages = client.GetMessages(thread, resultOrder: ListOrder.NewestFirst).GetAllValues(); foreach (ThreadMessage message in messages) { foreach (MessageContent content in message.Content) @@ -630,7 +633,7 @@ public async Task CanEnumerateAssistants() // Page through collection int count = 0; - AsyncPageableCollection assistants = client.GetAssistantsAsync(ListOrder.NewestFirst); + IAsyncEnumerable assistants = client.GetAssistantsAsync(ListOrder.NewestFirst).GetAllValuesAsync(); int lastIdSeen = int.MaxValue; @@ -672,14 +675,13 @@ public async Task CanPageThroughAssistantCollection() // Page through collection int count = 0; int pageCount = 0; - AsyncPageableCollection assistants = client.GetAssistantsAsync(ListOrder.NewestFirst); - IAsyncEnumerable> pages = assistants.AsPages(pageSizeHint: 2); - + AsyncPageCollection pages = client.GetAssistantsAsync(ListOrder.NewestFirst, pageSize: 2); + int lastIdSeen = int.MaxValue; - await foreach (ResultPage page in pages) + await foreach (ClientPage page in pages) { - foreach (Assistant assistant in page) + foreach (Assistant assistant in page.Values) { Console.WriteLine($"[{count,3}] {assistant.Id} {assistant.CreatedAt:s} {assistant.Name}"); if (assistant.Name?.StartsWith("Test Assistant ") == true) @@ -721,7 +723,7 @@ public async Task MessagesWithRoles() async Task RefreshMessageListAsync() { messages.Clear(); - await foreach (ThreadMessage message in client.GetMessagesAsync(thread)) + await foreach (ThreadMessage message in client.GetMessagesAsync(thread).GetAllValuesAsync()) { messages.Add(message); } diff --git a/tests/Assistants/VectorStoreTests.cs b/tests/Assistants/VectorStoreTests.cs index 8377f7d2a..7834b7592 100644 --- a/tests/Assistants/VectorStoreTests.cs +++ b/tests/Assistants/VectorStoreTests.cs @@ -102,7 +102,7 @@ public void CanEnumerateVectorStores() int lastIdSeen = int.MaxValue; int count = 0; - foreach (VectorStore vectorStore in client.GetVectorStores(ListOrder.NewestFirst)) + foreach (VectorStore vectorStore in client.GetVectorStores(ListOrder.NewestFirst).GetAllValues()) { Assert.That(vectorStore.Id, Is.Not.Null); if (vectorStore.Name?.StartsWith("Test Vector Store ") == true) @@ -139,7 +139,7 @@ public async Task CanEnumerateVectorStoresAsync() int lastIdSeen = int.MaxValue; int count = 0; - await foreach (VectorStore vectorStore in client.GetVectorStoresAsync(ListOrder.NewestFirst)) + await foreach (VectorStore vectorStore in client.GetVectorStoresAsync(ListOrder.NewestFirst).GetAllValuesAsync()) { Assert.That(vectorStore.Id, Is.Not.Null); if (vectorStore.Name?.StartsWith("Test Vector Store ") == true) @@ -190,7 +190,7 @@ public void CanAssociateFiles() Thread.Sleep(1000); int count = 0; - foreach (VectorStoreFileAssociation association in client.GetFileAssociations(vectorStore)) + foreach (VectorStoreFileAssociation association in client.GetFileAssociations(vectorStore).GetAllValues()) { count++; Assert.That(association.FileId, Is.Not.EqualTo(files[0].Id)); @@ -223,7 +223,7 @@ public void CanUseBatchIngestion() Thread.Sleep(500); } - foreach (VectorStoreFileAssociation association in client.GetFileAssociations(batchJob)) + foreach (VectorStoreFileAssociation association in client.GetFileAssociations(batchJob).GetAllValues()) { Assert.Multiple(() => { @@ -269,9 +269,9 @@ public async Task CanApplyChunkingStrategy(ChunkingStrategyKind strategyKind) Validate(vectorStore); Assert.That(vectorStore.FileCounts.Total, Is.EqualTo(5)); - AsyncPageableCollection associations = client.GetFileAssociationsAsync(vectorStore); + AsyncPageCollection associations = client.GetFileAssociationsAsync(vectorStore); - await foreach (VectorStoreFileAssociation association in associations) + await foreach (VectorStoreFileAssociation association in associations.GetAllValuesAsync()) { Assert.That(testFiles.Any(file => file.Id == association.FileId), Is.True); Assert.That(association.ChunkingStrategy, Is.InstanceOf()); diff --git a/tests/Chat/ChatClientTests.cs b/tests/Chat/ChatClientTests.cs index 7929d2b71..269015590 100644 --- a/tests/Chat/ChatClientTests.cs +++ b/tests/Chat/ChatClientTests.cs @@ -76,8 +76,8 @@ public void StreamingChat() TimeSpan? latestTokenReceiptTime = null; Stopwatch stopwatch = Stopwatch.StartNew(); - ResultCollection streamingResult = client.CompleteChatStreaming(messages); - Assert.That(streamingResult, Is.InstanceOf>()); + ResultValueCollection streamingResult = client.CompleteChatStreaming(messages); + Assert.That(streamingResult, Is.InstanceOf>()); int updateCount = 0; foreach (StreamingChatCompletionUpdate chatUpdate in streamingResult) @@ -108,8 +108,8 @@ public async Task StreamingChatAsync() TimeSpan? latestTokenReceiptTime = null; Stopwatch stopwatch = Stopwatch.StartNew(); - AsyncResultCollection streamingResult = client.CompleteChatStreamingAsync(messages); - Assert.That(streamingResult, Is.InstanceOf>()); + AsyncResultValueCollection streamingResult = client.CompleteChatStreamingAsync(messages); + Assert.That(streamingResult, Is.InstanceOf>()); int updateCount = 0; ChatTokenUsage usage = null; @@ -336,7 +336,7 @@ public async Task TokenLogProbabilitiesStreaming(bool includeLogProbabilities) options = new(); } - AsyncResultCollection chatCompletionUpdates = client.CompleteChatStreamingAsync(messages, options); + AsyncResultValueCollection chatCompletionUpdates = client.CompleteChatStreamingAsync(messages, options); Assert.That(chatCompletionUpdates, Is.Not.Null); await foreach (StreamingChatCompletionUpdate chatCompletionUpdate in chatCompletionUpdates) From 7679061d333b529782380f1d26fa08cf5326acc6 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Tue, 25 Jun 2024 18:00:25 -0700 Subject: [PATCH 05/72] fix page token serialization logic --- .../Assistants/AssistantClient.Protocol.cs | 4 +--- src/Custom/Assistants/AssistantClient.cs | 8 +++----- src/Custom/Common/OpenAIPageToken.cs | 17 +++++++++++++++++ tests/Assistants/AssistantTests.cs | 3 ++- 4 files changed, 23 insertions(+), 9 deletions(-) diff --git a/src/Custom/Assistants/AssistantClient.Protocol.cs b/src/Custom/Assistants/AssistantClient.Protocol.cs index 0ce420320..cfabe0472 100644 --- a/src/Custom/Assistants/AssistantClient.Protocol.cs +++ b/src/Custom/Assistants/AssistantClient.Protocol.cs @@ -97,9 +97,7 @@ public virtual IAsyncEnumerable GetAssistantsAsync(int? limit, str /// Service returned a non-success status code. /// The response returned from the service. public virtual IEnumerable GetAssistants(int? limit, string order, string after, string before, RequestOptions options) - { - return new ProtocolAssistantPageCollection(this, limit, order, after, before, options); - } + => new ProtocolAssistantPageCollection(this, limit, order, after, before, options); // This needs to be internal now internal virtual ClientResult GetAssistantsPage(int? limit, string order, string after, string before, RequestOptions options) diff --git a/src/Custom/Assistants/AssistantClient.cs b/src/Custom/Assistants/AssistantClient.cs index c842e4ee1..40e5f702d 100644 --- a/src/Custom/Assistants/AssistantClient.cs +++ b/src/Custom/Assistants/AssistantClient.cs @@ -134,9 +134,7 @@ public virtual AsyncPageCollection GetAssistantsAsync(ListOrder? resu /// A token that can be used to cancel this method call. /// A collection of assistants that can be enumerated using foreach. public virtual PageCollection GetAssistants(ListOrder? resultOrder = default, int? pageSize = default, string afterId = default, string beforeId = default, CancellationToken cancellationToken = default) - { - return new AssistantPageCollection(this, pageSize, resultOrder?.ToString(), afterId, beforeId); - } + => new AssistantPageCollection(this, pageSize, resultOrder?.ToString(), afterId, beforeId); /// /// Deletes an existing . @@ -295,7 +293,7 @@ public virtual async Task> CreateMessageAsync( string threadId, MessageRole role, IEnumerable content, - MessageCreationOptions options = null, + MessageCreationOptions options = null, CancellationToken cancellationToken = default) { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); @@ -646,7 +644,7 @@ public virtual AsyncResultValueCollection CreateThreadAndRunStr runOptions.Stream = true; BinaryContent protocolContent = CreateThreadAndRunProtocolContent(assistantId, threadOptions, runOptions); - async Task getResultAsync() => + async Task getResultAsync() => await CreateThreadAndRunAsync(protocolContent, cancellationToken.ToRequestOptions(streaming: true)) .ConfigureAwait(false); diff --git a/src/Custom/Common/OpenAIPageToken.cs b/src/Custom/Common/OpenAIPageToken.cs index 66d532664..d5a955bcc 100644 --- a/src/Custom/Common/OpenAIPageToken.cs +++ b/src/Custom/Common/OpenAIPageToken.cs @@ -30,6 +30,8 @@ public BinaryData ToBytes() using MemoryStream stream = new(); using Utf8JsonWriter writer = new(stream); + writer.WriteStartObject(); + if (Limit.HasValue) { writer.WriteNumber("limit", Limit.Value); @@ -50,6 +52,8 @@ public BinaryData ToBytes() writer.WriteString("before", Before); } + writer.WriteEndObject(); + writer.Flush(); stream.Position = 0; return BinaryData.FromStream(stream); @@ -60,6 +64,11 @@ public static BinaryData FromListOptions(int? limit, string? order, string? afte public static OpenAIPageToken FromBytes(BinaryData data) { + if (data.ToMemory().Length == 0) + { + return new(default, default, default, default); + } + Utf8JsonReader reader = new(data); int? limit = null; @@ -67,8 +76,16 @@ public static OpenAIPageToken FromBytes(BinaryData data) string? after = null; string? before = null; + reader.Read(); + Debug.Assert(reader.TokenType == JsonTokenType.StartObject); + while (reader.Read()) { + if (reader.TokenType == JsonTokenType.EndObject) + { + break; + } + Debug.Assert(reader.TokenType == JsonTokenType.PropertyName); string propertyName = reader.GetString()!; diff --git a/tests/Assistants/AssistantTests.cs b/tests/Assistants/AssistantTests.cs index f0066fb8f..8ca0bf352 100644 --- a/tests/Assistants/AssistantTests.cs +++ b/tests/Assistants/AssistantTests.cs @@ -51,7 +51,8 @@ public void BasicAssistantOperationsWork() }, }); Assert.That(modifiedAssistant.Id, Is.EqualTo(assistant.Id)); - IEnumerable recentAssistants = client.GetAssistants().GetAllValues(); + PageCollection pages = client.GetAssistants(); + IEnumerable recentAssistants = pages.GetAllValues(); Assistant listedAssistant = recentAssistants.FirstOrDefault(pageItem => pageItem.Id == assistant.Id); Assert.That(listedAssistant, Is.Not.Null); Assert.That(listedAssistant.Metadata.TryGetValue(s_cleanupMetadataKey, out string newMetadataValue) && newMetadataValue == "goodbye!"); From 6acd48b491b654f5835f18a400778354b7594f57 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Tue, 25 Jun 2024 18:08:48 -0700 Subject: [PATCH 06/72] add async page collections --- .../Assistants/AssistantClient.Protocol.cs | 9 +-- src/Custom/Assistants/AssistantClient.cs | 6 +- .../AsyncAssistantPageCollection.Protocol.cs | 61 +++++++++++++++++++ .../AsyncAssistantPageCollection.cs | 46 ++++++++++++++ 4 files changed, 113 insertions(+), 9 deletions(-) create mode 100644 src/Custom/Assistants/AsyncAssistantPageCollection.Protocol.cs create mode 100644 src/Custom/Assistants/AsyncAssistantPageCollection.cs diff --git a/src/Custom/Assistants/AssistantClient.Protocol.cs b/src/Custom/Assistants/AssistantClient.Protocol.cs index cfabe0472..4f1d6193a 100644 --- a/src/Custom/Assistants/AssistantClient.Protocol.cs +++ b/src/Custom/Assistants/AssistantClient.Protocol.cs @@ -65,11 +65,12 @@ public virtual ClientResult CreateAssistant(BinaryContent content, RequestOption /// Service returned a non-success status code. /// The response returned from the service. public virtual IAsyncEnumerable GetAssistantsAsync(int? limit, string order, string after, string before, RequestOptions options) + => new AsyncProtocolAssistantPageCollection(this, limit, order, after, before, options); + + internal virtual async Task GetAssistantsPageAsync(int? limit, string order, string after, string before, RequestOptions options) { - throw new NotImplementedException(); - //return new ProtocolAssistantPageCollection(this, limit, order, after, before, options); - //using PipelineMessage message = CreateGetAssistantsRequest(limit, order, after, before, options); - //return ClientResult.FromResponse(await _pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); + using PipelineMessage message = CreateGetAssistantsRequest(limit, order, after, before, options); + return ClientResult.FromResponse(await _pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); } /// diff --git a/src/Custom/Assistants/AssistantClient.cs b/src/Custom/Assistants/AssistantClient.cs index 40e5f702d..ab57549e9 100644 --- a/src/Custom/Assistants/AssistantClient.cs +++ b/src/Custom/Assistants/AssistantClient.cs @@ -115,11 +115,7 @@ public virtual ClientResult CreateAssistant(string model, AssistantCr /// A token that can be used to cancel this method call. /// A collection of assistants that can be enumerated using await foreach. public virtual AsyncPageCollection GetAssistantsAsync(ListOrder? resultOrder = default, int? pageSize = default, string afterId = default, string beforeId = default, CancellationToken cancellationToken = default) - { - throw new NotImplementedException(); - //return CreateAsyncPageable((continuationToken, pageSize) - // => GetAssistantsAsync(pageSize, resultOrder?.ToString(), continuationToken, null, cancellationToken.ToRequestOptions())); - } + => new AsyncAssistantPageCollection(this, pageSize, resultOrder?.ToString(), afterId, beforeId); /// /// Returns a collection of instances. diff --git a/src/Custom/Assistants/AsyncAssistantPageCollection.Protocol.cs b/src/Custom/Assistants/AsyncAssistantPageCollection.Protocol.cs new file mode 100644 index 000000000..4ea89b3a4 --- /dev/null +++ b/src/Custom/Assistants/AsyncAssistantPageCollection.Protocol.cs @@ -0,0 +1,61 @@ +using OpenAI.Assistants; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; +using System.Threading; + +#nullable enable + +namespace OpenAI; + +#pragma warning disable OPENAI001 +internal class AsyncProtocolAssistantPageCollection : IAsyncEnumerable +{ + private readonly AssistantClient _client; + + private readonly int? _limit; + private readonly string? _order; + private readonly string? _after; + private readonly string? _before; + + private readonly RequestOptions? _options; + + public AsyncProtocolAssistantPageCollection(AssistantClient client, int? limit, string order, string after, string before, RequestOptions options) + { + _client = client; + + _limit = limit; + _order = order; + _after = after; + _before = before; + + _options = options; + } + + public async IAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + + string? after = _after; + bool hasMore = false; + + do + { + ClientResult result = await _client.GetAssistantsPageAsync( + limit: _limit, + order: _order, + after: after, + before: _before, + options: _options).ConfigureAwait(false); + + yield return result; + + PipelineResponse response = result.GetRawResponse(); + using JsonDocument doc = JsonDocument.Parse(response.Content); + hasMore = doc.RootElement.GetProperty("has_more"u8).GetBoolean(); + after = doc.RootElement.GetProperty("last_id"u8).GetString(); + + } while (hasMore); + } +} +#pragma warning restore OPENAI001 \ No newline at end of file diff --git a/src/Custom/Assistants/AsyncAssistantPageCollection.cs b/src/Custom/Assistants/AsyncAssistantPageCollection.cs new file mode 100644 index 000000000..304b4fa33 --- /dev/null +++ b/src/Custom/Assistants/AsyncAssistantPageCollection.cs @@ -0,0 +1,46 @@ +using OpenAI.Assistants; +using System.ClientModel; +using System.ClientModel.Primitives; +using System; +using System.Threading.Tasks; + +#nullable enable + +namespace OpenAI; + +#pragma warning disable OPENAI001 +internal class AsyncAssistantPageCollection : AsyncPageCollection +{ + private readonly AssistantClient _client; + + // service method constructor + public AsyncAssistantPageCollection(AssistantClient client, int? limit, string? order, string? after, string? before) + { + _client = client; + FirstPageToken = OpenAIPageToken.FromListOptions(limit, order, after, before); + } + + public override BinaryData FirstPageToken { get; } + + public override async Task> GetPageAsync(BinaryData pageToken, RequestOptions? options) + { + OpenAIPageToken token = OpenAIPageToken.FromBytes(pageToken); + + ClientResult result = await _client.GetAssistantsPageAsync( + limit: token.Limit, + order: token.Order, + after: token.After, + before: token.Before, + options: options).ConfigureAwait(false); + + PipelineResponse response = result.GetRawResponse(); + InternalListAssistantsResponse list = ModelReaderWriter.Read(response.Content)!; + + BinaryData? nextPageToken = OpenAIPageToken.GetNextPageToken( + token, + list.HasMore, + list.LastId); + return ClientPage.Create(list.Data, pageToken, nextPageToken, response); + } +} +#pragma warning restore OPENAI001 \ No newline at end of file From 6327af659b6e879a15ee92022c1b09529660cf5e Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Tue, 25 Jun 2024 18:17:22 -0700 Subject: [PATCH 07/72] Add rehydration overload --- src/Custom/Assistants/AssistantClient.cs | 9 +++++++++ src/Custom/Assistants/AssistantPageCollection.cs | 6 ++++++ 2 files changed, 15 insertions(+) diff --git a/src/Custom/Assistants/AssistantClient.cs b/src/Custom/Assistants/AssistantClient.cs index ab57549e9..7ecbd101c 100644 --- a/src/Custom/Assistants/AssistantClient.cs +++ b/src/Custom/Assistants/AssistantClient.cs @@ -132,6 +132,15 @@ public virtual AsyncPageCollection GetAssistantsAsync(ListOrder? resu public virtual PageCollection GetAssistants(ListOrder? resultOrder = default, int? pageSize = default, string afterId = default, string beforeId = default, CancellationToken cancellationToken = default) => new AssistantPageCollection(this, pageSize, resultOrder?.ToString(), afterId, beforeId); + /// + /// Rehydrates a collection of instances. + /// + /// Page token indicating the first page of the collection to rehydrate. + /// A token that can be used to cancel this method call. + /// A collection of assistants that can be enumerated using foreach. + public virtual PageCollection GetAssistants(BinaryData firstPageToken, CancellationToken cancellationToken = default) + => new AssistantPageCollection(this, firstPageToken); + /// /// Deletes an existing . /// diff --git a/src/Custom/Assistants/AssistantPageCollection.cs b/src/Custom/Assistants/AssistantPageCollection.cs index 229e2edb0..f41fd1a26 100644 --- a/src/Custom/Assistants/AssistantPageCollection.cs +++ b/src/Custom/Assistants/AssistantPageCollection.cs @@ -19,6 +19,12 @@ public AssistantPageCollection(AssistantClient client, int? limit, string? order FirstPageToken = OpenAIPageToken.FromListOptions(limit, order, after, before); } + public AssistantPageCollection(AssistantClient client, BinaryData firstPageToken) + { + _client = client; + FirstPageToken = firstPageToken; + } + public override BinaryData FirstPageToken { get; } public override ClientPage GetPage(BinaryData pageToken, RequestOptions? options) From e0c14ebca316ff4acffe7776114f4527a5487428 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Tue, 25 Jun 2024 18:19:32 -0700 Subject: [PATCH 08/72] Add async rehydration overload --- src/Custom/Assistants/AssistantClient.cs | 9 +++++++++ src/Custom/Assistants/AssistantPageCollection.cs | 1 + src/Custom/Assistants/AsyncAssistantPageCollection.cs | 7 +++++++ 3 files changed, 17 insertions(+) diff --git a/src/Custom/Assistants/AssistantClient.cs b/src/Custom/Assistants/AssistantClient.cs index 7ecbd101c..93069f2eb 100644 --- a/src/Custom/Assistants/AssistantClient.cs +++ b/src/Custom/Assistants/AssistantClient.cs @@ -117,6 +117,15 @@ public virtual ClientResult CreateAssistant(string model, AssistantCr public virtual AsyncPageCollection GetAssistantsAsync(ListOrder? resultOrder = default, int? pageSize = default, string afterId = default, string beforeId = default, CancellationToken cancellationToken = default) => new AsyncAssistantPageCollection(this, pageSize, resultOrder?.ToString(), afterId, beforeId); + /// + /// Rehydrates a collection of instances. + /// + /// Page token indicating the first page of the collection to rehydrate. + /// A token that can be used to cancel this method call. + /// A collection of assistants that can be enumerated using await foreach. + public virtual AsyncPageCollection GetAssistantsAsync(BinaryData firstPageToken, CancellationToken cancellationToken = default) + => new AsyncAssistantPageCollection(this, firstPageToken); + /// /// Returns a collection of instances. /// diff --git a/src/Custom/Assistants/AssistantPageCollection.cs b/src/Custom/Assistants/AssistantPageCollection.cs index f41fd1a26..36e6dbd9a 100644 --- a/src/Custom/Assistants/AssistantPageCollection.cs +++ b/src/Custom/Assistants/AssistantPageCollection.cs @@ -19,6 +19,7 @@ public AssistantPageCollection(AssistantClient client, int? limit, string? order FirstPageToken = OpenAIPageToken.FromListOptions(limit, order, after, before); } + // rehydration constructor public AssistantPageCollection(AssistantClient client, BinaryData firstPageToken) { _client = client; diff --git a/src/Custom/Assistants/AsyncAssistantPageCollection.cs b/src/Custom/Assistants/AsyncAssistantPageCollection.cs index 304b4fa33..c12f34915 100644 --- a/src/Custom/Assistants/AsyncAssistantPageCollection.cs +++ b/src/Custom/Assistants/AsyncAssistantPageCollection.cs @@ -20,6 +20,13 @@ public AsyncAssistantPageCollection(AssistantClient client, int? limit, string? FirstPageToken = OpenAIPageToken.FromListOptions(limit, order, after, before); } + // rehydration constructor + public AsyncAssistantPageCollection(AssistantClient client, BinaryData firstPageToken) + { + _client = client; + FirstPageToken = firstPageToken; + } + public override BinaryData FirstPageToken { get; } public override async Task> GetPageAsync(BinaryData pageToken, RequestOptions? options) From 2d46435d51db629a360ec99fd923f47723afaaf7 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Wed, 26 Jun 2024 09:53:49 -0700 Subject: [PATCH 09/72] backup WIP on generalized implementation --- .../Assistants/AssistantPageCollection.cs | 1 + src/Custom/Common/InternalListHelpers.cs | 77 +++++++++------ .../Common/OpenAIPageCollectionHelpers.cs | 22 +++++ src/Custom/Common/PageCollectionHelpers.cs | 51 ++++++++++ src/Custom/Common/PageableResultHelpers.cs | 93 ------------------- 5 files changed, 121 insertions(+), 123 deletions(-) create mode 100644 src/Custom/Common/OpenAIPageCollectionHelpers.cs create mode 100644 src/Custom/Common/PageCollectionHelpers.cs delete mode 100644 src/Custom/Common/PageableResultHelpers.cs diff --git a/src/Custom/Assistants/AssistantPageCollection.cs b/src/Custom/Assistants/AssistantPageCollection.cs index 36e6dbd9a..6b34b9ad7 100644 --- a/src/Custom/Assistants/AssistantPageCollection.cs +++ b/src/Custom/Assistants/AssistantPageCollection.cs @@ -46,6 +46,7 @@ public override ClientPage GetPage(BinaryData pageToken, RequestOptio token, list.HasMore, list.LastId); + return ClientPage.Create(list.Data, pageToken, nextPageToken, response); } } diff --git a/src/Custom/Common/InternalListHelpers.cs b/src/Custom/Common/InternalListHelpers.cs index 46372992f..ffb78f225 100644 --- a/src/Custom/Common/InternalListHelpers.cs +++ b/src/Custom/Common/InternalListHelpers.cs @@ -1,37 +1,54 @@ +using System; using System.ClientModel; using System.ClientModel.Primitives; using System.Runtime.CompilerServices; using System.Threading.Tasks; +#nullable enable + namespace OpenAI; -//internal static class InternalListHelpers -//{ -// internal delegate Task AsyncListResponseFunc(string continuationToken, int? pageSize); -// internal delegate ClientResult ListResponseFunc(string continuationToken, int? pageSize); - -// internal static AsyncPageCollection CreateAsyncPageable(AsyncListResponseFunc listResponseFunc) -// where U : IJsonModel, IInternalListResponse -// { -// async Task> pageFunc(string continuationToken, int? pageSize) -// => GetPageFromProtocol(await listResponseFunc(continuationToken, pageSize).ConfigureAwait(false)); -// return PageableResultHelpers.Create((pageSize) => pageFunc(null, pageSize), pageFunc); -// } - -// internal static PageCollection CreatePageable(ListResponseFunc listResponseFunc) -// where U : IJsonModel, IInternalListResponse -// { -// ClientPage pageFunc(string continuationToken, int? pageSize) -// => GetPageFromProtocol(listResponseFunc(continuationToken, pageSize)); -// return PageableResultHelpers.Create((pageSize) => pageFunc(null, pageSize), pageFunc); -// } - -// [MethodImpl(MethodImplOptions.AggressiveInlining)] -// private static ClientPage GetPageFromProtocol(ClientResult protocolResult) -// where UInternalList : IJsonModel, IInternalListResponse -// { -// PipelineResponse response = protocolResult.GetRawResponse(); -// IInternalListResponse values = ModelReaderWriter.Read(response.Content); -// return ClientPage.Create(values.Data, values.HasMore ? values.LastId : null, response); -// } -//} +internal static class InternalListHelpers +{ + //internal delegate Task AsyncListResponseFunc(string continuationToken, int? pageSize); + + //internal static AsyncPageCollection CreateAsyncPageable(AsyncListResponseFunc listResponseFunc) + // where U : IJsonModel, IInternalListResponse + //{ + // async Task> pageFunc(string continuationToken, int? pageSize) + // => GetPageFromProtocol(await listResponseFunc(continuationToken, pageSize).ConfigureAwait(false)); + // return PageableResultHelpers.Create((pageSize) => pageFunc(null, pageSize), pageFunc); + //} + + //internal delegate ClientResult ListResponseFunc(string continuationToken, int? pageSize); + + internal delegate ClientResult GetListValues(int? limit, string? order, string? after, string? before, RequestOptions? options); + + internal static PageCollection CreatePageable(GetListValues getListValues) + where TList : IJsonModel, IInternalListResponse + { + ClientPage getPage(BinaryData pageToken, RequestOptions? options) + { + OpenAIPageToken token = OpenAIPageToken.FromBytes(pageToken); + + ClientResult result = getListValues( + limit: token.Limit, + order: token.Order, + after: token.After, + before: token.Before, + options); + + PipelineResponse response = result.GetRawResponse(); + IInternalListResponse list = ModelReaderWriter.Read(response.Content)!; + + BinaryData? nextPageToken = OpenAIPageToken.GetNextPageToken( + token, + list.HasMore, + list.LastId); + + return ClientPage.Create(list.Data, pageToken, nextPageToken, response); + } + + return PageCollectionHelpers.Create(); + } +} diff --git a/src/Custom/Common/OpenAIPageCollectionHelpers.cs b/src/Custom/Common/OpenAIPageCollectionHelpers.cs new file mode 100644 index 000000000..b499cd9a8 --- /dev/null +++ b/src/Custom/Common/OpenAIPageCollectionHelpers.cs @@ -0,0 +1,22 @@ +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Runtime.CompilerServices; +using System.Threading.Tasks; + +#nullable enable + +namespace OpenAI; + +internal class OpenAIPageCollectionHelpers +{ + public static AsyncPageCollection Create(int? limit, string? order, string? after, string? before) + where TList : IJsonModel, IInternalListResponse + { + BinaryData firstPageToken = OpenAIPageToken.FromListOptions(limit, order, after, before); + PageCollectionHelpers.Create() + } + + public static PageCollection Create(BinaryData firstPageToken, Func> getPage) where T : notnull + => new FuncPageable(firstPageToken, getPage); +} \ No newline at end of file diff --git a/src/Custom/Common/PageCollectionHelpers.cs b/src/Custom/Common/PageCollectionHelpers.cs new file mode 100644 index 000000000..d354d9e75 --- /dev/null +++ b/src/Custom/Common/PageCollectionHelpers.cs @@ -0,0 +1,51 @@ +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Threading.Tasks; + +#nullable enable + +namespace OpenAI; + +internal class PageCollectionHelpers +{ + public static AsyncPageCollection Create(BinaryData firstPageToken, Func>> getPageAsync) where T : notnull + => new FuncAsyncPageCollection(firstPageToken, getPageAsync); + + public static PageCollection Create(BinaryData firstPageToken, Func> getPage) where T : notnull + => new FuncPageCollection(firstPageToken, getPage); + + private class FuncAsyncPageCollection : AsyncPageCollection where T : notnull + { + private readonly BinaryData _firstPageToken; + private readonly Func>> _getPageAsync; + + public FuncAsyncPageCollection(BinaryData firstPageToken, Func>> getPageAsync) + { + _firstPageToken = firstPageToken; + _getPageAsync = getPageAsync; + } + + public override BinaryData FirstPageToken => _firstPageToken; + + public override async Task> GetPageAsync(BinaryData pageToken, RequestOptions? options = null) + => await _getPageAsync(pageToken, options).ConfigureAwait(false); + } + + private class FuncPageCollection : PageCollection where T : notnull + { + private readonly BinaryData _firstPageToken; + private readonly Func> _getPage; + + public FuncPageCollection(BinaryData firstPageToken, Func> getPage) + { + _firstPageToken = firstPageToken; + _getPage = getPage; + } + + public override BinaryData FirstPageToken => _firstPageToken; + + public override ClientPage GetPage(BinaryData pageToken, RequestOptions? options = null) + => _getPage(pageToken, options); + } +} diff --git a/src/Custom/Common/PageableResultHelpers.cs b/src/Custom/Common/PageableResultHelpers.cs deleted file mode 100644 index fc58a8823..000000000 --- a/src/Custom/Common/PageableResultHelpers.cs +++ /dev/null @@ -1,93 +0,0 @@ -using System; -using System.ClientModel; -using System.Collections.Generic; -using System.Threading.Tasks; - -#nullable enable - -namespace OpenAI; - -//internal class PageableResultHelpers -//{ -// public static PageCollection Create(Func> firstPageFunc, Func>? nextPageFunc, int? pageSize = default) where T : notnull -// { -// ClientPage first(string? _, int? pageSizeHint) => firstPageFunc(pageSizeHint); -// return new FuncPageable(first, nextPageFunc, pageSize); -// } - -// public static AsyncPageCollection Create(Func>> firstPageFunc, Func>>? nextPageFunc, int? pageSize = default) where T : notnull -// { -// Task> first(string? _, int? pageSizeHint) => firstPageFunc(pageSizeHint); -// return new FuncAsyncPageable(first, nextPageFunc, pageSize); -// } - -// private class FuncAsyncPageable : AsyncPageCollection where T : notnull -// { -// private readonly Func>> _firstPageFunc; -// private readonly Func>>? _nextPageFunc; -// private readonly int? _defaultPageSize; - -// public FuncAsyncPageable(Func>> firstPageFunc, Func>>? nextPageFunc, int? defaultPageSize = default) -// { -// _firstPageFunc = firstPageFunc; -// _nextPageFunc = nextPageFunc; -// _defaultPageSize = defaultPageSize; -// } - -// public override async IAsyncEnumerable> AsPages(string? continuationToken = default, int? pageSizeHint = default) -// { -// Func>>? pageFunc = string.IsNullOrEmpty(continuationToken) ? _firstPageFunc : _nextPageFunc; - -// if (pageFunc == null) -// { -// yield break; -// } - -// int? pageSize = pageSizeHint ?? _defaultPageSize; -// do -// { -// ClientPage page = await pageFunc(continuationToken, pageSize).ConfigureAwait(false); -// SetRawResponse(page.GetRawResponse()); -// yield return page; -// continuationToken = page.ContinuationToken; -// pageFunc = _nextPageFunc; -// } -// while (!string.IsNullOrEmpty(continuationToken) && pageFunc != null); -// } -// } - -// private class FuncPageable : PageCollection where T : notnull -// { -// private readonly Func> _firstPageFunc; -// private readonly Func>? _nextPageFunc; -// private readonly int? _defaultPageSize; - -// public FuncPageable(Func> firstPageFunc, Func>? nextPageFunc, int? defaultPageSize = default) -// { -// _firstPageFunc = firstPageFunc; -// _nextPageFunc = nextPageFunc; -// _defaultPageSize = defaultPageSize; -// } - -// public override IEnumerable> AsPages(string? continuationToken = default, int? pageSizeHint = default) -// { -// Func>? pageFunc = string.IsNullOrEmpty(continuationToken) ? _firstPageFunc : _nextPageFunc; - -// if (pageFunc == null) -// { -// yield break; -// } - -// int? pageSize = pageSizeHint ?? _defaultPageSize; -// do -// { -// ClientPage page = pageFunc(continuationToken, pageSize); -// SetRawResponse(page.GetRawResponse()); -// yield return page; -// continuationToken = page.ContinuationToken; -// pageFunc = _nextPageFunc; -// } -// while (!string.IsNullOrEmpty(continuationToken) && pageFunc != null); -// } -// } -//} From bae625a38ba8b3e4e2a49e83fc22522b3538e70d Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Wed, 26 Jun 2024 10:23:24 -0700 Subject: [PATCH 10/72] backup WIP on generalized implementation --- src/Custom/Assistants/AssistantClient.cs | 4 +- .../Assistants/AssistantPageCollection.cs | 11 ++- .../AsyncAssistantPageCollection.cs | 11 ++- src/Custom/Common/InternalListHelpers.cs | 54 ------------- .../Common/OpenAIPageCollectionHelpers.cs | 22 ------ src/Custom/Common/OpenAIPageHelpers.cs | 75 +++++++++++++++++++ src/Custom/Common/OpenAIPageToken.cs | 13 ++-- src/Custom/Common/PageCollectionHelpers.cs | 24 +++--- 8 files changed, 106 insertions(+), 108 deletions(-) delete mode 100644 src/Custom/Common/InternalListHelpers.cs delete mode 100644 src/Custom/Common/OpenAIPageCollectionHelpers.cs create mode 100644 src/Custom/Common/OpenAIPageHelpers.cs diff --git a/src/Custom/Assistants/AssistantClient.cs b/src/Custom/Assistants/AssistantClient.cs index 93069f2eb..071d35876 100644 --- a/src/Custom/Assistants/AssistantClient.cs +++ b/src/Custom/Assistants/AssistantClient.cs @@ -123,7 +123,7 @@ public virtual AsyncPageCollection GetAssistantsAsync(ListOrder? resu /// Page token indicating the first page of the collection to rehydrate. /// A token that can be used to cancel this method call. /// A collection of assistants that can be enumerated using await foreach. - public virtual AsyncPageCollection GetAssistantsAsync(BinaryData firstPageToken, CancellationToken cancellationToken = default) + public virtual AsyncPageCollection GetAssistantsAsync(ClientToken firstPageToken, CancellationToken cancellationToken = default) => new AsyncAssistantPageCollection(this, firstPageToken); /// @@ -147,7 +147,7 @@ public virtual PageCollection GetAssistants(ListOrder? resultOrder = /// Page token indicating the first page of the collection to rehydrate. /// A token that can be used to cancel this method call. /// A collection of assistants that can be enumerated using foreach. - public virtual PageCollection GetAssistants(BinaryData firstPageToken, CancellationToken cancellationToken = default) + public virtual PageCollection GetAssistants(ClientToken firstPageToken, CancellationToken cancellationToken = default) => new AssistantPageCollection(this, firstPageToken); /// diff --git a/src/Custom/Assistants/AssistantPageCollection.cs b/src/Custom/Assistants/AssistantPageCollection.cs index 6b34b9ad7..6c9550b71 100644 --- a/src/Custom/Assistants/AssistantPageCollection.cs +++ b/src/Custom/Assistants/AssistantPageCollection.cs @@ -1,7 +1,6 @@ using OpenAI.Assistants; using System.ClientModel; using System.ClientModel.Primitives; -using System; #nullable enable @@ -20,17 +19,17 @@ public AssistantPageCollection(AssistantClient client, int? limit, string? order } // rehydration constructor - public AssistantPageCollection(AssistantClient client, BinaryData firstPageToken) + public AssistantPageCollection(AssistantClient client, ClientToken firstPageToken) { _client = client; FirstPageToken = firstPageToken; } - public override BinaryData FirstPageToken { get; } + public override ClientToken FirstPageToken { get; } - public override ClientPage GetPage(BinaryData pageToken, RequestOptions? options) + public override ClientPage GetPage(ClientToken pageToken, RequestOptions? options) { - OpenAIPageToken token = OpenAIPageToken.FromBytes(pageToken); + OpenAIPageToken token = (OpenAIPageToken)pageToken; ClientResult result = _client.GetAssistantsPage( limit: token.Limit, @@ -42,7 +41,7 @@ public override ClientPage GetPage(BinaryData pageToken, RequestOptio PipelineResponse response = result.GetRawResponse(); InternalListAssistantsResponse list = ModelReaderWriter.Read(response.Content)!; - BinaryData? nextPageToken = OpenAIPageToken.GetNextPageToken( + OpenAIPageToken? nextPageToken = OpenAIPageToken.GetNextPageToken( token, list.HasMore, list.LastId); diff --git a/src/Custom/Assistants/AsyncAssistantPageCollection.cs b/src/Custom/Assistants/AsyncAssistantPageCollection.cs index c12f34915..f10fe4059 100644 --- a/src/Custom/Assistants/AsyncAssistantPageCollection.cs +++ b/src/Custom/Assistants/AsyncAssistantPageCollection.cs @@ -1,7 +1,6 @@ using OpenAI.Assistants; using System.ClientModel; using System.ClientModel.Primitives; -using System; using System.Threading.Tasks; #nullable enable @@ -21,17 +20,17 @@ public AsyncAssistantPageCollection(AssistantClient client, int? limit, string? } // rehydration constructor - public AsyncAssistantPageCollection(AssistantClient client, BinaryData firstPageToken) + public AsyncAssistantPageCollection(AssistantClient client, ClientToken firstPageToken) { _client = client; FirstPageToken = firstPageToken; } - public override BinaryData FirstPageToken { get; } + public override ClientToken FirstPageToken { get; } - public override async Task> GetPageAsync(BinaryData pageToken, RequestOptions? options) + public override async Task> GetPageAsync(ClientToken pageToken, RequestOptions? options) { - OpenAIPageToken token = OpenAIPageToken.FromBytes(pageToken); + OpenAIPageToken token = (OpenAIPageToken)pageToken; ClientResult result = await _client.GetAssistantsPageAsync( limit: token.Limit, @@ -43,7 +42,7 @@ public override async Task> GetPageAsync(BinaryData pageTo PipelineResponse response = result.GetRawResponse(); InternalListAssistantsResponse list = ModelReaderWriter.Read(response.Content)!; - BinaryData? nextPageToken = OpenAIPageToken.GetNextPageToken( + OpenAIPageToken? nextPageToken = OpenAIPageToken.GetNextPageToken( token, list.HasMore, list.LastId); diff --git a/src/Custom/Common/InternalListHelpers.cs b/src/Custom/Common/InternalListHelpers.cs deleted file mode 100644 index ffb78f225..000000000 --- a/src/Custom/Common/InternalListHelpers.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System; -using System.ClientModel; -using System.ClientModel.Primitives; -using System.Runtime.CompilerServices; -using System.Threading.Tasks; - -#nullable enable - -namespace OpenAI; - -internal static class InternalListHelpers -{ - //internal delegate Task AsyncListResponseFunc(string continuationToken, int? pageSize); - - //internal static AsyncPageCollection CreateAsyncPageable(AsyncListResponseFunc listResponseFunc) - // where U : IJsonModel, IInternalListResponse - //{ - // async Task> pageFunc(string continuationToken, int? pageSize) - // => GetPageFromProtocol(await listResponseFunc(continuationToken, pageSize).ConfigureAwait(false)); - // return PageableResultHelpers.Create((pageSize) => pageFunc(null, pageSize), pageFunc); - //} - - //internal delegate ClientResult ListResponseFunc(string continuationToken, int? pageSize); - - internal delegate ClientResult GetListValues(int? limit, string? order, string? after, string? before, RequestOptions? options); - - internal static PageCollection CreatePageable(GetListValues getListValues) - where TList : IJsonModel, IInternalListResponse - { - ClientPage getPage(BinaryData pageToken, RequestOptions? options) - { - OpenAIPageToken token = OpenAIPageToken.FromBytes(pageToken); - - ClientResult result = getListValues( - limit: token.Limit, - order: token.Order, - after: token.After, - before: token.Before, - options); - - PipelineResponse response = result.GetRawResponse(); - IInternalListResponse list = ModelReaderWriter.Read(response.Content)!; - - BinaryData? nextPageToken = OpenAIPageToken.GetNextPageToken( - token, - list.HasMore, - list.LastId); - - return ClientPage.Create(list.Data, pageToken, nextPageToken, response); - } - - return PageCollectionHelpers.Create(); - } -} diff --git a/src/Custom/Common/OpenAIPageCollectionHelpers.cs b/src/Custom/Common/OpenAIPageCollectionHelpers.cs deleted file mode 100644 index b499cd9a8..000000000 --- a/src/Custom/Common/OpenAIPageCollectionHelpers.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; -using System.ClientModel; -using System.ClientModel.Primitives; -using System.Runtime.CompilerServices; -using System.Threading.Tasks; - -#nullable enable - -namespace OpenAI; - -internal class OpenAIPageCollectionHelpers -{ - public static AsyncPageCollection Create(int? limit, string? order, string? after, string? before) - where TList : IJsonModel, IInternalListResponse - { - BinaryData firstPageToken = OpenAIPageToken.FromListOptions(limit, order, after, before); - PageCollectionHelpers.Create() - } - - public static PageCollection Create(BinaryData firstPageToken, Func> getPage) where T : notnull - => new FuncPageable(firstPageToken, getPage); -} \ No newline at end of file diff --git a/src/Custom/Common/OpenAIPageHelpers.cs b/src/Custom/Common/OpenAIPageHelpers.cs new file mode 100644 index 000000000..3d765690e --- /dev/null +++ b/src/Custom/Common/OpenAIPageHelpers.cs @@ -0,0 +1,75 @@ +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Threading.Tasks; + +#nullable enable + +namespace OpenAI; + +internal class OpenAIPageHelpers +{ + internal delegate Task GetListValuesAsync(int? limit, string? order, string? after, string? before, RequestOptions? options); + internal delegate ClientResult GetListValues(int? limit, string? order, string? after, string? before, RequestOptions? options); + + internal static AsyncPageCollection CreateAsync( + ClientToken firstPageToken, + GetListValuesAsync getListValuesAsync) + where TValue : notnull + where TList : IJsonModel, IInternalListResponse + { + async Task> getPageAsync(ClientToken pageToken, RequestOptions? options) + { + OpenAIPageToken token = (OpenAIPageToken)pageToken; + + ClientResult result = await getListValuesAsync( + limit: token.Limit, + order: token.Order, + after: token.After, + before: token.Before, + options).ConfigureAwait(false); + + PipelineResponse response = result.GetRawResponse(); + IInternalListResponse list = ModelReaderWriter.Read(response.Content)!; + + OpenAIPageToken? nextPageToken = OpenAIPageToken.GetNextPageToken( + token, + list.HasMore, + list.LastId); + + return ClientPage.Create(list.Data, pageToken, nextPageToken, response); + } + + return PageCollectionHelpers.Create(firstPageToken, getPageAsync); + } + + internal static PageCollection Create( + ClientToken firstPageToken, + GetListValues getListValues) + where TValue : notnull + where TList : IJsonModel, IInternalListResponse + { + ClientPage getPage(ClientToken pageToken, RequestOptions? options) + { + OpenAIPageToken token = (OpenAIPageToken)pageToken; + + ClientResult result = getListValues( + limit: token.Limit, + order: token.Order, + after: token.After, + before: token.Before, + options); + + PipelineResponse response = result.GetRawResponse(); + IInternalListResponse list = ModelReaderWriter.Read(response.Content)!; + + OpenAIPageToken? nextPageToken = OpenAIPageToken.GetNextPageToken( + token, + list.HasMore, + list.LastId); + + return ClientPage.Create(list.Data, pageToken, nextPageToken, response); + } + + return PageCollectionHelpers.Create(firstPageToken, getPage); + } +} \ No newline at end of file diff --git a/src/Custom/Common/OpenAIPageToken.cs b/src/Custom/Common/OpenAIPageToken.cs index d5a955bcc..d4e796ac2 100644 --- a/src/Custom/Common/OpenAIPageToken.cs +++ b/src/Custom/Common/OpenAIPageToken.cs @@ -1,4 +1,5 @@ using System; +using System.ClientModel; using System.Diagnostics; using System.IO; using System.Text.Json; @@ -7,7 +8,7 @@ namespace OpenAI; -internal class OpenAIPageToken +internal class OpenAIPageToken : ClientToken { public OpenAIPageToken(int? limit, string? order, string? after, string? before) { @@ -25,7 +26,7 @@ public OpenAIPageToken(int? limit, string? order, string? after, string? before) public string? Before { get; } - public BinaryData ToBytes() + public override BinaryData ToBytes() { using MemoryStream stream = new(); using Utf8JsonWriter writer = new(stream); @@ -59,8 +60,8 @@ public BinaryData ToBytes() return BinaryData.FromStream(stream); } - public static BinaryData FromListOptions(int? limit, string? order, string? after, string? before) - => new OpenAIPageToken(limit, order, after, before).ToBytes(); + public static OpenAIPageToken FromListOptions(int? limit, string? order, string? after, string? before) + => new OpenAIPageToken(limit, order, after, before); public static OpenAIPageToken FromBytes(BinaryData data) { @@ -119,13 +120,13 @@ public static OpenAIPageToken FromBytes(BinaryData data) return new(limit, order, after, before); } - public static BinaryData? GetNextPageToken(OpenAIPageToken token, bool hasMore, string? lastId) + public static OpenAIPageToken? GetNextPageToken(OpenAIPageToken token, bool hasMore, string? lastId) { if (!hasMore || lastId is null) { return null; } - return new OpenAIPageToken(token.Limit, token.Order, lastId, token.Before).ToBytes(); + return new OpenAIPageToken(token.Limit, token.Order, lastId, token.Before); } } \ No newline at end of file diff --git a/src/Custom/Common/PageCollectionHelpers.cs b/src/Custom/Common/PageCollectionHelpers.cs index d354d9e75..fc8d5abb3 100644 --- a/src/Custom/Common/PageCollectionHelpers.cs +++ b/src/Custom/Common/PageCollectionHelpers.cs @@ -9,43 +9,43 @@ namespace OpenAI; internal class PageCollectionHelpers { - public static AsyncPageCollection Create(BinaryData firstPageToken, Func>> getPageAsync) where T : notnull + public static AsyncPageCollection Create(ClientToken firstPageToken, Func>> getPageAsync) where T : notnull => new FuncAsyncPageCollection(firstPageToken, getPageAsync); - public static PageCollection Create(BinaryData firstPageToken, Func> getPage) where T : notnull + public static PageCollection Create(ClientToken firstPageToken, Func> getPage) where T : notnull => new FuncPageCollection(firstPageToken, getPage); private class FuncAsyncPageCollection : AsyncPageCollection where T : notnull { - private readonly BinaryData _firstPageToken; - private readonly Func>> _getPageAsync; + private readonly ClientToken _firstPageToken; + private readonly Func>> _getPageAsync; - public FuncAsyncPageCollection(BinaryData firstPageToken, Func>> getPageAsync) + public FuncAsyncPageCollection(ClientToken firstPageToken, Func>> getPageAsync) { _firstPageToken = firstPageToken; _getPageAsync = getPageAsync; } - public override BinaryData FirstPageToken => _firstPageToken; + public override ClientToken FirstPageToken => _firstPageToken; - public override async Task> GetPageAsync(BinaryData pageToken, RequestOptions? options = null) + public override async Task> GetPageAsync(ClientToken pageToken, RequestOptions? options = null) => await _getPageAsync(pageToken, options).ConfigureAwait(false); } private class FuncPageCollection : PageCollection where T : notnull { - private readonly BinaryData _firstPageToken; - private readonly Func> _getPage; + private readonly ClientToken _firstPageToken; + private readonly Func> _getPage; - public FuncPageCollection(BinaryData firstPageToken, Func> getPage) + public FuncPageCollection(ClientToken firstPageToken, Func> getPage) { _firstPageToken = firstPageToken; _getPage = getPage; } - public override BinaryData FirstPageToken => _firstPageToken; + public override ClientToken FirstPageToken => _firstPageToken; - public override ClientPage GetPage(BinaryData pageToken, RequestOptions? options = null) + public override ClientPage GetPage(ClientToken pageToken, RequestOptions? options = null) => _getPage(pageToken, options); } } From 03e17b672a27abc01f8d93650d331f6dadd46a97 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Wed, 26 Jun 2024 10:41:42 -0700 Subject: [PATCH 11/72] remove Assistant-specific page collection implementations in favor of using general helpers --- src/Custom/Assistants/AssistantClient.cs | 8 +-- .../Assistants/AssistantPageCollection.cs | 52 ------------------- .../AsyncAssistantPageCollection.cs | 52 ------------------- 3 files changed, 4 insertions(+), 108 deletions(-) delete mode 100644 src/Custom/Assistants/AssistantPageCollection.cs delete mode 100644 src/Custom/Assistants/AsyncAssistantPageCollection.cs diff --git a/src/Custom/Assistants/AssistantClient.cs b/src/Custom/Assistants/AssistantClient.cs index 071d35876..7dbc28f76 100644 --- a/src/Custom/Assistants/AssistantClient.cs +++ b/src/Custom/Assistants/AssistantClient.cs @@ -115,7 +115,7 @@ public virtual ClientResult CreateAssistant(string model, AssistantCr /// A token that can be used to cancel this method call. /// A collection of assistants that can be enumerated using await foreach. public virtual AsyncPageCollection GetAssistantsAsync(ListOrder? resultOrder = default, int? pageSize = default, string afterId = default, string beforeId = default, CancellationToken cancellationToken = default) - => new AsyncAssistantPageCollection(this, pageSize, resultOrder?.ToString(), afterId, beforeId); + => GetAssistantsAsync(OpenAIPageToken.FromListOptions(limit: pageSize, order: resultOrder?.ToString(), after: afterId, before: beforeId)); /// /// Rehydrates a collection of instances. @@ -124,7 +124,7 @@ public virtual AsyncPageCollection GetAssistantsAsync(ListOrder? resu /// A token that can be used to cancel this method call. /// A collection of assistants that can be enumerated using await foreach. public virtual AsyncPageCollection GetAssistantsAsync(ClientToken firstPageToken, CancellationToken cancellationToken = default) - => new AsyncAssistantPageCollection(this, firstPageToken); + => OpenAIPageHelpers.CreateAsync(firstPageToken, GetAssistantsPageAsync); /// /// Returns a collection of instances. @@ -139,7 +139,7 @@ public virtual AsyncPageCollection GetAssistantsAsync(ClientToken fir /// A token that can be used to cancel this method call. /// A collection of assistants that can be enumerated using foreach. public virtual PageCollection GetAssistants(ListOrder? resultOrder = default, int? pageSize = default, string afterId = default, string beforeId = default, CancellationToken cancellationToken = default) - => new AssistantPageCollection(this, pageSize, resultOrder?.ToString(), afterId, beforeId); + => GetAssistants(OpenAIPageToken.FromListOptions(limit: pageSize, order: resultOrder?.ToString(), after: afterId, before: beforeId)); /// /// Rehydrates a collection of instances. @@ -148,7 +148,7 @@ public virtual PageCollection GetAssistants(ListOrder? resultOrder = /// A token that can be used to cancel this method call. /// A collection of assistants that can be enumerated using foreach. public virtual PageCollection GetAssistants(ClientToken firstPageToken, CancellationToken cancellationToken = default) - => new AssistantPageCollection(this, firstPageToken); + => OpenAIPageHelpers.Create(firstPageToken, GetAssistantsPage); /// /// Deletes an existing . diff --git a/src/Custom/Assistants/AssistantPageCollection.cs b/src/Custom/Assistants/AssistantPageCollection.cs deleted file mode 100644 index 6c9550b71..000000000 --- a/src/Custom/Assistants/AssistantPageCollection.cs +++ /dev/null @@ -1,52 +0,0 @@ -using OpenAI.Assistants; -using System.ClientModel; -using System.ClientModel.Primitives; - -#nullable enable - -namespace OpenAI; - -#pragma warning disable OPENAI001 -internal class AssistantPageCollection : PageCollection -{ - private readonly AssistantClient _client; - - // service method constructor - public AssistantPageCollection(AssistantClient client, int? limit, string? order, string? after, string? before) - { - _client = client; - FirstPageToken = OpenAIPageToken.FromListOptions(limit, order, after, before); - } - - // rehydration constructor - public AssistantPageCollection(AssistantClient client, ClientToken firstPageToken) - { - _client = client; - FirstPageToken = firstPageToken; - } - - public override ClientToken FirstPageToken { get; } - - public override ClientPage GetPage(ClientToken pageToken, RequestOptions? options) - { - OpenAIPageToken token = (OpenAIPageToken)pageToken; - - ClientResult result = _client.GetAssistantsPage( - limit: token.Limit, - order: token.Order, - after: token.After, - before: token.Before, - options: options); - - PipelineResponse response = result.GetRawResponse(); - InternalListAssistantsResponse list = ModelReaderWriter.Read(response.Content)!; - - OpenAIPageToken? nextPageToken = OpenAIPageToken.GetNextPageToken( - token, - list.HasMore, - list.LastId); - - return ClientPage.Create(list.Data, pageToken, nextPageToken, response); - } -} -#pragma warning restore OPENAI001 \ No newline at end of file diff --git a/src/Custom/Assistants/AsyncAssistantPageCollection.cs b/src/Custom/Assistants/AsyncAssistantPageCollection.cs deleted file mode 100644 index f10fe4059..000000000 --- a/src/Custom/Assistants/AsyncAssistantPageCollection.cs +++ /dev/null @@ -1,52 +0,0 @@ -using OpenAI.Assistants; -using System.ClientModel; -using System.ClientModel.Primitives; -using System.Threading.Tasks; - -#nullable enable - -namespace OpenAI; - -#pragma warning disable OPENAI001 -internal class AsyncAssistantPageCollection : AsyncPageCollection -{ - private readonly AssistantClient _client; - - // service method constructor - public AsyncAssistantPageCollection(AssistantClient client, int? limit, string? order, string? after, string? before) - { - _client = client; - FirstPageToken = OpenAIPageToken.FromListOptions(limit, order, after, before); - } - - // rehydration constructor - public AsyncAssistantPageCollection(AssistantClient client, ClientToken firstPageToken) - { - _client = client; - FirstPageToken = firstPageToken; - } - - public override ClientToken FirstPageToken { get; } - - public override async Task> GetPageAsync(ClientToken pageToken, RequestOptions? options) - { - OpenAIPageToken token = (OpenAIPageToken)pageToken; - - ClientResult result = await _client.GetAssistantsPageAsync( - limit: token.Limit, - order: token.Order, - after: token.After, - before: token.Before, - options: options).ConfigureAwait(false); - - PipelineResponse response = result.GetRawResponse(); - InternalListAssistantsResponse list = ModelReaderWriter.Read(response.Content)!; - - OpenAIPageToken? nextPageToken = OpenAIPageToken.GetNextPageToken( - token, - list.HasMore, - list.LastId); - return ClientPage.Create(list.Data, pageToken, nextPageToken, response); - } -} -#pragma warning restore OPENAI001 \ No newline at end of file From 1f150ea83f9a8bee4867ea28167197a43cb19932 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Wed, 26 Jun 2024 11:15:39 -0700 Subject: [PATCH 12/72] remove Assistant-specific page collection implementations in favor of using general helpers --- .../Assistants/AssistantClient.Protocol.cs | 4 +- src/Custom/Assistants/AssistantClient.cs | 4 +- .../AsyncAssistantPageCollection.Protocol.cs | 1 - src/Custom/Common/OpenAIPageHelpers.cs | 75 ------------------- src/Custom/Common/PageCollectionHelpers.cs | 46 +++++++++++- 5 files changed, 48 insertions(+), 82 deletions(-) delete mode 100644 src/Custom/Common/OpenAIPageHelpers.cs diff --git a/src/Custom/Assistants/AssistantClient.Protocol.cs b/src/Custom/Assistants/AssistantClient.Protocol.cs index 4f1d6193a..80b3f3de7 100644 --- a/src/Custom/Assistants/AssistantClient.Protocol.cs +++ b/src/Custom/Assistants/AssistantClient.Protocol.cs @@ -65,7 +65,7 @@ public virtual ClientResult CreateAssistant(BinaryContent content, RequestOption /// Service returned a non-success status code. /// The response returned from the service. public virtual IAsyncEnumerable GetAssistantsAsync(int? limit, string order, string after, string before, RequestOptions options) - => new AsyncProtocolAssistantPageCollection(this, limit, order, after, before, options); + => new AsyncProtocolAssistantPageCollection(this, limit, order, after, before, options); internal virtual async Task GetAssistantsPageAsync(int? limit, string order, string after, string before, RequestOptions options) { @@ -98,7 +98,7 @@ internal virtual async Task GetAssistantsPageAsync(int? limit, str /// Service returned a non-success status code. /// The response returned from the service. public virtual IEnumerable GetAssistants(int? limit, string order, string after, string before, RequestOptions options) - => new ProtocolAssistantPageCollection(this, limit, order, after, before, options); + => OpenAIPagingHelpers.CreateProtocol(limit, order, after, before, options, GetAssistantsPage); // This needs to be internal now internal virtual ClientResult GetAssistantsPage(int? limit, string order, string after, string before, RequestOptions options) diff --git a/src/Custom/Assistants/AssistantClient.cs b/src/Custom/Assistants/AssistantClient.cs index 7dbc28f76..b58c80260 100644 --- a/src/Custom/Assistants/AssistantClient.cs +++ b/src/Custom/Assistants/AssistantClient.cs @@ -124,7 +124,7 @@ public virtual AsyncPageCollection GetAssistantsAsync(ListOrder? resu /// A token that can be used to cancel this method call. /// A collection of assistants that can be enumerated using await foreach. public virtual AsyncPageCollection GetAssistantsAsync(ClientToken firstPageToken, CancellationToken cancellationToken = default) - => OpenAIPageHelpers.CreateAsync(firstPageToken, GetAssistantsPageAsync); + => OpenAIPagingHelpers.CreateAsync(firstPageToken, GetAssistantsPageAsync); /// /// Returns a collection of instances. @@ -148,7 +148,7 @@ public virtual PageCollection GetAssistants(ListOrder? resultOrder = /// A token that can be used to cancel this method call. /// A collection of assistants that can be enumerated using foreach. public virtual PageCollection GetAssistants(ClientToken firstPageToken, CancellationToken cancellationToken = default) - => OpenAIPageHelpers.Create(firstPageToken, GetAssistantsPage); + => OpenAIPagingHelpers.Create(firstPageToken, GetAssistantsPage); /// /// Deletes an existing . diff --git a/src/Custom/Assistants/AsyncAssistantPageCollection.Protocol.cs b/src/Custom/Assistants/AsyncAssistantPageCollection.Protocol.cs index 4ea89b3a4..7815da874 100644 --- a/src/Custom/Assistants/AsyncAssistantPageCollection.Protocol.cs +++ b/src/Custom/Assistants/AsyncAssistantPageCollection.Protocol.cs @@ -35,7 +35,6 @@ public AsyncProtocolAssistantPageCollection(AssistantClient client, int? limit, public async IAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) { - string? after = _after; bool hasMore = false; diff --git a/src/Custom/Common/OpenAIPageHelpers.cs b/src/Custom/Common/OpenAIPageHelpers.cs deleted file mode 100644 index 3d765690e..000000000 --- a/src/Custom/Common/OpenAIPageHelpers.cs +++ /dev/null @@ -1,75 +0,0 @@ -using System.ClientModel; -using System.ClientModel.Primitives; -using System.Threading.Tasks; - -#nullable enable - -namespace OpenAI; - -internal class OpenAIPageHelpers -{ - internal delegate Task GetListValuesAsync(int? limit, string? order, string? after, string? before, RequestOptions? options); - internal delegate ClientResult GetListValues(int? limit, string? order, string? after, string? before, RequestOptions? options); - - internal static AsyncPageCollection CreateAsync( - ClientToken firstPageToken, - GetListValuesAsync getListValuesAsync) - where TValue : notnull - where TList : IJsonModel, IInternalListResponse - { - async Task> getPageAsync(ClientToken pageToken, RequestOptions? options) - { - OpenAIPageToken token = (OpenAIPageToken)pageToken; - - ClientResult result = await getListValuesAsync( - limit: token.Limit, - order: token.Order, - after: token.After, - before: token.Before, - options).ConfigureAwait(false); - - PipelineResponse response = result.GetRawResponse(); - IInternalListResponse list = ModelReaderWriter.Read(response.Content)!; - - OpenAIPageToken? nextPageToken = OpenAIPageToken.GetNextPageToken( - token, - list.HasMore, - list.LastId); - - return ClientPage.Create(list.Data, pageToken, nextPageToken, response); - } - - return PageCollectionHelpers.Create(firstPageToken, getPageAsync); - } - - internal static PageCollection Create( - ClientToken firstPageToken, - GetListValues getListValues) - where TValue : notnull - where TList : IJsonModel, IInternalListResponse - { - ClientPage getPage(ClientToken pageToken, RequestOptions? options) - { - OpenAIPageToken token = (OpenAIPageToken)pageToken; - - ClientResult result = getListValues( - limit: token.Limit, - order: token.Order, - after: token.After, - before: token.Before, - options); - - PipelineResponse response = result.GetRawResponse(); - IInternalListResponse list = ModelReaderWriter.Read(response.Content)!; - - OpenAIPageToken? nextPageToken = OpenAIPageToken.GetNextPageToken( - token, - list.HasMore, - list.LastId); - - return ClientPage.Create(list.Data, pageToken, nextPageToken, response); - } - - return PageCollectionHelpers.Create(firstPageToken, getPage); - } -} \ No newline at end of file diff --git a/src/Custom/Common/PageCollectionHelpers.cs b/src/Custom/Common/PageCollectionHelpers.cs index fc8d5abb3..a5e26b231 100644 --- a/src/Custom/Common/PageCollectionHelpers.cs +++ b/src/Custom/Common/PageCollectionHelpers.cs @@ -1,6 +1,8 @@ using System; using System.ClientModel; using System.ClientModel.Primitives; +using System.Collections; +using System.Collections.Generic; using System.Threading.Tasks; #nullable enable @@ -9,12 +11,19 @@ namespace OpenAI; internal class PageCollectionHelpers { - public static AsyncPageCollection Create(ClientToken firstPageToken, Func>> getPageAsync) where T : notnull + public static AsyncPageCollection Create(ClientToken firstPageToken, + Func>> getPageAsync) where T : notnull => new FuncAsyncPageCollection(firstPageToken, getPageAsync); - public static PageCollection Create(ClientToken firstPageToken, Func> getPage) where T : notnull + public static PageCollection Create(ClientToken firstPageToken, + Func> getPage) where T : notnull => new FuncPageCollection(firstPageToken, getPage); + public static IEnumerable CreatePrototol(RequestOptions? options, + Func getPage, + Func isLastPage) + => new FuncResultEnumerable(options, getPage, isLastPage); + private class FuncAsyncPageCollection : AsyncPageCollection where T : notnull { private readonly ClientToken _firstPageToken; @@ -48,4 +57,37 @@ public FuncPageCollection(ClientToken firstPageToken, Func GetPage(ClientToken pageToken, RequestOptions? options = null) => _getPage(pageToken, options); } + + private class FuncResultEnumerable : IEnumerable + { + private readonly RequestOptions? _options; + + private readonly Func _getPage; + private readonly Func _isLastPage; + + public FuncResultEnumerable(RequestOptions? options, + Func getPage, + Func isLastPage) + { + _options = options; + _getPage = getPage; + _isLastPage = isLastPage; + } + + public IEnumerator GetEnumerator() + { + bool lastPage = false; + + do + { + ClientResult result = _getPage(_options); + yield return result; + + lastPage = _isLastPage(result); + } + while (!lastPage); + } + + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + } } From 6ba8dbdb8780d6e6d35579e94230e132596dbe43 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Wed, 26 Jun 2024 11:39:33 -0700 Subject: [PATCH 13/72] Backup of generalized protocol paging idea --- src/Custom/Common/OpenAIPagingHelpers.cs | 104 +++++++++++++++++++++ src/Custom/Common/PageCollectionHelpers.cs | 34 ++++--- 2 files changed, 120 insertions(+), 18 deletions(-) create mode 100644 src/Custom/Common/OpenAIPagingHelpers.cs diff --git a/src/Custom/Common/OpenAIPagingHelpers.cs b/src/Custom/Common/OpenAIPagingHelpers.cs new file mode 100644 index 000000000..9331522d3 --- /dev/null +++ b/src/Custom/Common/OpenAIPagingHelpers.cs @@ -0,0 +1,104 @@ +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; +using System.Threading.Tasks; + +#nullable enable + +namespace OpenAI; + +internal class OpenAIPagingHelpers +{ + public delegate Task GetValuesAsync(int? limit, string? order, string? after, string? before, RequestOptions? options); + public delegate ClientResult GetPageValues(int? limit, string? order, string? after, string? before, RequestOptions? options); + + public static AsyncPageCollection CreateAsync( + ClientToken firstPageToken, + GetValuesAsync getListValuesAsync) + where TValue : notnull + where TList : IJsonModel, IInternalListResponse + { + async Task> getPageAsync(ClientToken pageToken, RequestOptions? options) + { + OpenAIPageToken token = (OpenAIPageToken)pageToken; + + ClientResult result = await getListValuesAsync( + limit: token.Limit, + order: token.Order, + after: token.After, + before: token.Before, + options).ConfigureAwait(false); + + PipelineResponse response = result.GetRawResponse(); + IInternalListResponse list = ModelReaderWriter.Read(response.Content)!; + + OpenAIPageToken? nextPageToken = OpenAIPageToken.GetNextPageToken( + token, + list.HasMore, + list.LastId); + + return ClientPage.Create(list.Data, pageToken, nextPageToken, response); + } + + return PageCollectionHelpers.Create(firstPageToken, getPageAsync); + } + + public static PageCollection Create( + ClientToken firstPageToken, + GetPageValues getListValues) + where TValue : notnull + where TList : IJsonModel, IInternalListResponse + { + ClientPage getPage(ClientToken pageToken, RequestOptions? options) + { + OpenAIPageToken token = (OpenAIPageToken)pageToken; + + ClientResult result = getListValues( + limit: token.Limit, + order: token.Order, + after: token.After, + before: token.Before, + options); + + PipelineResponse response = result.GetRawResponse(); + IInternalListResponse list = ModelReaderWriter.Read(response.Content)!; + + OpenAIPageToken? nextPageToken = OpenAIPageToken.GetNextPageToken( + token, + list.HasMore, + list.LastId); + + return ClientPage.Create(list.Data, pageToken, nextPageToken, response); + } + + return PageCollectionHelpers.Create(firstPageToken, getPage); + } + + public static IEnumerable CreateProtocol( + int? limit, string? order, string? after, string? before, RequestOptions? options, + GetPageValues getPageValues) + { + OpenAIPageToken firstPageToken = OpenAIPageToken.FromListOptions(limit, order, after, before); + + ClientResult getPage(ClientToken pageToken) + { + OpenAIPageToken token = (OpenAIPageToken)pageToken; + return getPageValues(token.Limit, token.Order, token.After, token.Before, options); + } + + ClientToken? getNextPageToken(ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + + using JsonDocument doc = JsonDocument.Parse(response.Content); + bool hasMore = doc.RootElement.GetProperty("has_more"u8).GetBoolean(); + after = doc.RootElement.GetProperty("last_id"u8).GetString(); + + return !hasMore ? null : OpenAIPageToken.FromListOptions(limit, order, after, before); + } + + return PageCollectionHelpers.CreatePrototol(firstPageToken, getPage, getNextPageToken); + } +} \ No newline at end of file diff --git a/src/Custom/Common/PageCollectionHelpers.cs b/src/Custom/Common/PageCollectionHelpers.cs index a5e26b231..cb7f60d64 100644 --- a/src/Custom/Common/PageCollectionHelpers.cs +++ b/src/Custom/Common/PageCollectionHelpers.cs @@ -19,10 +19,10 @@ public static PageCollection Create(ClientToken firstPageToken, Func> getPage) where T : notnull => new FuncPageCollection(firstPageToken, getPage); - public static IEnumerable CreatePrototol(RequestOptions? options, - Func getPage, - Func isLastPage) - => new FuncResultEnumerable(options, getPage, isLastPage); + public static IEnumerable CreatePrototol(ClientToken firstPageToken, + Func getPage, + Func getNextPageToken) + => new FuncResultEnumerable(firstPageToken, getPage, getNextPageToken); private class FuncAsyncPageCollection : AsyncPageCollection where T : notnull { @@ -60,32 +60,30 @@ public override ClientPage GetPage(ClientToken pageToken, RequestOptions? opt private class FuncResultEnumerable : IEnumerable { - private readonly RequestOptions? _options; - - private readonly Func _getPage; - private readonly Func _isLastPage; + private readonly ClientToken _firstPageToken; + private readonly Func _getPage; + private readonly Func _getNextPageToken; - public FuncResultEnumerable(RequestOptions? options, - Func getPage, - Func isLastPage) + public FuncResultEnumerable(ClientToken firstPageToken, + Func getPage, + Func getNextPageToken) { - _options = options; + _firstPageToken = firstPageToken; _getPage = getPage; - _isLastPage = isLastPage; + _getNextPageToken = getNextPageToken; } public IEnumerator GetEnumerator() { - bool lastPage = false; + ClientToken? pageToken = _firstPageToken; do { - ClientResult result = _getPage(_options); + ClientResult result = _getPage(pageToken); yield return result; - - lastPage = _isLastPage(result); + pageToken = _getNextPageToken(result); } - while (!lastPage); + while (pageToken != null); } IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); From 7c1f74d5ea34c6798194c582ee1354453634d4ac Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Wed, 26 Jun 2024 12:06:29 -0700 Subject: [PATCH 14/72] remove Assistant-specific page result enumerator implementations in favor of generalized helpers --- .../Assistants/AssistantClient.Protocol.cs | 2 +- .../AssistantPageCollection.Protocol.cs | 62 ------------------- .../AsyncAssistantPageCollection.Protocol.cs | 60 ------------------ src/Custom/Common/OpenAIPageToken.cs | 9 ++- src/Custom/Common/OpenAIPagingHelpers.cs | 47 +++++++++----- src/Custom/Common/PageCollectionHelpers.cs | 43 +++++++++++-- 6 files changed, 78 insertions(+), 145 deletions(-) delete mode 100644 src/Custom/Assistants/AssistantPageCollection.Protocol.cs delete mode 100644 src/Custom/Assistants/AsyncAssistantPageCollection.Protocol.cs diff --git a/src/Custom/Assistants/AssistantClient.Protocol.cs b/src/Custom/Assistants/AssistantClient.Protocol.cs index 80b3f3de7..0287dd1fc 100644 --- a/src/Custom/Assistants/AssistantClient.Protocol.cs +++ b/src/Custom/Assistants/AssistantClient.Protocol.cs @@ -65,7 +65,7 @@ public virtual ClientResult CreateAssistant(BinaryContent content, RequestOption /// Service returned a non-success status code. /// The response returned from the service. public virtual IAsyncEnumerable GetAssistantsAsync(int? limit, string order, string after, string before, RequestOptions options) - => new AsyncProtocolAssistantPageCollection(this, limit, order, after, before, options); + => OpenAIPagingHelpers.CreateProtocolAsync(limit, order, after, before, options, GetAssistantsPageAsync); internal virtual async Task GetAssistantsPageAsync(int? limit, string order, string after, string before, RequestOptions options) { diff --git a/src/Custom/Assistants/AssistantPageCollection.Protocol.cs b/src/Custom/Assistants/AssistantPageCollection.Protocol.cs deleted file mode 100644 index 8f38120ff..000000000 --- a/src/Custom/Assistants/AssistantPageCollection.Protocol.cs +++ /dev/null @@ -1,62 +0,0 @@ -using OpenAI.Assistants; -using System.ClientModel; -using System.ClientModel.Primitives; -using System.Collections; -using System.Collections.Generic; -using System.Text.Json; - -#nullable enable - -namespace OpenAI; - -#pragma warning disable OPENAI001 -internal class ProtocolAssistantPageCollection : IEnumerable -{ - private readonly AssistantClient _client; - - private readonly int? _limit; - private readonly string? _order; - private readonly string? _after; - private readonly string? _before; - - private readonly RequestOptions? _options; - - public ProtocolAssistantPageCollection(AssistantClient client, int? limit, string order, string after, string before, RequestOptions options) - { - _client = client; - - _limit = limit; - _order = order; - _after = after; - _before = before; - - _options = options; - } - - public IEnumerator GetEnumerator() - { - string? after = _after; - bool hasMore = false; - - do - { - ClientResult result = _client.GetAssistantsPage( - limit: _limit, - order: _order, - after: after, - before: _before, - options: _options); - - yield return result; - - PipelineResponse response = result.GetRawResponse(); - using JsonDocument doc = JsonDocument.Parse(response.Content); - hasMore = doc.RootElement.GetProperty("has_more"u8).GetBoolean(); - after = doc.RootElement.GetProperty("last_id"u8).GetString(); - - } while (hasMore); - } - - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); -} -#pragma warning restore OPENAI001 \ No newline at end of file diff --git a/src/Custom/Assistants/AsyncAssistantPageCollection.Protocol.cs b/src/Custom/Assistants/AsyncAssistantPageCollection.Protocol.cs deleted file mode 100644 index 7815da874..000000000 --- a/src/Custom/Assistants/AsyncAssistantPageCollection.Protocol.cs +++ /dev/null @@ -1,60 +0,0 @@ -using OpenAI.Assistants; -using System.ClientModel; -using System.ClientModel.Primitives; -using System.Collections.Generic; -using System.Text.Json; -using System.Threading; - -#nullable enable - -namespace OpenAI; - -#pragma warning disable OPENAI001 -internal class AsyncProtocolAssistantPageCollection : IAsyncEnumerable -{ - private readonly AssistantClient _client; - - private readonly int? _limit; - private readonly string? _order; - private readonly string? _after; - private readonly string? _before; - - private readonly RequestOptions? _options; - - public AsyncProtocolAssistantPageCollection(AssistantClient client, int? limit, string order, string after, string before, RequestOptions options) - { - _client = client; - - _limit = limit; - _order = order; - _after = after; - _before = before; - - _options = options; - } - - public async IAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) - { - string? after = _after; - bool hasMore = false; - - do - { - ClientResult result = await _client.GetAssistantsPageAsync( - limit: _limit, - order: _order, - after: after, - before: _before, - options: _options).ConfigureAwait(false); - - yield return result; - - PipelineResponse response = result.GetRawResponse(); - using JsonDocument doc = JsonDocument.Parse(response.Content); - hasMore = doc.RootElement.GetProperty("has_more"u8).GetBoolean(); - after = doc.RootElement.GetProperty("last_id"u8).GetString(); - - } while (hasMore); - } -} -#pragma warning restore OPENAI001 \ No newline at end of file diff --git a/src/Custom/Common/OpenAIPageToken.cs b/src/Custom/Common/OpenAIPageToken.cs index d4e796ac2..3b58b31f3 100644 --- a/src/Custom/Common/OpenAIPageToken.cs +++ b/src/Custom/Common/OpenAIPageToken.cs @@ -60,6 +60,9 @@ public override BinaryData ToBytes() return BinaryData.FromStream(stream); } + public OpenAIPageToken? GetNextPageToken(bool hasMore, string? lastId) + => GetNextPageToken(Limit, Order, lastId, Before, hasMore); + public static OpenAIPageToken FromListOptions(int? limit, string? order, string? after, string? before) => new OpenAIPageToken(limit, order, after, before); @@ -120,13 +123,13 @@ public static OpenAIPageToken FromBytes(BinaryData data) return new(limit, order, after, before); } - public static OpenAIPageToken? GetNextPageToken(OpenAIPageToken token, bool hasMore, string? lastId) + public static OpenAIPageToken? GetNextPageToken(int? limit, string? order, string? after, string? before, bool hasMore) { - if (!hasMore || lastId is null) + if (!hasMore || after is null) { return null; } - return new OpenAIPageToken(token.Limit, token.Order, lastId, token.Before); + return new OpenAIPageToken(limit, order, after, before); } } \ No newline at end of file diff --git a/src/Custom/Common/OpenAIPagingHelpers.cs b/src/Custom/Common/OpenAIPagingHelpers.cs index 9331522d3..189064da5 100644 --- a/src/Custom/Common/OpenAIPagingHelpers.cs +++ b/src/Custom/Common/OpenAIPagingHelpers.cs @@ -1,4 +1,3 @@ -using System; using System.ClientModel; using System.ClientModel.Primitives; using System.Collections.Generic; @@ -11,12 +10,12 @@ namespace OpenAI; internal class OpenAIPagingHelpers { - public delegate Task GetValuesAsync(int? limit, string? order, string? after, string? before, RequestOptions? options); + public delegate Task GetPageValuesAsync(int? limit, string? order, string? after, string? before, RequestOptions? options); public delegate ClientResult GetPageValues(int? limit, string? order, string? after, string? before, RequestOptions? options); public static AsyncPageCollection CreateAsync( ClientToken firstPageToken, - GetValuesAsync getListValuesAsync) + GetPageValuesAsync getListValuesAsync) where TValue : notnull where TList : IJsonModel, IInternalListResponse { @@ -33,16 +32,12 @@ async Task> getPageAsync(ClientToken pageToken, RequestOption PipelineResponse response = result.GetRawResponse(); IInternalListResponse list = ModelReaderWriter.Read(response.Content)!; - - OpenAIPageToken? nextPageToken = OpenAIPageToken.GetNextPageToken( - token, - list.HasMore, - list.LastId); + OpenAIPageToken? nextPageToken = token.GetNextPageToken(list.HasMore, list.LastId); return ClientPage.Create(list.Data, pageToken, nextPageToken, response); } - return PageCollectionHelpers.Create(firstPageToken, getPageAsync); + return PageCollectionHelpers.CreateAsync(firstPageToken, getPageAsync); } public static PageCollection Create( @@ -64,11 +59,7 @@ ClientPage getPage(ClientToken pageToken, RequestOptions? options) PipelineResponse response = result.GetRawResponse(); IInternalListResponse list = ModelReaderWriter.Read(response.Content)!; - - OpenAIPageToken? nextPageToken = OpenAIPageToken.GetNextPageToken( - token, - list.HasMore, - list.LastId); + OpenAIPageToken? nextPageToken = token.GetNextPageToken(list.HasMore, list.LastId); return ClientPage.Create(list.Data, pageToken, nextPageToken, response); } @@ -76,6 +67,32 @@ ClientPage getPage(ClientToken pageToken, RequestOptions? options) return PageCollectionHelpers.Create(firstPageToken, getPage); } + public static IAsyncEnumerable CreateProtocolAsync( + int? limit, string? order, string? after, string? before, RequestOptions? options, + GetPageValuesAsync getPageValuesAsync) + { + OpenAIPageToken firstPageToken = OpenAIPageToken.FromListOptions(limit, order, after, before); + + async Task getPageAsync(ClientToken pageToken) + { + OpenAIPageToken token = (OpenAIPageToken)pageToken; + return await getPageValuesAsync(token.Limit, token.Order, token.After, token.Before, options).ConfigureAwait(false); + } + + ClientToken? getNextPageToken(ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + + using JsonDocument doc = JsonDocument.Parse(response.Content); + bool hasMore = doc.RootElement.GetProperty("has_more"u8).GetBoolean(); + after = doc.RootElement.GetProperty("last_id"u8).GetString(); + + return OpenAIPageToken.GetNextPageToken(limit, order, after, before, hasMore); + } + + return PageCollectionHelpers.CreatePrototolAsync(firstPageToken, getPageAsync, getNextPageToken); + } + public static IEnumerable CreateProtocol( int? limit, string? order, string? after, string? before, RequestOptions? options, GetPageValues getPageValues) @@ -96,7 +113,7 @@ ClientResult getPage(ClientToken pageToken) bool hasMore = doc.RootElement.GetProperty("has_more"u8).GetBoolean(); after = doc.RootElement.GetProperty("last_id"u8).GetString(); - return !hasMore ? null : OpenAIPageToken.FromListOptions(limit, order, after, before); + return OpenAIPageToken.GetNextPageToken(limit, order, after, before, hasMore); } return PageCollectionHelpers.CreatePrototol(firstPageToken, getPage, getNextPageToken); diff --git a/src/Custom/Common/PageCollectionHelpers.cs b/src/Custom/Common/PageCollectionHelpers.cs index cb7f60d64..1fb2c950e 100644 --- a/src/Custom/Common/PageCollectionHelpers.cs +++ b/src/Custom/Common/PageCollectionHelpers.cs @@ -3,6 +3,7 @@ using System.ClientModel.Primitives; using System.Collections; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; #nullable enable @@ -11,25 +12,30 @@ namespace OpenAI; internal class PageCollectionHelpers { - public static AsyncPageCollection Create(ClientToken firstPageToken, + public static AsyncPageCollection CreateAsync(ClientToken firstPageToken, Func>> getPageAsync) where T : notnull - => new FuncAsyncPageCollection(firstPageToken, getPageAsync); + => new AsyncFuncPageCollection(firstPageToken, getPageAsync); public static PageCollection Create(ClientToken firstPageToken, Func> getPage) where T : notnull => new FuncPageCollection(firstPageToken, getPage); + public static IAsyncEnumerable CreatePrototolAsync(ClientToken firstPageToken, + Func> getPageAsync, + Func getNextPageToken) + => new AsyncFuncResultEnumerable(firstPageToken, getPageAsync, getNextPageToken); + public static IEnumerable CreatePrototol(ClientToken firstPageToken, Func getPage, Func getNextPageToken) => new FuncResultEnumerable(firstPageToken, getPage, getNextPageToken); - private class FuncAsyncPageCollection : AsyncPageCollection where T : notnull + private class AsyncFuncPageCollection : AsyncPageCollection where T : notnull { private readonly ClientToken _firstPageToken; private readonly Func>> _getPageAsync; - public FuncAsyncPageCollection(ClientToken firstPageToken, Func>> getPageAsync) + public AsyncFuncPageCollection(ClientToken firstPageToken, Func>> getPageAsync) { _firstPageToken = firstPageToken; _getPageAsync = getPageAsync; @@ -58,6 +64,35 @@ public override ClientPage GetPage(ClientToken pageToken, RequestOptions? opt => _getPage(pageToken, options); } + private class AsyncFuncResultEnumerable : IAsyncEnumerable + { + private readonly ClientToken _firstPageToken; + private readonly Func> _getPageAsync; + private readonly Func _getNextPageToken; + + public AsyncFuncResultEnumerable(ClientToken firstPageToken, + Func> getPageAsync, + Func getNextPageToken) + { + _firstPageToken = firstPageToken; + _getPageAsync = getPageAsync; + _getNextPageToken = getNextPageToken; + } + + public async IAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + ClientToken? pageToken = _firstPageToken; + + do + { + ClientResult result = await _getPageAsync(pageToken).ConfigureAwait(false); + yield return result; + pageToken = _getNextPageToken(result); + } + while (pageToken != null); + } + } + private class FuncResultEnumerable : IEnumerable { private readonly ClientToken _firstPageToken; From bc2004e22c5559d0a6fef3a25cc529f535aa84f8 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Wed, 26 Jun 2024 13:04:45 -0700 Subject: [PATCH 15/72] take BinaryData instead of ClientToken, which cannot be constructed as an abstract type --- src/Custom/Assistants/AssistantClient.cs | 32 ++++++++++++++++-------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/src/Custom/Assistants/AssistantClient.cs b/src/Custom/Assistants/AssistantClient.cs index b58c80260..76fcdf736 100644 --- a/src/Custom/Assistants/AssistantClient.cs +++ b/src/Custom/Assistants/AssistantClient.cs @@ -115,16 +115,22 @@ public virtual ClientResult CreateAssistant(string model, AssistantCr /// A token that can be used to cancel this method call. /// A collection of assistants that can be enumerated using await foreach. public virtual AsyncPageCollection GetAssistantsAsync(ListOrder? resultOrder = default, int? pageSize = default, string afterId = default, string beforeId = default, CancellationToken cancellationToken = default) - => GetAssistantsAsync(OpenAIPageToken.FromListOptions(limit: pageSize, order: resultOrder?.ToString(), after: afterId, before: beforeId)); + { + OpenAIPageToken pageToken = OpenAIPageToken.FromListOptions(limit: pageSize, order: resultOrder?.ToString(), after: afterId, before: beforeId); + return OpenAIPagingHelpers.CreateAsync(pageToken, GetAssistantsPageAsync); + } /// - /// Rehydrates a collection of instances. + /// Rehydrates a collection of instances a page token's serialized bytes. /// - /// Page token indicating the first page of the collection to rehydrate. + /// Serialized page token indicating the first page of the collection to rehydrate. /// A token that can be used to cancel this method call. /// A collection of assistants that can be enumerated using await foreach. - public virtual AsyncPageCollection GetAssistantsAsync(ClientToken firstPageToken, CancellationToken cancellationToken = default) - => OpenAIPagingHelpers.CreateAsync(firstPageToken, GetAssistantsPageAsync); + public virtual AsyncPageCollection GetAssistantsAsync(BinaryData firstPageToken, CancellationToken cancellationToken = default) + { + OpenAIPageToken pageToken = OpenAIPageToken.FromBytes(firstPageToken); + return OpenAIPagingHelpers.CreateAsync(pageToken, GetAssistantsPageAsync); + } /// /// Returns a collection of instances. @@ -139,16 +145,22 @@ public virtual AsyncPageCollection GetAssistantsAsync(ClientToken fir /// A token that can be used to cancel this method call. /// A collection of assistants that can be enumerated using foreach. public virtual PageCollection GetAssistants(ListOrder? resultOrder = default, int? pageSize = default, string afterId = default, string beforeId = default, CancellationToken cancellationToken = default) - => GetAssistants(OpenAIPageToken.FromListOptions(limit: pageSize, order: resultOrder?.ToString(), after: afterId, before: beforeId)); + { + OpenAIPageToken firstPageToken = OpenAIPageToken.FromListOptions(limit: pageSize, order: resultOrder?.ToString(), after: afterId, before: beforeId); + return OpenAIPagingHelpers.Create(firstPageToken, GetAssistantsPage); + } /// - /// Rehydrates a collection of instances. + /// Rehydrates a collection of instances a page token's serialized bytes. /// - /// Page token indicating the first page of the collection to rehydrate. + /// Serialized page token indicating the first page of the collection to rehydrate. /// A token that can be used to cancel this method call. /// A collection of assistants that can be enumerated using foreach. - public virtual PageCollection GetAssistants(ClientToken firstPageToken, CancellationToken cancellationToken = default) - => OpenAIPagingHelpers.Create(firstPageToken, GetAssistantsPage); + public virtual PageCollection GetAssistants(BinaryData firstPageToken, CancellationToken cancellationToken = default) + { + OpenAIPageToken pageToken = OpenAIPageToken.FromBytes(firstPageToken); + return OpenAIPagingHelpers.Create(pageToken, GetAssistantsPage); + } /// /// Deletes an existing . From 6138636f989276a99d15b74b9f4703efc8ae53c7 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Wed, 26 Jun 2024 13:22:29 -0700 Subject: [PATCH 16/72] rework rehydration methods to use new ClientToken pattern --- src/Custom/Assistants/AssistantClient.cs | 16 ++++++++++++---- src/Custom/Common/OpenAIPageToken.cs | 4 +++- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/Custom/Assistants/AssistantClient.cs b/src/Custom/Assistants/AssistantClient.cs index 76fcdf736..d6f3a704e 100644 --- a/src/Custom/Assistants/AssistantClient.cs +++ b/src/Custom/Assistants/AssistantClient.cs @@ -126,9 +126,13 @@ public virtual AsyncPageCollection GetAssistantsAsync(ListOrder? resu /// Serialized page token indicating the first page of the collection to rehydrate. /// A token that can be used to cancel this method call. /// A collection of assistants that can be enumerated using await foreach. - public virtual AsyncPageCollection GetAssistantsAsync(BinaryData firstPageToken, CancellationToken cancellationToken = default) + public virtual AsyncPageCollection GetAssistantsAsync(ClientToken firstPageToken, CancellationToken cancellationToken = default) { - OpenAIPageToken pageToken = OpenAIPageToken.FromBytes(firstPageToken); + if (firstPageToken is not OpenAIPageToken pageToken) + { + pageToken = OpenAIPageToken.FromToken(firstPageToken); + } + return OpenAIPagingHelpers.CreateAsync(pageToken, GetAssistantsPageAsync); } @@ -156,9 +160,13 @@ public virtual PageCollection GetAssistants(ListOrder? resultOrder = /// Serialized page token indicating the first page of the collection to rehydrate. /// A token that can be used to cancel this method call. /// A collection of assistants that can be enumerated using foreach. - public virtual PageCollection GetAssistants(BinaryData firstPageToken, CancellationToken cancellationToken = default) + public virtual PageCollection GetAssistants(ClientToken firstPageToken, CancellationToken cancellationToken = default) { - OpenAIPageToken pageToken = OpenAIPageToken.FromBytes(firstPageToken); + if (firstPageToken is not OpenAIPageToken pageToken) + { + pageToken = OpenAIPageToken.FromToken(firstPageToken); + } + return OpenAIPagingHelpers.Create(pageToken, GetAssistantsPage); } diff --git a/src/Custom/Common/OpenAIPageToken.cs b/src/Custom/Common/OpenAIPageToken.cs index 3b58b31f3..5cfd8c59f 100644 --- a/src/Custom/Common/OpenAIPageToken.cs +++ b/src/Custom/Common/OpenAIPageToken.cs @@ -66,8 +66,10 @@ public override BinaryData ToBytes() public static OpenAIPageToken FromListOptions(int? limit, string? order, string? after, string? before) => new OpenAIPageToken(limit, order, after, before); - public static OpenAIPageToken FromBytes(BinaryData data) + public static OpenAIPageToken FromToken(ClientToken token) { + BinaryData data = token.ToBytes(); + if (data.ToMemory().Length == 0) { return new(default, default, default, default); From bae34b901ca24813408adfefeb853d6bc09a9ffe Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Wed, 26 Jun 2024 13:26:43 -0700 Subject: [PATCH 17/72] add test for rehydration method --- tests/Assistants/AssistantTests.cs | 55 ++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/tests/Assistants/AssistantTests.cs b/tests/Assistants/AssistantTests.cs index 8ca0bf352..6818ce161 100644 --- a/tests/Assistants/AssistantTests.cs +++ b/tests/Assistants/AssistantTests.cs @@ -705,6 +705,61 @@ public async Task CanPageThroughAssistantCollection() Assert.That(pageCount, Is.GreaterThanOrEqualTo(5)); } + + [Test] + public async Task CanRehydratePageCollection() + { + AssistantClient client = GetTestClient(); + + // Create assistant collection + for (int i = 0; i < 10; i++) + { + Assistant assistant = client.CreateAssistant("gpt-3.5-turbo", new AssistantCreationOptions() + { + Name = $"Test Assistant {i}" + }); + Validate(assistant); + Assert.That(assistant.Name, Is.EqualTo($"Test Assistant {i}")); + } + + AsyncPageCollection pages = client.GetAssistantsAsync(ListOrder.NewestFirst, pageSize: 2); + + // Simulate rehydration of the collection + BinaryData rehydrationBytes = pages.FirstPageToken.ToBytes(); + ClientToken rehydrationToken = ClientToken.FromBytes(rehydrationBytes); + + AsyncPageCollection rehydratedPages = client.GetAssistantsAsync(rehydrationToken); + + int count = 0; + int pageCount = 0; + int lastIdSeen = int.MaxValue; + + await foreach (ClientPage page in rehydratedPages) + { + foreach (Assistant assistant in page.Values) + { + Console.WriteLine($"[{count,3}] {assistant.Id} {assistant.CreatedAt:s} {assistant.Name}"); + if (assistant.Name?.StartsWith("Test Assistant ") == true) + { + Assert.That(int.TryParse(assistant.Name["Test Assistant ".Length..], out int seenId), Is.True); + Assert.That(seenId, Is.LessThan(lastIdSeen)); + lastIdSeen = seenId; + } + count++; + } + + pageCount++; + if (lastIdSeen == 0 || count > 100) + { + break; + } + } + + Assert.That(count, Is.GreaterThanOrEqualTo(10)); + Assert.That(pageCount, Is.GreaterThanOrEqualTo(5)); + } + + [Test] public async Task MessagesWithRoles() { From 5283bc5ba47e32c50e9bee219849223b440f48fb Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Wed, 26 Jun 2024 13:32:30 -0700 Subject: [PATCH 18/72] add a second test for rehydration method --- tests/Assistants/AssistantTests.cs | 52 +++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/tests/Assistants/AssistantTests.cs b/tests/Assistants/AssistantTests.cs index 6818ce161..7faf839b3 100644 --- a/tests/Assistants/AssistantTests.cs +++ b/tests/Assistants/AssistantTests.cs @@ -707,7 +707,7 @@ public async Task CanPageThroughAssistantCollection() [Test] - public async Task CanRehydratePageCollection() + public async Task CanRehydratePageCollectionFromBytes() { AssistantClient client = GetTestClient(); @@ -759,6 +759,56 @@ public async Task CanRehydratePageCollection() Assert.That(pageCount, Is.GreaterThanOrEqualTo(5)); } + [Test] + public async Task CanRehydratePageCollectionFromPageToken() + { + AssistantClient client = GetTestClient(); + + // Create assistant collection + for (int i = 0; i < 10; i++) + { + Assistant assistant = client.CreateAssistant("gpt-3.5-turbo", new AssistantCreationOptions() + { + Name = $"Test Assistant {i}" + }); + Validate(assistant); + Assert.That(assistant.Name, Is.EqualTo($"Test Assistant {i}")); + } + + AsyncPageCollection pages = client.GetAssistantsAsync(ListOrder.NewestFirst, pageSize: 2); + + // Call the rehydration method, passing a typed OpenAIPageToken + AsyncPageCollection rehydratedPages = client.GetAssistantsAsync(pages.FirstPageToken); + + int count = 0; + int pageCount = 0; + int lastIdSeen = int.MaxValue; + + await foreach (ClientPage page in rehydratedPages) + { + foreach (Assistant assistant in page.Values) + { + Console.WriteLine($"[{count,3}] {assistant.Id} {assistant.CreatedAt:s} {assistant.Name}"); + if (assistant.Name?.StartsWith("Test Assistant ") == true) + { + Assert.That(int.TryParse(assistant.Name["Test Assistant ".Length..], out int seenId), Is.True); + Assert.That(seenId, Is.LessThan(lastIdSeen)); + lastIdSeen = seenId; + } + count++; + } + + pageCount++; + if (lastIdSeen == 0 || count > 100) + { + break; + } + } + + Assert.That(count, Is.GreaterThanOrEqualTo(10)); + Assert.That(pageCount, Is.GreaterThanOrEqualTo(5)); + } + [Test] public async Task MessagesWithRoles() From e0305ea883171f4df0aa04a6014fcd2a988aa4da Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Wed, 26 Jun 2024 14:11:57 -0700 Subject: [PATCH 19/72] SCM renames --- README.md | 12 ++++++------ .../Assistants/AssistantClient.Convenience.cs | 12 ++++++------ src/Custom/Assistants/AssistantClient.cs | 12 ++++++------ .../Streaming/AsyncStreamingUpdateCollection.cs | 2 +- .../Streaming/StreamingUpdateCollection.cs | 2 +- src/Custom/Chat/ChatClient.cs | 8 ++++---- ...yncStreamingChatCompletionUpdateCollection.cs | 2 +- .../StreamingChatCompletionUpdateCollection.cs | 2 +- src/Custom/Common/OpenAIPagingHelpers.cs | 8 ++++---- src/Custom/Common/PageCollectionHelpers.cs | 16 ++++++++-------- tests/Assistants/AssistantTests.cs | 12 ++++++------ tests/Chat/ChatClientTests.cs | 10 +++++----- 12 files changed, 49 insertions(+), 49 deletions(-) diff --git a/README.md b/README.md index d124cace5..88e4b572c 100644 --- a/README.md +++ b/README.md @@ -115,11 +115,11 @@ When you request a chat completion, the default behavior is for the server to ge The client library offers a convenient approach to working with streaming chat completions. If you wanted to re-write the example from the previous section using streaming, rather than calling the `ChatClient`'s `CompleteChat` method, you would call its `CompleteChatStreaming` method instead: ```csharp -ResultValueCollection updates +CollectionResult updates = client.CompleteChatStreaming("Say 'this is a test.'"); ``` -Notice that the returned value is a `ResultValueCollection` instance, which can be enumerated to process the streaming response chunks as they arrive: +Notice that the returned value is a `CollectionResult` instance, which can be enumerated to process the streaming response chunks as they arrive: ```csharp Console.WriteLine($"[ASSISTANT]:"); @@ -132,10 +132,10 @@ foreach (StreamingChatCompletionUpdate update in updates) } ``` -Alternatively, you can do this asynchronously by calling the `CompleteChatStreamingAsync` method to get an `AsyncResultValueCollection` and enumerate it using `await foreach`: +Alternatively, you can do this asynchronously by calling the `CompleteChatStreamingAsync` method to get an `AsyncCollectionResult` and enumerate it using `await foreach`: ```csharp -AsyncResultValueCollection updates +AsyncCollectionResult updates = client.CompleteChatStreamingAsync("Say 'this is a test.'"); Console.WriteLine($"[ASSISTANT]:"); @@ -640,10 +640,10 @@ AssistantThread thread = assistantClient.CreateThread(new ThreadCreationOptions( }); ``` -With the assistant and thread prepared, use the `CreateRunStreaming` method to get an enumerable `ResultValueCollection`. You can then iterate over this collection with `foreach`. For async calling patterns, use `CreateRunStreamingAsync` and iterate over the `AsyncResultValueCollection` with `await foreach`, instead. Note that streaming variants also exist for `CreateThreadAndRunStreaming` and `SubmitToolOutputsToRunStreaming`. +With the assistant and thread prepared, use the `CreateRunStreaming` method to get an enumerable `CollectionResult`. You can then iterate over this collection with `foreach`. For async calling patterns, use `CreateRunStreamingAsync` and iterate over the `AsyncCollectionResult` with `await foreach`, instead. Note that streaming variants also exist for `CreateThreadAndRunStreaming` and `SubmitToolOutputsToRunStreaming`. ```csharp -ResultValueCollection streamingUpdates = assistantClient.CreateRunStreaming( +CollectionResult streamingUpdates = assistantClient.CreateRunStreaming( thread, assistant, new RunCreationOptions() diff --git a/src/Custom/Assistants/AssistantClient.Convenience.cs b/src/Custom/Assistants/AssistantClient.Convenience.cs index e69b2a95f..1c48698b1 100644 --- a/src/Custom/Assistants/AssistantClient.Convenience.cs +++ b/src/Custom/Assistants/AssistantClient.Convenience.cs @@ -240,7 +240,7 @@ public virtual ClientResult CreateRun(AssistantThread thread, Assista /// The thread that the run should evaluate. /// The assistant that should be used when evaluating the thread. /// Additional options for the run. - public virtual AsyncResultValueCollection CreateRunStreamingAsync( + public virtual AsyncCollectionResult CreateRunStreamingAsync( AssistantThread thread, Assistant assistant, RunCreationOptions options = null) @@ -253,7 +253,7 @@ public virtual AsyncResultValueCollection CreateRunStreamingAsy /// The thread that the run should evaluate. /// The assistant that should be used when evaluating the thread. /// Additional options for the run. - public virtual ResultValueCollection CreateRunStreaming( + public virtual CollectionResult CreateRunStreaming( AssistantThread thread, Assistant assistant, RunCreationOptions options = null) @@ -291,7 +291,7 @@ public virtual ClientResult CreateThreadAndRun( /// The assistant that the new run should use. /// Options for the new thread that will be created. /// Additional options to apply to the run that will begin. - public virtual AsyncResultValueCollection CreateThreadAndRunStreamingAsync( + public virtual AsyncCollectionResult CreateThreadAndRunStreamingAsync( Assistant assistant, ThreadCreationOptions threadOptions = null, RunCreationOptions runOptions = null) @@ -303,7 +303,7 @@ public virtual AsyncResultValueCollection CreateThreadAndRunStr /// The assistant that the new run should use. /// Options for the new thread that will be created. /// Additional options to apply to the run that will begin. - public virtual ResultValueCollection CreateThreadAndRunStreaming( + public virtual CollectionResult CreateThreadAndRunStreaming( Assistant assistant, ThreadCreationOptions threadOptions = null, RunCreationOptions runOptions = null) @@ -394,7 +394,7 @@ public virtual ClientResult SubmitToolOutputsToRun( /// /// The tool outputs, corresponding to instances from the run. /// - public virtual AsyncResultValueCollection SubmitToolOutputsToRunStreamingAsync( + public virtual AsyncCollectionResult SubmitToolOutputsToRunStreamingAsync( ThreadRun run, IEnumerable toolOutputs) => SubmitToolOutputsToRunStreamingAsync(run?.ThreadId, run?.Id, toolOutputs); @@ -406,7 +406,7 @@ public virtual AsyncResultValueCollection SubmitToolOutputsToRu /// /// The tool outputs, corresponding to instances from the run. /// - public virtual ResultValueCollection SubmitToolOutputsToRunStreaming( + public virtual CollectionResult SubmitToolOutputsToRunStreaming( ThreadRun run, IEnumerable toolOutputs) => SubmitToolOutputsToRunStreaming(run?.ThreadId, run?.Id, toolOutputs); diff --git a/src/Custom/Assistants/AssistantClient.cs b/src/Custom/Assistants/AssistantClient.cs index d6f3a704e..1ef6818c5 100644 --- a/src/Custom/Assistants/AssistantClient.cs +++ b/src/Custom/Assistants/AssistantClient.cs @@ -571,7 +571,7 @@ public virtual ClientResult CreateRun(string threadId, string assista /// The ID of the assistant that should be used when evaluating the thread. /// Additional options for the run. /// A token that can be used to cancel this method call. - public virtual AsyncResultValueCollection CreateRunStreamingAsync( + public virtual AsyncCollectionResult CreateRunStreamingAsync( string threadId, string assistantId, RunCreationOptions options = null, @@ -599,7 +599,7 @@ await CreateRunAsync(threadId, options.ToBinaryContent(), cancellationToken.ToRe /// The ID of the assistant that should be used when evaluating the thread. /// Additional options for the run. /// A token that can be used to cancel this method call. - public virtual ResultValueCollection CreateRunStreaming( + public virtual CollectionResult CreateRunStreaming( string threadId, string assistantId, RunCreationOptions options = null, @@ -666,7 +666,7 @@ public virtual ClientResult CreateThreadAndRun( /// Options for the new thread that will be created. /// Additional options to apply to the run that will begin. /// A token that can be used to cancel this method call. - public virtual AsyncResultValueCollection CreateThreadAndRunStreamingAsync( + public virtual AsyncCollectionResult CreateThreadAndRunStreamingAsync( string assistantId, ThreadCreationOptions threadOptions = null, RunCreationOptions runOptions = null, @@ -692,7 +692,7 @@ await CreateThreadAndRunAsync(protocolContent, cancellationToken.ToRequestOption /// Options for the new thread that will be created. /// Additional options to apply to the run that will begin. /// A token that can be used to cancel this method call. - public virtual ResultValueCollection CreateThreadAndRunStreaming( + public virtual CollectionResult CreateThreadAndRunStreaming( string assistantId, ThreadCreationOptions threadOptions = null, RunCreationOptions runOptions = null, @@ -843,7 +843,7 @@ public virtual ClientResult SubmitToolOutputsToRun( /// The tool outputs, corresponding to instances from the run. /// /// A token that can be used to cancel this method call. - public virtual AsyncResultValueCollection SubmitToolOutputsToRunStreamingAsync( + public virtual AsyncCollectionResult SubmitToolOutputsToRunStreamingAsync( string threadId, string runId, IEnumerable toolOutputs, @@ -871,7 +871,7 @@ await SubmitToolOutputsToRunAsync(threadId, runId, content, cancellationToken.To /// The tool outputs, corresponding to instances from the run. /// /// A token that can be used to cancel this method call. - public virtual ResultValueCollection SubmitToolOutputsToRunStreaming( + public virtual CollectionResult SubmitToolOutputsToRunStreaming( string threadId, string runId, IEnumerable toolOutputs, diff --git a/src/Custom/Assistants/Streaming/AsyncStreamingUpdateCollection.cs b/src/Custom/Assistants/Streaming/AsyncStreamingUpdateCollection.cs index 325611128..187163a09 100644 --- a/src/Custom/Assistants/Streaming/AsyncStreamingUpdateCollection.cs +++ b/src/Custom/Assistants/Streaming/AsyncStreamingUpdateCollection.cs @@ -15,7 +15,7 @@ namespace OpenAI.Assistants; /// /// Implementation of collection abstraction over streaming assistant updates. /// -internal class AsyncStreamingUpdateCollection : AsyncResultValueCollection +internal class AsyncStreamingUpdateCollection : AsyncCollectionResult { private readonly Func> _getResultAsync; diff --git a/src/Custom/Assistants/Streaming/StreamingUpdateCollection.cs b/src/Custom/Assistants/Streaming/StreamingUpdateCollection.cs index 4f9b511f8..954bc2284 100644 --- a/src/Custom/Assistants/Streaming/StreamingUpdateCollection.cs +++ b/src/Custom/Assistants/Streaming/StreamingUpdateCollection.cs @@ -13,7 +13,7 @@ namespace OpenAI.Assistants; /// /// Implementation of collection abstraction over streaming assistant updates. /// -internal class StreamingUpdateCollection : ResultValueCollection +internal class StreamingUpdateCollection : CollectionResult { private readonly Func _getResult; diff --git a/src/Custom/Chat/ChatClient.cs b/src/Custom/Chat/ChatClient.cs index 788035217..72b9a5d7d 100644 --- a/src/Custom/Chat/ChatClient.cs +++ b/src/Custom/Chat/ChatClient.cs @@ -132,7 +132,7 @@ public virtual ClientResult CompleteChat(params ChatMessage[] me /// Additional options for the chat completion request. /// A token that can be used to cancel this method call. /// A streaming result with incremental chat completion updates. - public virtual AsyncResultValueCollection CompleteChatStreamingAsync(IEnumerable messages, ChatCompletionOptions options = null, CancellationToken cancellationToken = default) + public virtual AsyncCollectionResult CompleteChatStreamingAsync(IEnumerable messages, ChatCompletionOptions options = null, CancellationToken cancellationToken = default) { Argument.AssertNotNull(messages, nameof(messages)); @@ -156,7 +156,7 @@ async Task getResultAsync() => /// /// The messages to provide as input for chat completion. /// A streaming result with incremental chat completion updates. - public virtual AsyncResultValueCollection CompleteChatStreamingAsync(params ChatMessage[] messages) + public virtual AsyncCollectionResult CompleteChatStreamingAsync(params ChatMessage[] messages) => CompleteChatStreamingAsync(messages, default(ChatCompletionOptions)); /// @@ -171,7 +171,7 @@ public virtual AsyncResultValueCollection Complet /// Additional options for the chat completion request. /// A token that can be used to cancel this method call. /// A streaming result with incremental chat completion updates. - public virtual ResultValueCollection CompleteChatStreaming(IEnumerable messages, ChatCompletionOptions options = null, CancellationToken cancellationToken = default) + public virtual CollectionResult CompleteChatStreaming(IEnumerable messages, ChatCompletionOptions options = null, CancellationToken cancellationToken = default) { Argument.AssertNotNull(messages, nameof(messages)); @@ -193,7 +193,7 @@ public virtual ResultValueCollection CompleteChat /// /// The messages to provide as input for chat completion. /// A streaming result with incremental chat completion updates. - public virtual ResultValueCollection CompleteChatStreaming(params ChatMessage[] messages) + public virtual CollectionResult CompleteChatStreaming(params ChatMessage[] messages) => CompleteChatStreaming(messages, default(ChatCompletionOptions)); private void CreateChatCompletionOptions(IEnumerable messages, ref ChatCompletionOptions options, bool stream = false) diff --git a/src/Custom/Chat/Internal/AsyncStreamingChatCompletionUpdateCollection.cs b/src/Custom/Chat/Internal/AsyncStreamingChatCompletionUpdateCollection.cs index 689a5ed2d..db3781235 100644 --- a/src/Custom/Chat/Internal/AsyncStreamingChatCompletionUpdateCollection.cs +++ b/src/Custom/Chat/Internal/AsyncStreamingChatCompletionUpdateCollection.cs @@ -15,7 +15,7 @@ namespace OpenAI.Chat; /// /// Implementation of collection abstraction over streaming chat updates. /// -internal class AsyncStreamingChatCompletionUpdateCollection : AsyncResultValueCollection +internal class AsyncStreamingChatCompletionUpdateCollection : AsyncCollectionResult { private readonly Func> _getResultAsync; diff --git a/src/Custom/Chat/Internal/StreamingChatCompletionUpdateCollection.cs b/src/Custom/Chat/Internal/StreamingChatCompletionUpdateCollection.cs index c6990fe39..647642c77 100644 --- a/src/Custom/Chat/Internal/StreamingChatCompletionUpdateCollection.cs +++ b/src/Custom/Chat/Internal/StreamingChatCompletionUpdateCollection.cs @@ -14,7 +14,7 @@ namespace OpenAI.Chat; /// /// Implementation of collection abstraction over streaming chat updates. /// -internal class StreamingChatCompletionUpdateCollection : ResultValueCollection +internal class StreamingChatCompletionUpdateCollection : CollectionResult { private readonly Func _getResult; diff --git a/src/Custom/Common/OpenAIPagingHelpers.cs b/src/Custom/Common/OpenAIPagingHelpers.cs index 189064da5..388e3dd68 100644 --- a/src/Custom/Common/OpenAIPagingHelpers.cs +++ b/src/Custom/Common/OpenAIPagingHelpers.cs @@ -19,7 +19,7 @@ public static AsyncPageCollection CreateAsync( where TValue : notnull where TList : IJsonModel, IInternalListResponse { - async Task> getPageAsync(ClientToken pageToken, RequestOptions? options) + async Task> getPageAsync(ClientToken pageToken, RequestOptions? options) { OpenAIPageToken token = (OpenAIPageToken)pageToken; @@ -34,7 +34,7 @@ async Task> getPageAsync(ClientToken pageToken, RequestOption IInternalListResponse list = ModelReaderWriter.Read(response.Content)!; OpenAIPageToken? nextPageToken = token.GetNextPageToken(list.HasMore, list.LastId); - return ClientPage.Create(list.Data, pageToken, nextPageToken, response); + return PageResult.Create(list.Data, pageToken, nextPageToken, response); } return PageCollectionHelpers.CreateAsync(firstPageToken, getPageAsync); @@ -46,7 +46,7 @@ public static PageCollection Create( where TValue : notnull where TList : IJsonModel, IInternalListResponse { - ClientPage getPage(ClientToken pageToken, RequestOptions? options) + PageResult getPage(ClientToken pageToken, RequestOptions? options) { OpenAIPageToken token = (OpenAIPageToken)pageToken; @@ -61,7 +61,7 @@ ClientPage getPage(ClientToken pageToken, RequestOptions? options) IInternalListResponse list = ModelReaderWriter.Read(response.Content)!; OpenAIPageToken? nextPageToken = token.GetNextPageToken(list.HasMore, list.LastId); - return ClientPage.Create(list.Data, pageToken, nextPageToken, response); + return PageResult.Create(list.Data, pageToken, nextPageToken, response); } return PageCollectionHelpers.Create(firstPageToken, getPage); diff --git a/src/Custom/Common/PageCollectionHelpers.cs b/src/Custom/Common/PageCollectionHelpers.cs index 1fb2c950e..377616b12 100644 --- a/src/Custom/Common/PageCollectionHelpers.cs +++ b/src/Custom/Common/PageCollectionHelpers.cs @@ -13,11 +13,11 @@ namespace OpenAI; internal class PageCollectionHelpers { public static AsyncPageCollection CreateAsync(ClientToken firstPageToken, - Func>> getPageAsync) where T : notnull + Func>> getPageAsync) where T : notnull => new AsyncFuncPageCollection(firstPageToken, getPageAsync); public static PageCollection Create(ClientToken firstPageToken, - Func> getPage) where T : notnull + Func> getPage) where T : notnull => new FuncPageCollection(firstPageToken, getPage); public static IAsyncEnumerable CreatePrototolAsync(ClientToken firstPageToken, @@ -33,9 +33,9 @@ public static IEnumerable CreatePrototol(ClientToken firstPageToke private class AsyncFuncPageCollection : AsyncPageCollection where T : notnull { private readonly ClientToken _firstPageToken; - private readonly Func>> _getPageAsync; + private readonly Func>> _getPageAsync; - public AsyncFuncPageCollection(ClientToken firstPageToken, Func>> getPageAsync) + public AsyncFuncPageCollection(ClientToken firstPageToken, Func>> getPageAsync) { _firstPageToken = firstPageToken; _getPageAsync = getPageAsync; @@ -43,16 +43,16 @@ public AsyncFuncPageCollection(ClientToken firstPageToken, Func _firstPageToken; - public override async Task> GetPageAsync(ClientToken pageToken, RequestOptions? options = null) + public override async Task> GetPageAsync(ClientToken pageToken, RequestOptions? options = null) => await _getPageAsync(pageToken, options).ConfigureAwait(false); } private class FuncPageCollection : PageCollection where T : notnull { private readonly ClientToken _firstPageToken; - private readonly Func> _getPage; + private readonly Func> _getPage; - public FuncPageCollection(ClientToken firstPageToken, Func> getPage) + public FuncPageCollection(ClientToken firstPageToken, Func> getPage) { _firstPageToken = firstPageToken; _getPage = getPage; @@ -60,7 +60,7 @@ public FuncPageCollection(ClientToken firstPageToken, Func _firstPageToken; - public override ClientPage GetPage(ClientToken pageToken, RequestOptions? options = null) + public override PageResult GetPage(ClientToken pageToken, RequestOptions? options = null) => _getPage(pageToken, options); } diff --git a/tests/Assistants/AssistantTests.cs b/tests/Assistants/AssistantTests.cs index 7faf839b3..9e1514c6b 100644 --- a/tests/Assistants/AssistantTests.cs +++ b/tests/Assistants/AssistantTests.cs @@ -269,7 +269,7 @@ public void BasicRunStepFunctionalityWorks() Assert.That(run.Usage?.TotalTokens, Is.GreaterThan(0)); PageCollection pages = client.GetRunSteps(run); - ClientPage firstPage = pages.First(); + PageResult firstPage = pages.First(); IEnumerable runSteps = pages.GetAllValues(); Assert.That(runSteps.Count, Is.GreaterThan(1)); @@ -414,7 +414,7 @@ public async Task StreamingRunWorks() Stopwatch stopwatch = Stopwatch.StartNew(); void Print(string message) => Console.WriteLine($"[{stopwatch.ElapsedMilliseconds,6}] {message}"); - AsyncResultValueCollection streamingResult + AsyncCollectionResult streamingResult = client.CreateRunStreamingAsync(thread.Id, assistant.Id); Print(">>> Connected <<<"); @@ -461,7 +461,7 @@ public async Task StreamingToolCall() void Print(string message) => Console.WriteLine($"[{stopwatch.ElapsedMilliseconds,6}] {message}"); Print(" >>> Beginning call ... "); - AsyncResultValueCollection asyncResults = client.CreateThreadAndRunStreamingAsync( + AsyncCollectionResult asyncResults = client.CreateThreadAndRunStreamingAsync( assistant, new() { @@ -680,7 +680,7 @@ public async Task CanPageThroughAssistantCollection() int lastIdSeen = int.MaxValue; - await foreach (ClientPage page in pages) + await foreach (PageResult page in pages) { foreach (Assistant assistant in page.Values) { @@ -734,7 +734,7 @@ public async Task CanRehydratePageCollectionFromBytes() int pageCount = 0; int lastIdSeen = int.MaxValue; - await foreach (ClientPage page in rehydratedPages) + await foreach (PageResult page in rehydratedPages) { foreach (Assistant assistant in page.Values) { @@ -784,7 +784,7 @@ public async Task CanRehydratePageCollectionFromPageToken() int pageCount = 0; int lastIdSeen = int.MaxValue; - await foreach (ClientPage page in rehydratedPages) + await foreach (PageResult page in rehydratedPages) { foreach (Assistant assistant in page.Values) { diff --git a/tests/Chat/ChatClientTests.cs b/tests/Chat/ChatClientTests.cs index 269015590..7cc85239d 100644 --- a/tests/Chat/ChatClientTests.cs +++ b/tests/Chat/ChatClientTests.cs @@ -76,8 +76,8 @@ public void StreamingChat() TimeSpan? latestTokenReceiptTime = null; Stopwatch stopwatch = Stopwatch.StartNew(); - ResultValueCollection streamingResult = client.CompleteChatStreaming(messages); - Assert.That(streamingResult, Is.InstanceOf>()); + CollectionResult streamingResult = client.CompleteChatStreaming(messages); + Assert.That(streamingResult, Is.InstanceOf>()); int updateCount = 0; foreach (StreamingChatCompletionUpdate chatUpdate in streamingResult) @@ -108,8 +108,8 @@ public async Task StreamingChatAsync() TimeSpan? latestTokenReceiptTime = null; Stopwatch stopwatch = Stopwatch.StartNew(); - AsyncResultValueCollection streamingResult = client.CompleteChatStreamingAsync(messages); - Assert.That(streamingResult, Is.InstanceOf>()); + AsyncCollectionResult streamingResult = client.CompleteChatStreamingAsync(messages); + Assert.That(streamingResult, Is.InstanceOf>()); int updateCount = 0; ChatTokenUsage usage = null; @@ -336,7 +336,7 @@ public async Task TokenLogProbabilitiesStreaming(bool includeLogProbabilities) options = new(); } - AsyncResultValueCollection chatCompletionUpdates = client.CompleteChatStreamingAsync(messages, options); + AsyncCollectionResult chatCompletionUpdates = client.CompleteChatStreamingAsync(messages, options); Assert.That(chatCompletionUpdates, Is.Not.Null); await foreach (StreamingChatCompletionUpdate chatCompletionUpdate in chatCompletionUpdates) From 64bea2b3388a0039213366b0627e7b581a791fb7 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Wed, 26 Jun 2024 14:34:12 -0700 Subject: [PATCH 20/72] updates from mini pr review --- .../Example01_RetrievalAugmentedGeneration.cs | 5 +++-- .../Example01_RetrievalAugmentedGenerationAsync.cs | 5 +++-- examples/Assistants/Example02_FunctionCalling.cs | 5 +++-- .../Assistants/Example02_FunctionCallingAsync.cs | 5 +++-- .../Example02b_FunctionCallingStreaming.cs | 2 +- .../Example03_ListAssistantsWithPagination.cs | 4 +++- .../Example03_ListAssistantsWithPaginationAsync.cs | 4 +++- examples/Assistants/Example04_AllTheTools.cs | 5 +++-- .../Assistants/Example05_AssistantsWithVision.cs | 2 +- .../Example05_AssistantsWithVisionAsync.cs | 2 +- examples/Chat/Example02_SimpleChatStreaming.cs | 2 +- examples/Chat/Example02_SimpleChatStreamingAsync.cs | 2 +- examples/Chat/Example04_FunctionCallingStreaming.cs | 2 +- .../Chat/Example04_FunctionCallingStreamingAsync.cs | 2 +- src/Custom/Assistants/AssistantClient.Protocol.cs | 5 ++--- src/Custom/Assistants/AssistantClient.cs | 13 ++++++------- ...ingHelpers.cs => OpenAIPageCollectionHelpers.cs} | 11 ++++++----- src/Custom/VectorStores/VectorStoreClient.cs | 1 - .../Common => Utility}/PageCollectionHelpers.cs | 2 +- tests/Assistants/AssistantTests.cs | 4 ++-- 20 files changed, 45 insertions(+), 38 deletions(-) rename src/Custom/Common/{OpenAIPagingHelpers.cs => OpenAIPageCollectionHelpers.cs} (94%) rename src/{Custom/Common => Utility}/PageCollectionHelpers.cs (99%) diff --git a/examples/Assistants/Example01_RetrievalAugmentedGeneration.cs b/examples/Assistants/Example01_RetrievalAugmentedGeneration.cs index 9d792269d..9998162e1 100644 --- a/examples/Assistants/Example01_RetrievalAugmentedGeneration.cs +++ b/examples/Assistants/Example01_RetrievalAugmentedGeneration.cs @@ -98,10 +98,11 @@ public void Example01_RetrievalAugmentedGeneration() } while (!threadRun.Status.IsTerminal); // Finally, we'll print out the full history for the thread that includes the augmented generation - PageCollection messages + PageCollection messagePages = assistantClient.GetMessages(threadRun.ThreadId, ListOrder.OldestFirst); + IEnumerable messages = messagePages.GetAllValues(); - foreach (ThreadMessage message in messages.GetAllValues()) + foreach (ThreadMessage message in messages) { Console.Write($"[{message.Role.ToString().ToUpper()}]: "); foreach (MessageContent contentItem in message.Content) diff --git a/examples/Assistants/Example01_RetrievalAugmentedGenerationAsync.cs b/examples/Assistants/Example01_RetrievalAugmentedGenerationAsync.cs index 03f1e7aff..f04fd9715 100644 --- a/examples/Assistants/Example01_RetrievalAugmentedGenerationAsync.cs +++ b/examples/Assistants/Example01_RetrievalAugmentedGenerationAsync.cs @@ -99,10 +99,11 @@ public async Task Example01_RetrievalAugmentedGenerationAsync() } while (!threadRun.Status.IsTerminal); // Finally, we'll print out the full history for the thread that includes the augmented generation - AsyncPageCollection messages + AsyncPageCollection messagePages = assistantClient.GetMessagesAsync(threadRun.ThreadId, ListOrder.OldestFirst); + IAsyncEnumerable messages = messagePages.GetAllValuesAsync(); - await foreach (ThreadMessage message in messages.GetAllValuesAsync()) + await foreach (ThreadMessage message in messages) { Console.Write($"[{message.Role.ToString().ToUpper()}]: "); foreach (MessageContent contentItem in message.Content) diff --git a/examples/Assistants/Example02_FunctionCalling.cs b/examples/Assistants/Example02_FunctionCalling.cs index 50f62df73..4af074c79 100644 --- a/examples/Assistants/Example02_FunctionCalling.cs +++ b/examples/Assistants/Example02_FunctionCalling.cs @@ -151,10 +151,11 @@ string GetCurrentWeather(string location, string unit = "celsius") // With the run complete, list the messages and display their content if (run.Status == RunStatus.Completed) { - PageCollection messages + PageCollection messagePages = client.GetMessages(run.ThreadId, resultOrder: ListOrder.OldestFirst); + IEnumerable messages = messagePages.GetAllValues(); - foreach (ThreadMessage message in messages.GetAllValues()) + foreach (ThreadMessage message in messages) { Console.WriteLine($"[{message.Role.ToString().ToUpper()}]: "); foreach (MessageContent contentItem in message.Content) diff --git a/examples/Assistants/Example02_FunctionCallingAsync.cs b/examples/Assistants/Example02_FunctionCallingAsync.cs index 96d2e43eb..4add93b9a 100644 --- a/examples/Assistants/Example02_FunctionCallingAsync.cs +++ b/examples/Assistants/Example02_FunctionCallingAsync.cs @@ -151,10 +151,11 @@ string GetCurrentWeather(string location, string unit = "celsius") // With the run complete, list the messages and display their content if (run.Status == RunStatus.Completed) { - AsyncPageCollection messages + AsyncPageCollection messagePages = client.GetMessagesAsync(run.ThreadId, resultOrder: ListOrder.OldestFirst); + IAsyncEnumerable messages = messagePages.GetAllValuesAsync(); - await foreach (ThreadMessage message in messages.GetAllValuesAsync()) + await foreach (ThreadMessage message in messages) { Console.WriteLine($"[{message.Role.ToString().ToUpper()}]: "); foreach (MessageContent contentItem in message.Content) diff --git a/examples/Assistants/Example02b_FunctionCallingStreaming.cs b/examples/Assistants/Example02b_FunctionCallingStreaming.cs index 06ae7df7d..9c3e0adfc 100644 --- a/examples/Assistants/Example02b_FunctionCallingStreaming.cs +++ b/examples/Assistants/Example02b_FunctionCallingStreaming.cs @@ -91,7 +91,7 @@ public async Task Example02b_FunctionCallingStreaming() #endregion #region Step 3 - Initiate a streaming run - AsyncResultValueCollection asyncUpdates + AsyncCollectionResult asyncUpdates = client.CreateRunStreamingAsync(thread, assistant); ThreadRun currentRun = null; diff --git a/examples/Assistants/Example03_ListAssistantsWithPagination.cs b/examples/Assistants/Example03_ListAssistantsWithPagination.cs index 39533ccb9..e8640f1c5 100644 --- a/examples/Assistants/Example03_ListAssistantsWithPagination.cs +++ b/examples/Assistants/Example03_ListAssistantsWithPagination.cs @@ -1,6 +1,7 @@ using NUnit.Framework; using OpenAI.Assistants; using System; +using System.ClientModel; using System.Collections.Generic; namespace OpenAI.Examples; @@ -16,7 +17,8 @@ public void Example03_ListAssistantsWithPagination() int count = 0; - IEnumerable assistants = client.GetAssistants().GetAllValues(); + PageCollection assitantPages = client.GetAssistants(); + IEnumerable assistants = assitantPages.GetAllValues(); foreach (Assistant assistant in assistants) { Console.WriteLine($"[{count,3}] {assistant.Id} {assistant.CreatedAt:s} {assistant.Name}"); diff --git a/examples/Assistants/Example03_ListAssistantsWithPaginationAsync.cs b/examples/Assistants/Example03_ListAssistantsWithPaginationAsync.cs index 477e53add..fa67a713f 100644 --- a/examples/Assistants/Example03_ListAssistantsWithPaginationAsync.cs +++ b/examples/Assistants/Example03_ListAssistantsWithPaginationAsync.cs @@ -1,6 +1,7 @@ using NUnit.Framework; using OpenAI.Assistants; using System; +using System.ClientModel; using System.Collections.Generic; using System.Threading.Tasks; @@ -17,7 +18,8 @@ public async Task Example03_ListAssistantsWithPaginationAsync() int count = 0; - IAsyncEnumerable assistants = client.GetAssistantsAsync().GetAllValuesAsync(); + AsyncPageCollection assitantPages = client.GetAssistantsAsync(); + IAsyncEnumerable assistants = assitantPages.GetAllValuesAsync(); await foreach (Assistant assistant in assistants) { Console.WriteLine($"[{count,3}] {assistant.Id} {assistant.CreatedAt:s} {assistant.Name}"); diff --git a/examples/Assistants/Example04_AllTheTools.cs b/examples/Assistants/Example04_AllTheTools.cs index bbaa45131..61be9f4a5 100644 --- a/examples/Assistants/Example04_AllTheTools.cs +++ b/examples/Assistants/Example04_AllTheTools.cs @@ -137,10 +137,11 @@ static string GetNameOfFamilyMember(string relation) // With the run complete, list the messages and display their content if (run.Status == RunStatus.Completed) { - PageCollection messages + PageCollection messagePages = client.GetMessages(run.ThreadId, resultOrder: ListOrder.OldestFirst); + IEnumerable messages = messagePages.GetAllValues(); - foreach (ThreadMessage message in messages.GetAllValues()) + foreach (ThreadMessage message in messages) { Console.WriteLine($"[{message.Role.ToString().ToUpper()}]: "); foreach (MessageContent contentItem in message.Content) diff --git a/examples/Assistants/Example05_AssistantsWithVision.cs b/examples/Assistants/Example05_AssistantsWithVision.cs index f1e2a64a9..4d10c84cf 100644 --- a/examples/Assistants/Example05_AssistantsWithVision.cs +++ b/examples/Assistants/Example05_AssistantsWithVision.cs @@ -44,7 +44,7 @@ public void Example05_AssistantsWithVision() } }); - ResultValueCollection streamingUpdates = assistantClient.CreateRunStreaming( + CollectionResult streamingUpdates = assistantClient.CreateRunStreaming( thread, assistant, new RunCreationOptions() diff --git a/examples/Assistants/Example05_AssistantsWithVisionAsync.cs b/examples/Assistants/Example05_AssistantsWithVisionAsync.cs index df27d894d..3f79137e8 100644 --- a/examples/Assistants/Example05_AssistantsWithVisionAsync.cs +++ b/examples/Assistants/Example05_AssistantsWithVisionAsync.cs @@ -45,7 +45,7 @@ public async Task Example05_AssistantsWithVisionAsync() } }); - AsyncResultValueCollection streamingUpdates = assistantClient.CreateRunStreamingAsync( + AsyncCollectionResult streamingUpdates = assistantClient.CreateRunStreamingAsync( thread, assistant, new RunCreationOptions() diff --git a/examples/Chat/Example02_SimpleChatStreaming.cs b/examples/Chat/Example02_SimpleChatStreaming.cs index 1c6c75c41..50b8938f0 100644 --- a/examples/Chat/Example02_SimpleChatStreaming.cs +++ b/examples/Chat/Example02_SimpleChatStreaming.cs @@ -12,7 +12,7 @@ public void Example02_SimpleChatStreaming() { ChatClient client = new(model: "gpt-4o", Environment.GetEnvironmentVariable("OPENAI_API_KEY")); - ResultValueCollection updates + CollectionResult updates = client.CompleteChatStreaming("Say 'this is a test.'"); Console.WriteLine($"[ASSISTANT]:"); diff --git a/examples/Chat/Example02_SimpleChatStreamingAsync.cs b/examples/Chat/Example02_SimpleChatStreamingAsync.cs index 11afc0222..c22bb4d8f 100644 --- a/examples/Chat/Example02_SimpleChatStreamingAsync.cs +++ b/examples/Chat/Example02_SimpleChatStreamingAsync.cs @@ -13,7 +13,7 @@ public async Task Example02_SimpleChatStreamingAsync() { ChatClient client = new(model: "gpt-4o", Environment.GetEnvironmentVariable("OPENAI_API_KEY")); - AsyncResultValueCollection updates + AsyncCollectionResult updates = client.CompleteChatStreamingAsync("Say 'this is a test.'"); Console.WriteLine($"[ASSISTANT]:"); diff --git a/examples/Chat/Example04_FunctionCallingStreaming.cs b/examples/Chat/Example04_FunctionCallingStreaming.cs index 50ad08f31..3f0770692 100644 --- a/examples/Chat/Example04_FunctionCallingStreaming.cs +++ b/examples/Chat/Example04_FunctionCallingStreaming.cs @@ -38,7 +38,7 @@ public void Example04_FunctionCallingStreaming() Dictionary indexToFunctionName = []; Dictionary indexToFunctionArguments = []; StringBuilder contentBuilder = new(); - ResultValueCollection chatUpdates + CollectionResult chatUpdates = client.CompleteChatStreaming(messages, options); foreach (StreamingChatCompletionUpdate chatUpdate in chatUpdates) diff --git a/examples/Chat/Example04_FunctionCallingStreamingAsync.cs b/examples/Chat/Example04_FunctionCallingStreamingAsync.cs index d585424a0..6fac2c494 100644 --- a/examples/Chat/Example04_FunctionCallingStreamingAsync.cs +++ b/examples/Chat/Example04_FunctionCallingStreamingAsync.cs @@ -39,7 +39,7 @@ public async Task Example04_FunctionCallingStreamingAsync() Dictionary indexToFunctionName = []; Dictionary indexToFunctionArguments = []; StringBuilder contentBuilder = new(); - AsyncResultValueCollection chatUpdates + AsyncCollectionResult chatUpdates = client.CompleteChatStreamingAsync(messages, options); await foreach (StreamingChatCompletionUpdate chatUpdate in chatUpdates) diff --git a/src/Custom/Assistants/AssistantClient.Protocol.cs b/src/Custom/Assistants/AssistantClient.Protocol.cs index 0287dd1fc..dcc9317d0 100644 --- a/src/Custom/Assistants/AssistantClient.Protocol.cs +++ b/src/Custom/Assistants/AssistantClient.Protocol.cs @@ -65,7 +65,7 @@ public virtual ClientResult CreateAssistant(BinaryContent content, RequestOption /// Service returned a non-success status code. /// The response returned from the service. public virtual IAsyncEnumerable GetAssistantsAsync(int? limit, string order, string after, string before, RequestOptions options) - => OpenAIPagingHelpers.CreateProtocolAsync(limit, order, after, before, options, GetAssistantsPageAsync); + => OpenAIPageCollectionHelpers.CreateProtocolAsync(limit, order, after, before, options, GetAssistantsPageAsync); internal virtual async Task GetAssistantsPageAsync(int? limit, string order, string after, string before, RequestOptions options) { @@ -98,9 +98,8 @@ internal virtual async Task GetAssistantsPageAsync(int? limit, str /// Service returned a non-success status code. /// The response returned from the service. public virtual IEnumerable GetAssistants(int? limit, string order, string after, string before, RequestOptions options) - => OpenAIPagingHelpers.CreateProtocol(limit, order, after, before, options, GetAssistantsPage); + => OpenAIPageCollectionHelpers.CreateProtocol(limit, order, after, before, options, GetAssistantsPage); - // This needs to be internal now internal virtual ClientResult GetAssistantsPage(int? limit, string order, string after, string before, RequestOptions options) { using PipelineMessage message = CreateGetAssistantsRequest(limit, order, after, before, options); diff --git a/src/Custom/Assistants/AssistantClient.cs b/src/Custom/Assistants/AssistantClient.cs index 1ef6818c5..ca9bf9fc9 100644 --- a/src/Custom/Assistants/AssistantClient.cs +++ b/src/Custom/Assistants/AssistantClient.cs @@ -7,7 +7,6 @@ using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; -//using static OpenAI.InternalListHelpers; namespace OpenAI.Assistants; @@ -114,10 +113,10 @@ public virtual ClientResult CreateAssistant(string model, AssistantCr /// The id of the item following the last item in the collection. /// A token that can be used to cancel this method call. /// A collection of assistants that can be enumerated using await foreach. - public virtual AsyncPageCollection GetAssistantsAsync(ListOrder? resultOrder = default, int? pageSize = default, string afterId = default, string beforeId = default, CancellationToken cancellationToken = default) + public virtual AsyncPageCollection GetAssistantsAsync(ListOrder? resultOrder = null, int? pageSize = null, string afterId = default, string beforeId = default, CancellationToken cancellationToken = default) { OpenAIPageToken pageToken = OpenAIPageToken.FromListOptions(limit: pageSize, order: resultOrder?.ToString(), after: afterId, before: beforeId); - return OpenAIPagingHelpers.CreateAsync(pageToken, GetAssistantsPageAsync); + return OpenAIPageCollectionHelpers.CreateAsync(pageToken, GetAssistantsPageAsync); } /// @@ -133,7 +132,7 @@ public virtual AsyncPageCollection GetAssistantsAsync(ClientToken fir pageToken = OpenAIPageToken.FromToken(firstPageToken); } - return OpenAIPagingHelpers.CreateAsync(pageToken, GetAssistantsPageAsync); + return OpenAIPageCollectionHelpers.CreateAsync(pageToken, GetAssistantsPageAsync); } /// @@ -148,10 +147,10 @@ public virtual AsyncPageCollection GetAssistantsAsync(ClientToken fir /// The id of the item following the last item in the collection. /// A token that can be used to cancel this method call. /// A collection of assistants that can be enumerated using foreach. - public virtual PageCollection GetAssistants(ListOrder? resultOrder = default, int? pageSize = default, string afterId = default, string beforeId = default, CancellationToken cancellationToken = default) + public virtual PageCollection GetAssistants(ListOrder? resultOrder = null, int? pageSize = null, string afterId = default, string beforeId = default, CancellationToken cancellationToken = default) { OpenAIPageToken firstPageToken = OpenAIPageToken.FromListOptions(limit: pageSize, order: resultOrder?.ToString(), after: afterId, before: beforeId); - return OpenAIPagingHelpers.Create(firstPageToken, GetAssistantsPage); + return OpenAIPageCollectionHelpers.Create(firstPageToken, GetAssistantsPage); } /// @@ -167,7 +166,7 @@ public virtual PageCollection GetAssistants(ClientToken firstPageToke pageToken = OpenAIPageToken.FromToken(firstPageToken); } - return OpenAIPagingHelpers.Create(pageToken, GetAssistantsPage); + return OpenAIPageCollectionHelpers.Create(pageToken, GetAssistantsPage); } /// diff --git a/src/Custom/Common/OpenAIPagingHelpers.cs b/src/Custom/Common/OpenAIPageCollectionHelpers.cs similarity index 94% rename from src/Custom/Common/OpenAIPagingHelpers.cs rename to src/Custom/Common/OpenAIPageCollectionHelpers.cs index 388e3dd68..03a11fd86 100644 --- a/src/Custom/Common/OpenAIPagingHelpers.cs +++ b/src/Custom/Common/OpenAIPageCollectionHelpers.cs @@ -3,19 +3,20 @@ using System.Collections.Generic; using System.Text.Json; using System.Threading.Tasks; +using OpenAI.Utility; #nullable enable namespace OpenAI; -internal class OpenAIPagingHelpers +internal class OpenAIPageCollectionHelpers { public delegate Task GetPageValuesAsync(int? limit, string? order, string? after, string? before, RequestOptions? options); public delegate ClientResult GetPageValues(int? limit, string? order, string? after, string? before, RequestOptions? options); public static AsyncPageCollection CreateAsync( ClientToken firstPageToken, - GetPageValuesAsync getListValuesAsync) + GetPageValuesAsync getPageValuesAsync) where TValue : notnull where TList : IJsonModel, IInternalListResponse { @@ -23,7 +24,7 @@ async Task> getPageAsync(ClientToken pageToken, RequestOption { OpenAIPageToken token = (OpenAIPageToken)pageToken; - ClientResult result = await getListValuesAsync( + ClientResult result = await getPageValuesAsync( limit: token.Limit, order: token.Order, after: token.After, @@ -42,7 +43,7 @@ async Task> getPageAsync(ClientToken pageToken, RequestOption public static PageCollection Create( ClientToken firstPageToken, - GetPageValues getListValues) + GetPageValues getPageValues) where TValue : notnull where TList : IJsonModel, IInternalListResponse { @@ -50,7 +51,7 @@ PageResult getPage(ClientToken pageToken, RequestOptions? options) { OpenAIPageToken token = (OpenAIPageToken)pageToken; - ClientResult result = getListValues( + ClientResult result = getPageValues( limit: token.Limit, order: token.Order, after: token.After, diff --git a/src/Custom/VectorStores/VectorStoreClient.cs b/src/Custom/VectorStores/VectorStoreClient.cs index 4acbc19e6..60ec1c83e 100644 --- a/src/Custom/VectorStores/VectorStoreClient.cs +++ b/src/Custom/VectorStores/VectorStoreClient.cs @@ -8,7 +8,6 @@ using System.Diagnostics.CodeAnalysis; using System.Threading; using System.Threading.Tasks; -//using static OpenAI.InternalListHelpers; namespace OpenAI.VectorStores; diff --git a/src/Custom/Common/PageCollectionHelpers.cs b/src/Utility/PageCollectionHelpers.cs similarity index 99% rename from src/Custom/Common/PageCollectionHelpers.cs rename to src/Utility/PageCollectionHelpers.cs index 377616b12..055dbb8dd 100644 --- a/src/Custom/Common/PageCollectionHelpers.cs +++ b/src/Utility/PageCollectionHelpers.cs @@ -8,7 +8,7 @@ #nullable enable -namespace OpenAI; +namespace OpenAI.Utility; internal class PageCollectionHelpers { diff --git a/tests/Assistants/AssistantTests.cs b/tests/Assistants/AssistantTests.cs index 9e1514c6b..aaa8661f8 100644 --- a/tests/Assistants/AssistantTests.cs +++ b/tests/Assistants/AssistantTests.cs @@ -1,4 +1,5 @@ -using NUnit.Framework; + +using NUnit.Framework; using OpenAI.Assistants; using OpenAI.Files; using OpenAI.VectorStores; @@ -809,7 +810,6 @@ public async Task CanRehydratePageCollectionFromPageToken() Assert.That(pageCount, Is.GreaterThanOrEqualTo(5)); } - [Test] public async Task MessagesWithRoles() { From ea8db962f63c782f03989ece9bae40742434b55a Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Wed, 26 Jun 2024 15:07:16 -0700 Subject: [PATCH 21/72] rework RequestOptions --- src/Custom/Assistants/AssistantClient.cs | 8 +++---- .../Common/OpenAIPageCollectionHelpers.cs | 10 ++++---- src/Utility/PageCollectionHelpers.cs | 23 ++++++++++--------- 3 files changed, 22 insertions(+), 19 deletions(-) diff --git a/src/Custom/Assistants/AssistantClient.cs b/src/Custom/Assistants/AssistantClient.cs index ca9bf9fc9..48599ca4b 100644 --- a/src/Custom/Assistants/AssistantClient.cs +++ b/src/Custom/Assistants/AssistantClient.cs @@ -116,7 +116,7 @@ public virtual ClientResult CreateAssistant(string model, AssistantCr public virtual AsyncPageCollection GetAssistantsAsync(ListOrder? resultOrder = null, int? pageSize = null, string afterId = default, string beforeId = default, CancellationToken cancellationToken = default) { OpenAIPageToken pageToken = OpenAIPageToken.FromListOptions(limit: pageSize, order: resultOrder?.ToString(), after: afterId, before: beforeId); - return OpenAIPageCollectionHelpers.CreateAsync(pageToken, GetAssistantsPageAsync); + return OpenAIPageCollectionHelpers.CreateAsync(pageToken, GetAssistantsPageAsync, cancellationToken.ToRequestOptions()); } /// @@ -132,7 +132,7 @@ public virtual AsyncPageCollection GetAssistantsAsync(ClientToken fir pageToken = OpenAIPageToken.FromToken(firstPageToken); } - return OpenAIPageCollectionHelpers.CreateAsync(pageToken, GetAssistantsPageAsync); + return OpenAIPageCollectionHelpers.CreateAsync(pageToken, GetAssistantsPageAsync, cancellationToken.ToRequestOptions()); } /// @@ -150,7 +150,7 @@ public virtual AsyncPageCollection GetAssistantsAsync(ClientToken fir public virtual PageCollection GetAssistants(ListOrder? resultOrder = null, int? pageSize = null, string afterId = default, string beforeId = default, CancellationToken cancellationToken = default) { OpenAIPageToken firstPageToken = OpenAIPageToken.FromListOptions(limit: pageSize, order: resultOrder?.ToString(), after: afterId, before: beforeId); - return OpenAIPageCollectionHelpers.Create(firstPageToken, GetAssistantsPage); + return OpenAIPageCollectionHelpers.Create(firstPageToken, GetAssistantsPage, cancellationToken.ToRequestOptions()); } /// @@ -166,7 +166,7 @@ public virtual PageCollection GetAssistants(ClientToken firstPageToke pageToken = OpenAIPageToken.FromToken(firstPageToken); } - return OpenAIPageCollectionHelpers.Create(pageToken, GetAssistantsPage); + return OpenAIPageCollectionHelpers.Create(pageToken, GetAssistantsPage, cancellationToken.ToRequestOptions()); } /// diff --git a/src/Custom/Common/OpenAIPageCollectionHelpers.cs b/src/Custom/Common/OpenAIPageCollectionHelpers.cs index 03a11fd86..37d7c4658 100644 --- a/src/Custom/Common/OpenAIPageCollectionHelpers.cs +++ b/src/Custom/Common/OpenAIPageCollectionHelpers.cs @@ -16,11 +16,12 @@ internal class OpenAIPageCollectionHelpers public static AsyncPageCollection CreateAsync( ClientToken firstPageToken, - GetPageValuesAsync getPageValuesAsync) + GetPageValuesAsync getPageValuesAsync, + RequestOptions? options) where TValue : notnull where TList : IJsonModel, IInternalListResponse { - async Task> getPageAsync(ClientToken pageToken, RequestOptions? options) + async Task> getPageAsync(ClientToken pageToken) { OpenAIPageToken token = (OpenAIPageToken)pageToken; @@ -43,11 +44,12 @@ async Task> getPageAsync(ClientToken pageToken, RequestOption public static PageCollection Create( ClientToken firstPageToken, - GetPageValues getPageValues) + GetPageValues getPageValues, + RequestOptions? options) where TValue : notnull where TList : IJsonModel, IInternalListResponse { - PageResult getPage(ClientToken pageToken, RequestOptions? options) + PageResult getPage(ClientToken pageToken) { OpenAIPageToken token = (OpenAIPageToken)pageToken; diff --git a/src/Utility/PageCollectionHelpers.cs b/src/Utility/PageCollectionHelpers.cs index 055dbb8dd..8df67c549 100644 --- a/src/Utility/PageCollectionHelpers.cs +++ b/src/Utility/PageCollectionHelpers.cs @@ -1,6 +1,5 @@ using System; using System.ClientModel; -using System.ClientModel.Primitives; using System.Collections; using System.Collections.Generic; using System.Threading; @@ -13,11 +12,11 @@ namespace OpenAI.Utility; internal class PageCollectionHelpers { public static AsyncPageCollection CreateAsync(ClientToken firstPageToken, - Func>> getPageAsync) where T : notnull + Func>> getPageAsync) where T : notnull => new AsyncFuncPageCollection(firstPageToken, getPageAsync); public static PageCollection Create(ClientToken firstPageToken, - Func> getPage) where T : notnull + Func> getPage) where T : notnull => new FuncPageCollection(firstPageToken, getPage); public static IAsyncEnumerable CreatePrototolAsync(ClientToken firstPageToken, @@ -33,9 +32,10 @@ public static IEnumerable CreatePrototol(ClientToken firstPageToke private class AsyncFuncPageCollection : AsyncPageCollection where T : notnull { private readonly ClientToken _firstPageToken; - private readonly Func>> _getPageAsync; + private readonly Func>> _getPageAsync; - public AsyncFuncPageCollection(ClientToken firstPageToken, Func>> getPageAsync) + public AsyncFuncPageCollection(ClientToken firstPageToken, + Func>> getPageAsync) { _firstPageToken = firstPageToken; _getPageAsync = getPageAsync; @@ -43,16 +43,17 @@ public AsyncFuncPageCollection(ClientToken firstPageToken, Func _firstPageToken; - public override async Task> GetPageAsync(ClientToken pageToken, RequestOptions? options = null) - => await _getPageAsync(pageToken, options).ConfigureAwait(false); + public override async Task> GetPageAsync(ClientToken pageToken) + => await _getPageAsync(pageToken).ConfigureAwait(false); } private class FuncPageCollection : PageCollection where T : notnull { private readonly ClientToken _firstPageToken; - private readonly Func> _getPage; + private readonly Func> _getPage; - public FuncPageCollection(ClientToken firstPageToken, Func> getPage) + public FuncPageCollection(ClientToken firstPageToken, + Func> getPage) { _firstPageToken = firstPageToken; _getPage = getPage; @@ -60,8 +61,8 @@ public FuncPageCollection(ClientToken firstPageToken, Func _firstPageToken; - public override PageResult GetPage(ClientToken pageToken, RequestOptions? options = null) - => _getPage(pageToken, options); + public override PageResult GetPage(ClientToken pageToken) + => _getPage(pageToken); } private class AsyncFuncResultEnumerable : IAsyncEnumerable From bcfed80683252b7df9c7879e0c27c543461ff49c Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Wed, 26 Jun 2024 16:35:43 -0700 Subject: [PATCH 22/72] bug fix --- src/Custom/Assistants/AssistantClient.cs | 24 +++++++------------ .../Common/OpenAIPageCollectionHelpers.cs | 4 ++-- src/Custom/Common/OpenAIPageToken.cs | 5 ++++ 3 files changed, 15 insertions(+), 18 deletions(-) diff --git a/src/Custom/Assistants/AssistantClient.cs b/src/Custom/Assistants/AssistantClient.cs index 48599ca4b..c2a8dff4e 100644 --- a/src/Custom/Assistants/AssistantClient.cs +++ b/src/Custom/Assistants/AssistantClient.cs @@ -104,7 +104,7 @@ public virtual ClientResult CreateAssistant(string model, AssistantCr /// /// Returns a collection of instances. /// - /// + /// /// The order that results should appear in the list according to their created_at /// timestamp. /// @@ -113,9 +113,9 @@ public virtual ClientResult CreateAssistant(string model, AssistantCr /// The id of the item following the last item in the collection. /// A token that can be used to cancel this method call. /// A collection of assistants that can be enumerated using await foreach. - public virtual AsyncPageCollection GetAssistantsAsync(ListOrder? resultOrder = null, int? pageSize = null, string afterId = default, string beforeId = default, CancellationToken cancellationToken = default) + public virtual AsyncPageCollection GetAssistantsAsync(ListOrder? order = null, int? pageSize = null, string afterId = default, string beforeId = default, CancellationToken cancellationToken = default) { - OpenAIPageToken pageToken = OpenAIPageToken.FromListOptions(limit: pageSize, order: resultOrder?.ToString(), after: afterId, before: beforeId); + OpenAIPageToken pageToken = OpenAIPageToken.FromListOptions(limit: pageSize, order: order?.ToString(), after: afterId, before: beforeId); return OpenAIPageCollectionHelpers.CreateAsync(pageToken, GetAssistantsPageAsync, cancellationToken.ToRequestOptions()); } @@ -127,18 +127,14 @@ public virtual AsyncPageCollection GetAssistantsAsync(ListOrder? resu /// A collection of assistants that can be enumerated using await foreach. public virtual AsyncPageCollection GetAssistantsAsync(ClientToken firstPageToken, CancellationToken cancellationToken = default) { - if (firstPageToken is not OpenAIPageToken pageToken) - { - pageToken = OpenAIPageToken.FromToken(firstPageToken); - } - + OpenAIPageToken pageToken = OpenAIPageToken.FromToken(firstPageToken); return OpenAIPageCollectionHelpers.CreateAsync(pageToken, GetAssistantsPageAsync, cancellationToken.ToRequestOptions()); } /// /// Returns a collection of instances. /// - /// + /// /// The order that results should appear in the list according to their created_at /// timestamp. /// @@ -147,9 +143,9 @@ public virtual AsyncPageCollection GetAssistantsAsync(ClientToken fir /// The id of the item following the last item in the collection. /// A token that can be used to cancel this method call. /// A collection of assistants that can be enumerated using foreach. - public virtual PageCollection GetAssistants(ListOrder? resultOrder = null, int? pageSize = null, string afterId = default, string beforeId = default, CancellationToken cancellationToken = default) + public virtual PageCollection GetAssistants(ListOrder? order = null, int? pageSize = null, string afterId = default, string beforeId = default, CancellationToken cancellationToken = default) { - OpenAIPageToken firstPageToken = OpenAIPageToken.FromListOptions(limit: pageSize, order: resultOrder?.ToString(), after: afterId, before: beforeId); + OpenAIPageToken firstPageToken = OpenAIPageToken.FromListOptions(limit: pageSize, order: order?.ToString(), after: afterId, before: beforeId); return OpenAIPageCollectionHelpers.Create(firstPageToken, GetAssistantsPage, cancellationToken.ToRequestOptions()); } @@ -161,11 +157,7 @@ public virtual PageCollection GetAssistants(ListOrder? resultOrder = /// A collection of assistants that can be enumerated using foreach. public virtual PageCollection GetAssistants(ClientToken firstPageToken, CancellationToken cancellationToken = default) { - if (firstPageToken is not OpenAIPageToken pageToken) - { - pageToken = OpenAIPageToken.FromToken(firstPageToken); - } - + OpenAIPageToken pageToken = OpenAIPageToken.FromToken(firstPageToken); return OpenAIPageCollectionHelpers.Create(pageToken, GetAssistantsPage, cancellationToken.ToRequestOptions()); } diff --git a/src/Custom/Common/OpenAIPageCollectionHelpers.cs b/src/Custom/Common/OpenAIPageCollectionHelpers.cs index 37d7c4658..1d6dbe6e3 100644 --- a/src/Custom/Common/OpenAIPageCollectionHelpers.cs +++ b/src/Custom/Common/OpenAIPageCollectionHelpers.cs @@ -23,7 +23,7 @@ public static AsyncPageCollection CreateAsync( { async Task> getPageAsync(ClientToken pageToken) { - OpenAIPageToken token = (OpenAIPageToken)pageToken; + OpenAIPageToken token = OpenAIPageToken.FromToken(pageToken); ClientResult result = await getPageValuesAsync( limit: token.Limit, @@ -51,7 +51,7 @@ public static PageCollection Create( { PageResult getPage(ClientToken pageToken) { - OpenAIPageToken token = (OpenAIPageToken)pageToken; + OpenAIPageToken token = OpenAIPageToken.FromToken(pageToken); ClientResult result = getPageValues( limit: token.Limit, diff --git a/src/Custom/Common/OpenAIPageToken.cs b/src/Custom/Common/OpenAIPageToken.cs index 5cfd8c59f..bbda1cfcb 100644 --- a/src/Custom/Common/OpenAIPageToken.cs +++ b/src/Custom/Common/OpenAIPageToken.cs @@ -68,6 +68,11 @@ public static OpenAIPageToken FromListOptions(int? limit, string? order, string? public static OpenAIPageToken FromToken(ClientToken token) { + if (token is OpenAIPageToken openAIPageToken) + { + return openAIPageToken; + } + BinaryData data = token.ToBytes(); if (data.ToMemory().Length == 0) From e36556680cdbcdbbb85b187213ae1f4e7468ad8b Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Wed, 26 Jun 2024 17:46:28 -0700 Subject: [PATCH 23/72] GetPageCore --- src/Utility/PageCollectionHelpers.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Utility/PageCollectionHelpers.cs b/src/Utility/PageCollectionHelpers.cs index 8df67c549..c7582a374 100644 --- a/src/Utility/PageCollectionHelpers.cs +++ b/src/Utility/PageCollectionHelpers.cs @@ -43,7 +43,7 @@ public AsyncFuncPageCollection(ClientToken firstPageToken, public override ClientToken FirstPageToken => _firstPageToken; - public override async Task> GetPageAsync(ClientToken pageToken) + public override async Task> GetPageAsyncCore(ClientToken pageToken) => await _getPageAsync(pageToken).ConfigureAwait(false); } @@ -61,7 +61,7 @@ public FuncPageCollection(ClientToken firstPageToken, public override ClientToken FirstPageToken => _firstPageToken; - public override PageResult GetPage(ClientToken pageToken) + public override PageResult GetPageCore(ClientToken pageToken) => _getPage(pageToken); } From 1ed51afe158219b6fa4f421002bddfad62c9129d Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Thu, 27 Jun 2024 07:18:34 -0700 Subject: [PATCH 24/72] backup of initial thinking on operation-specific page token idea --- src/Custom/Assistants/AssistantClient.cs | 87 +++++++--- .../Assistants/GetAssistantsPageToken.cs | 96 +++++++++++ .../Common/OpenAIPageCollectionHelpers.cs | 11 +- src/Custom/Common/OpenAIPageToken.cs | 152 +++++++++--------- 4 files changed, 241 insertions(+), 105 deletions(-) create mode 100644 src/Custom/Assistants/GetAssistantsPageToken.cs diff --git a/src/Custom/Assistants/AssistantClient.cs b/src/Custom/Assistants/AssistantClient.cs index c2a8dff4e..650f5df00 100644 --- a/src/Custom/Assistants/AssistantClient.cs +++ b/src/Custom/Assistants/AssistantClient.cs @@ -115,8 +115,31 @@ public virtual ClientResult CreateAssistant(string model, AssistantCr /// A collection of assistants that can be enumerated using await foreach. public virtual AsyncPageCollection GetAssistantsAsync(ListOrder? order = null, int? pageSize = null, string afterId = default, string beforeId = default, CancellationToken cancellationToken = default) { - OpenAIPageToken pageToken = OpenAIPageToken.FromListOptions(limit: pageSize, order: order?.ToString(), after: afterId, before: beforeId); - return OpenAIPageCollectionHelpers.CreateAsync(pageToken, GetAssistantsPageAsync, cancellationToken.ToRequestOptions()); + GetAssistantsPageToken firstPageToken = GetAssistantsPageToken.FromOptions(limit: pageSize, order: order?.ToString(), after: afterId, before: beforeId); + return OpenAIPageCollectionHelpers.CreateAsync( + firstPageToken, + GetAssistantsPageAsync, + GetAssistantsPageToken.FromToken, + cancellationToken.ToRequestOptions()); + + //async Task> getPageAsync(ClientToken pageToken) + //{ + // GetAssistantsPageToken token = GetAssistantsPageToken.FromToken(pageToken); + + // ClientResult result = await GetAssistantsPageAsync( + // limit: token.Limit, + // order: token.Order, + // after: token.After, + // before: token.Before, + // cancellationToken.ToRequestOptions()).ConfigureAwait(false); + + // PipelineResponse response = result.GetRawResponse(); + // InternalListAssistantsResponse list = ModelReaderWriter.Read(response.Content)!; + // OpenAIPageToken nextPageToken = token.GetNextPageToken(list.HasMore, list.LastId); + + // return PageResult.Create(list.Data, pageToken, nextPageToken, response); + //} + //return PageCollectionHelpers.CreateAsync(firstPageToken, getPageAsync); } /// @@ -127,8 +150,12 @@ public virtual AsyncPageCollection GetAssistantsAsync(ListOrder? orde /// A collection of assistants that can be enumerated using await foreach. public virtual AsyncPageCollection GetAssistantsAsync(ClientToken firstPageToken, CancellationToken cancellationToken = default) { - OpenAIPageToken pageToken = OpenAIPageToken.FromToken(firstPageToken); - return OpenAIPageCollectionHelpers.CreateAsync(pageToken, GetAssistantsPageAsync, cancellationToken.ToRequestOptions()); + GetAssistantsPageToken pageToken = GetAssistantsPageToken.FromToken(firstPageToken); + return OpenAIPageCollectionHelpers.CreateAsync( + firstPageToken, + GetAssistantsPageAsync, + GetAssistantsPageToken.FromToken, + cancellationToken.ToRequestOptions()); } /// @@ -145,7 +172,7 @@ public virtual AsyncPageCollection GetAssistantsAsync(ClientToken fir /// A collection of assistants that can be enumerated using foreach. public virtual PageCollection GetAssistants(ListOrder? order = null, int? pageSize = null, string afterId = default, string beforeId = default, CancellationToken cancellationToken = default) { - OpenAIPageToken firstPageToken = OpenAIPageToken.FromListOptions(limit: pageSize, order: order?.ToString(), after: afterId, before: beforeId); + GetAssistantsPageToken firstPageToken = GetAssistantsPageToken.FromOptions(limit: pageSize, order: order?.ToString(), after: afterId, before: beforeId); return OpenAIPageCollectionHelpers.Create(firstPageToken, GetAssistantsPage, cancellationToken.ToRequestOptions()); } @@ -157,7 +184,7 @@ public virtual PageCollection GetAssistants(ListOrder? order = null, /// A collection of assistants that can be enumerated using foreach. public virtual PageCollection GetAssistants(ClientToken firstPageToken, CancellationToken cancellationToken = default) { - OpenAIPageToken pageToken = OpenAIPageToken.FromToken(firstPageToken); + GetAssistantsPageToken pageToken = GetAssistantsPageToken.FromToken(firstPageToken); return OpenAIPageCollectionHelpers.Create(pageToken, GetAssistantsPage, cancellationToken.ToRequestOptions()); } @@ -368,16 +395,18 @@ public virtual ClientResult CreateMessage( /// Returns a collection of instances from an existing . /// /// The ID of the thread to list messages from. - /// + /// /// The order that results should appear in the list according to their created_at /// timestamp. /// + /// The number of values to return in a single page in the page collection. + /// The id of the item preceeding the first item in the collection. + /// The id of the item following the last item in the collection. /// A token that can be used to cancel this method call. /// A collection of messages that can be enumerated using await foreach. public virtual AsyncPageCollection GetMessagesAsync( string threadId, - ListOrder? resultOrder = null, - CancellationToken cancellationToken = default) + ListOrder? order = null, int? pageSize = null, string afterId = default, string beforeId = default, CancellationToken cancellationToken = default) { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); @@ -390,16 +419,18 @@ public virtual AsyncPageCollection GetMessagesAsync( /// Returns a collection of instances from an existing . /// /// The ID of the thread to list messages from. - /// + /// /// The order that results should appear in the list according to their created_at /// timestamp. /// + /// The number of values to return in a single page in the page collection. + /// The id of the item preceeding the first item in the collection. + /// The id of the item following the last item in the collection. /// A token that can be used to cancel this method call. /// A collection of messages that can be enumerated using foreach. public virtual PageCollection GetMessages( string threadId, - ListOrder? resultOrder = null, - CancellationToken cancellationToken = default) + ListOrder? order = null, int? pageSize = null, string afterId = default, string beforeId = default, CancellationToken cancellationToken = default) { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); @@ -704,16 +735,18 @@ public virtual CollectionResult CreateThreadAndRunStreaming( /// Returns a collection of instances associated with an existing . /// /// The ID of the thread that runs in the list should be associated with. - /// + /// /// The order that results should appear in the list according to their created_at /// timestamp. /// + /// The number of values to return in a single page in the page collection. + /// The id of the item preceeding the first item in the collection. + /// The id of the item following the last item in the collection. /// A token that can be used to cancel this method call. /// A collection of runs that can be enumerated using await foreach. public virtual AsyncPageCollection GetRunsAsync( string threadId, - ListOrder? resultOrder = default, - CancellationToken cancellationToken = default) + ListOrder? order = null, int? pageSize = null, string afterId = default, string beforeId = default, CancellationToken cancellationToken = default) { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); @@ -726,16 +759,18 @@ public virtual AsyncPageCollection GetRunsAsync( /// Returns a collection of instances associated with an existing . /// /// The ID of the thread that runs in the list should be associated with. - /// + /// /// The order that results should appear in the list according to their created_at /// timestamp. /// + /// The number of values to return in a single page in the page collection. + /// The id of the item preceeding the first item in the collection. + /// The id of the item following the last item in the collection. /// A token that can be used to cancel this method call. /// A collection of runs that can be enumerated using foreach. public virtual PageCollection GetRuns( string threadId, - ListOrder? resultOrder = default, - CancellationToken cancellationToken = default) + ListOrder? order = null, int? pageSize = null, string afterId = default, string beforeId = default, CancellationToken cancellationToken = default) { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); @@ -916,17 +951,19 @@ public virtual ClientResult CancelRun(string threadId, string runId, /// /// The ID of the thread associated with the run. /// The ID of the run to list run steps from. - /// + /// /// The order that results should appear in the list according to their created_at /// timestamp. /// + /// The number of values to return in a single page in the page collection. + /// The id of the item preceeding the first item in the collection. + /// The id of the item following the last item in the collection. /// A token that can be used to cancel this method call. /// A collection of run steps that can be enumerated using await foreach. public virtual AsyncPageCollection GetRunStepsAsync( string threadId, string runId, - ListOrder? resultOrder = default, - CancellationToken cancellationToken = default) +ListOrder? order = null, int? pageSize = null, string afterId = default, string beforeId = default, CancellationToken cancellationToken = default) { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); Argument.AssertNotNullOrEmpty(runId, nameof(runId)); @@ -941,17 +978,19 @@ public virtual AsyncPageCollection GetRunStepsAsync( /// /// The ID of the thread associated with the run. /// The ID of the run to list run steps from. - /// + /// /// The order that results should appear in the list according to their created_at /// timestamp. /// + /// The number of values to return in a single page in the page collection. + /// The id of the item preceeding the first item in the collection. + /// The id of the item following the last item in the collection. /// A token that can be used to cancel this method call. /// A collection of run steps that can be enumerated using foreach. public virtual PageCollection GetRunSteps( string threadId, string runId, - ListOrder? resultOrder = default, - CancellationToken cancellationToken = default) +ListOrder? order = null, int? pageSize = null, string afterId = default, string beforeId = default, CancellationToken cancellationToken = default) { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); Argument.AssertNotNullOrEmpty(runId, nameof(runId)); diff --git a/src/Custom/Assistants/GetAssistantsPageToken.cs b/src/Custom/Assistants/GetAssistantsPageToken.cs new file mode 100644 index 000000000..46dc634a3 --- /dev/null +++ b/src/Custom/Assistants/GetAssistantsPageToken.cs @@ -0,0 +1,96 @@ +using System; +using System.ClientModel; +using System.Diagnostics; +using System.Text.Json; + +#nullable enable + +namespace OpenAI.Assistants; + +internal class GetAssistantsPageToken : OpenAIPageToken +{ + public GetAssistantsPageToken(int? limit, string? order, string? after, string? before) + : base(limit, order, after, before) + { + } + + public override OpenAIPageToken? GetNextPageToken(bool hasMore, string? lastId) + => GetNextPageToken(Limit, Order, lastId, Before, hasMore); + + public static GetAssistantsPageToken FromOptions(int? limit, string? order, string? after, string? before) + => new GetAssistantsPageToken(limit, order, after, before); + + public static GetAssistantsPageToken FromToken(ClientToken token) + { + if (token is GetAssistantsPageToken pageToken) + { + return pageToken; + } + + BinaryData data = token.ToBytes(); + + if (data.ToMemory().Length == 0) + { + return new(default, default, default, default); + } + + Utf8JsonReader reader = new(data); + + int? limit = null; + string? order = null; + string? after = null; + string? before = null; + + reader.Read(); + Debug.Assert(reader.TokenType == JsonTokenType.StartObject); + + while (reader.Read()) + { + if (reader.TokenType == JsonTokenType.EndObject) + { + break; + } + + Debug.Assert(reader.TokenType == JsonTokenType.PropertyName); + string propertyName = reader.GetString()!; + + switch (propertyName) + { + case "limit": + reader.Read(); + Debug.Assert(reader.TokenType == JsonTokenType.Number); + limit = reader.GetInt32(); + break; + case "order": + reader.Read(); + Debug.Assert(reader.TokenType == JsonTokenType.String); + order = reader.GetString(); + break; + case "after": + reader.Read(); + Debug.Assert(reader.TokenType == JsonTokenType.String); + after = reader.GetString(); + break; + case "before": + reader.Read(); + Debug.Assert(reader.TokenType == JsonTokenType.String); + before = reader.GetString(); + break; + default: + throw new JsonException($"Unrecognized property '{propertyName}'."); + } + } + + return new(limit, order, after, before); + } + + public static GetAssistantsPageToken? GetNextPageToken(int? limit, string? order, string? after, string? before, bool hasMore) + { + if (!hasMore || after is null) + { + return null; + } + + return new GetAssistantsPageToken(limit, order, after, before); + } +} \ No newline at end of file diff --git a/src/Custom/Common/OpenAIPageCollectionHelpers.cs b/src/Custom/Common/OpenAIPageCollectionHelpers.cs index 1d6dbe6e3..57cdac054 100644 --- a/src/Custom/Common/OpenAIPageCollectionHelpers.cs +++ b/src/Custom/Common/OpenAIPageCollectionHelpers.cs @@ -1,3 +1,4 @@ +using System; using System.ClientModel; using System.ClientModel.Primitives; using System.Collections.Generic; @@ -14,16 +15,18 @@ internal class OpenAIPageCollectionHelpers public delegate Task GetPageValuesAsync(int? limit, string? order, string? after, string? before, RequestOptions? options); public delegate ClientResult GetPageValues(int? limit, string? order, string? after, string? before, RequestOptions? options); - public static AsyncPageCollection CreateAsync( + public static AsyncPageCollection CreateAsync( ClientToken firstPageToken, GetPageValuesAsync getPageValuesAsync, + Func getToken, RequestOptions? options) where TValue : notnull where TList : IJsonModel, IInternalListResponse + where TToken : OpenAIPageToken { async Task> getPageAsync(ClientToken pageToken) { - OpenAIPageToken token = OpenAIPageToken.FromToken(pageToken); + OpenAIPageToken token = getToken(pageToken); ClientResult result = await getPageValuesAsync( limit: token.Limit, @@ -74,7 +77,7 @@ public static IAsyncEnumerable CreateProtocolAsync( int? limit, string? order, string? after, string? before, RequestOptions? options, GetPageValuesAsync getPageValuesAsync) { - OpenAIPageToken firstPageToken = OpenAIPageToken.FromListOptions(limit, order, after, before); + OpenAIPageToken firstPageToken = OpenAIPageToken.FromOptions(limit, order, after, before); async Task getPageAsync(ClientToken pageToken) { @@ -100,7 +103,7 @@ public static IEnumerable CreateProtocol( int? limit, string? order, string? after, string? before, RequestOptions? options, GetPageValues getPageValues) { - OpenAIPageToken firstPageToken = OpenAIPageToken.FromListOptions(limit, order, after, before); + OpenAIPageToken firstPageToken = OpenAIPageToken.FromOptions(limit, order, after, before); ClientResult getPage(ClientToken pageToken) { diff --git a/src/Custom/Common/OpenAIPageToken.cs b/src/Custom/Common/OpenAIPageToken.cs index bbda1cfcb..39e8c6a53 100644 --- a/src/Custom/Common/OpenAIPageToken.cs +++ b/src/Custom/Common/OpenAIPageToken.cs @@ -1,6 +1,5 @@ using System; using System.ClientModel; -using System.Diagnostics; using System.IO; using System.Text.Json; @@ -8,7 +7,7 @@ namespace OpenAI; -internal class OpenAIPageToken : ClientToken +internal abstract class OpenAIPageToken : ClientToken { public OpenAIPageToken(int? limit, string? order, string? after, string? before) { @@ -60,83 +59,82 @@ public override BinaryData ToBytes() return BinaryData.FromStream(stream); } - public OpenAIPageToken? GetNextPageToken(bool hasMore, string? lastId) - => GetNextPageToken(Limit, Order, lastId, Before, hasMore); + public abstract OpenAIPageToken? GetNextPageToken(bool hasMore, string? lastId); - public static OpenAIPageToken FromListOptions(int? limit, string? order, string? after, string? before) - => new OpenAIPageToken(limit, order, after, before); + //public static OpenAIPageToken FromOptions(int? limit, string? order, string? after, string? before) + // => new OpenAIPageToken(limit, order, after, before); - public static OpenAIPageToken FromToken(ClientToken token) - { - if (token is OpenAIPageToken openAIPageToken) - { - return openAIPageToken; - } + //public static OpenAIPageToken FromToken(ClientToken token) + //{ + // if (token is OpenAIPageToken openAIPageToken) + // { + // return openAIPageToken; + // } - BinaryData data = token.ToBytes(); + // BinaryData data = token.ToBytes(); - if (data.ToMemory().Length == 0) - { - return new(default, default, default, default); - } - - Utf8JsonReader reader = new(data); - - int? limit = null; - string? order = null; - string? after = null; - string? before = null; - - reader.Read(); - Debug.Assert(reader.TokenType == JsonTokenType.StartObject); - - while (reader.Read()) - { - if (reader.TokenType == JsonTokenType.EndObject) - { - break; - } - - Debug.Assert(reader.TokenType == JsonTokenType.PropertyName); - string propertyName = reader.GetString()!; - - switch (propertyName) - { - case "limit": - reader.Read(); - Debug.Assert(reader.TokenType == JsonTokenType.Number); - limit = reader.GetInt32(); - break; - case "order": - reader.Read(); - Debug.Assert(reader.TokenType == JsonTokenType.String); - order = reader.GetString(); - break; - case "after": - reader.Read(); - Debug.Assert(reader.TokenType == JsonTokenType.String); - after = reader.GetString(); - break; - case "before": - reader.Read(); - Debug.Assert(reader.TokenType == JsonTokenType.String); - before = reader.GetString(); - break; - default: - throw new JsonException($"Unrecognized property '{propertyName}'."); - } - } - - return new(limit, order, after, before); - } - - public static OpenAIPageToken? GetNextPageToken(int? limit, string? order, string? after, string? before, bool hasMore) - { - if (!hasMore || after is null) - { - return null; - } - - return new OpenAIPageToken(limit, order, after, before); - } + // if (data.ToMemory().Length == 0) + // { + // return new(default, default, default, default); + // } + + // Utf8JsonReader reader = new(data); + + // int? limit = null; + // string? order = null; + // string? after = null; + // string? before = null; + + // reader.Read(); + // Debug.Assert(reader.TokenType == JsonTokenType.StartObject); + + // while (reader.Read()) + // { + // if (reader.TokenType == JsonTokenType.EndObject) + // { + // break; + // } + + // Debug.Assert(reader.TokenType == JsonTokenType.PropertyName); + // string propertyName = reader.GetString()!; + + // switch (propertyName) + // { + // case "limit": + // reader.Read(); + // Debug.Assert(reader.TokenType == JsonTokenType.Number); + // limit = reader.GetInt32(); + // break; + // case "order": + // reader.Read(); + // Debug.Assert(reader.TokenType == JsonTokenType.String); + // order = reader.GetString(); + // break; + // case "after": + // reader.Read(); + // Debug.Assert(reader.TokenType == JsonTokenType.String); + // after = reader.GetString(); + // break; + // case "before": + // reader.Read(); + // Debug.Assert(reader.TokenType == JsonTokenType.String); + // before = reader.GetString(); + // break; + // default: + // throw new JsonException($"Unrecognized property '{propertyName}'."); + // } + // } + + // return new(limit, order, after, before); + //} + + //public static OpenAIPageToken? GetNextPageToken(int? limit, string? order, string? after, string? before, bool hasMore) + //{ + // if (!hasMore || after is null) + // { + // return null; + // } + + // return new OpenAIPageToken(limit, order, after, before); + //} } \ No newline at end of file From 2ad6dc18d0a08539d1c2fd43987464cb3cbaf3b2 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Thu, 27 Jun 2024 09:13:55 -0700 Subject: [PATCH 25/72] extend operation-specific page token idea to protocol methods --- .../Assistants/Example02_FunctionCalling.cs | 2 +- .../Example02_FunctionCallingAsync.cs | 2 +- examples/Assistants/Example04_AllTheTools.cs | 2 +- .../Assistants/AssistantClient.Protocol.cs | 10 ++++- src/Custom/Assistants/AssistantClient.cs | 16 ++++++-- .../Common/OpenAIPageCollectionHelpers.cs | 40 ++++++++++--------- src/Utility/PageCollectionHelpers.cs | 16 ++++---- tests/Assistants/AssistantTests.cs | 2 +- 8 files changed, 53 insertions(+), 37 deletions(-) diff --git a/examples/Assistants/Example02_FunctionCalling.cs b/examples/Assistants/Example02_FunctionCalling.cs index 4af074c79..8fcc2580f 100644 --- a/examples/Assistants/Example02_FunctionCalling.cs +++ b/examples/Assistants/Example02_FunctionCalling.cs @@ -152,7 +152,7 @@ string GetCurrentWeather(string location, string unit = "celsius") if (run.Status == RunStatus.Completed) { PageCollection messagePages - = client.GetMessages(run.ThreadId, resultOrder: ListOrder.OldestFirst); + = client.GetMessages(run.ThreadId, ListOrder.OldestFirst); IEnumerable messages = messagePages.GetAllValues(); foreach (ThreadMessage message in messages) diff --git a/examples/Assistants/Example02_FunctionCallingAsync.cs b/examples/Assistants/Example02_FunctionCallingAsync.cs index 4add93b9a..fdb449473 100644 --- a/examples/Assistants/Example02_FunctionCallingAsync.cs +++ b/examples/Assistants/Example02_FunctionCallingAsync.cs @@ -152,7 +152,7 @@ string GetCurrentWeather(string location, string unit = "celsius") if (run.Status == RunStatus.Completed) { AsyncPageCollection messagePages - = client.GetMessagesAsync(run.ThreadId, resultOrder: ListOrder.OldestFirst); + = client.GetMessagesAsync(run.ThreadId, ListOrder.OldestFirst); IAsyncEnumerable messages = messagePages.GetAllValuesAsync(); await foreach (ThreadMessage message in messages) diff --git a/examples/Assistants/Example04_AllTheTools.cs b/examples/Assistants/Example04_AllTheTools.cs index 61be9f4a5..3fa08dda9 100644 --- a/examples/Assistants/Example04_AllTheTools.cs +++ b/examples/Assistants/Example04_AllTheTools.cs @@ -138,7 +138,7 @@ static string GetNameOfFamilyMember(string relation) if (run.Status == RunStatus.Completed) { PageCollection messagePages - = client.GetMessages(run.ThreadId, resultOrder: ListOrder.OldestFirst); + = client.GetMessages(run.ThreadId, ListOrder.OldestFirst); IEnumerable messages = messagePages.GetAllValues(); foreach (ThreadMessage message in messages) diff --git a/src/Custom/Assistants/AssistantClient.Protocol.cs b/src/Custom/Assistants/AssistantClient.Protocol.cs index dcc9317d0..8adb1a249 100644 --- a/src/Custom/Assistants/AssistantClient.Protocol.cs +++ b/src/Custom/Assistants/AssistantClient.Protocol.cs @@ -65,7 +65,10 @@ public virtual ClientResult CreateAssistant(BinaryContent content, RequestOption /// Service returned a non-success status code. /// The response returned from the service. public virtual IAsyncEnumerable GetAssistantsAsync(int? limit, string order, string after, string before, RequestOptions options) - => OpenAIPageCollectionHelpers.CreateProtocolAsync(limit, order, after, before, options, GetAssistantsPageAsync); + { + GetAssistantsPageToken firstPageToken = GetAssistantsPageToken.FromOptions(limit, order, after, before); + return OpenAIPageCollectionHelpers.CreateProtocolAsync(firstPageToken, GetAssistantsPageAsync, GetAssistantsPageToken.FromToken, options); + } internal virtual async Task GetAssistantsPageAsync(int? limit, string order, string after, string before, RequestOptions options) { @@ -98,7 +101,10 @@ internal virtual async Task GetAssistantsPageAsync(int? limit, str /// Service returned a non-success status code. /// The response returned from the service. public virtual IEnumerable GetAssistants(int? limit, string order, string after, string before, RequestOptions options) - => OpenAIPageCollectionHelpers.CreateProtocol(limit, order, after, before, options, GetAssistantsPage); + { + GetAssistantsPageToken firstPageToken = GetAssistantsPageToken.FromOptions(limit, order, after, before); + return OpenAIPageCollectionHelpers.CreateProtocol(firstPageToken, GetAssistantsPage, GetAssistantsPageToken.FromToken, options); + } internal virtual ClientResult GetAssistantsPage(int? limit, string order, string after, string before, RequestOptions options) { diff --git a/src/Custom/Assistants/AssistantClient.cs b/src/Custom/Assistants/AssistantClient.cs index 650f5df00..d1025fcd3 100644 --- a/src/Custom/Assistants/AssistantClient.cs +++ b/src/Custom/Assistants/AssistantClient.cs @@ -116,7 +116,7 @@ public virtual ClientResult CreateAssistant(string model, AssistantCr public virtual AsyncPageCollection GetAssistantsAsync(ListOrder? order = null, int? pageSize = null, string afterId = default, string beforeId = default, CancellationToken cancellationToken = default) { GetAssistantsPageToken firstPageToken = GetAssistantsPageToken.FromOptions(limit: pageSize, order: order?.ToString(), after: afterId, before: beforeId); - return OpenAIPageCollectionHelpers.CreateAsync( + return OpenAIPageCollectionHelpers.CreateAsync( firstPageToken, GetAssistantsPageAsync, GetAssistantsPageToken.FromToken, @@ -151,7 +151,7 @@ public virtual AsyncPageCollection GetAssistantsAsync(ListOrder? orde public virtual AsyncPageCollection GetAssistantsAsync(ClientToken firstPageToken, CancellationToken cancellationToken = default) { GetAssistantsPageToken pageToken = GetAssistantsPageToken.FromToken(firstPageToken); - return OpenAIPageCollectionHelpers.CreateAsync( + return OpenAIPageCollectionHelpers.CreateAsync( firstPageToken, GetAssistantsPageAsync, GetAssistantsPageToken.FromToken, @@ -173,7 +173,11 @@ public virtual AsyncPageCollection GetAssistantsAsync(ClientToken fir public virtual PageCollection GetAssistants(ListOrder? order = null, int? pageSize = null, string afterId = default, string beforeId = default, CancellationToken cancellationToken = default) { GetAssistantsPageToken firstPageToken = GetAssistantsPageToken.FromOptions(limit: pageSize, order: order?.ToString(), after: afterId, before: beforeId); - return OpenAIPageCollectionHelpers.Create(firstPageToken, GetAssistantsPage, cancellationToken.ToRequestOptions()); + return OpenAIPageCollectionHelpers.Create( + firstPageToken, + GetAssistantsPage, + GetAssistantsPageToken.FromToken, + cancellationToken.ToRequestOptions()); } /// @@ -185,7 +189,11 @@ public virtual PageCollection GetAssistants(ListOrder? order = null, public virtual PageCollection GetAssistants(ClientToken firstPageToken, CancellationToken cancellationToken = default) { GetAssistantsPageToken pageToken = GetAssistantsPageToken.FromToken(firstPageToken); - return OpenAIPageCollectionHelpers.Create(pageToken, GetAssistantsPage, cancellationToken.ToRequestOptions()); + return OpenAIPageCollectionHelpers.Create( + pageToken, + GetAssistantsPage, + GetAssistantsPageToken.FromToken, + cancellationToken.ToRequestOptions()); } /// diff --git a/src/Custom/Common/OpenAIPageCollectionHelpers.cs b/src/Custom/Common/OpenAIPageCollectionHelpers.cs index 57cdac054..e990d6657 100644 --- a/src/Custom/Common/OpenAIPageCollectionHelpers.cs +++ b/src/Custom/Common/OpenAIPageCollectionHelpers.cs @@ -15,14 +15,13 @@ internal class OpenAIPageCollectionHelpers public delegate Task GetPageValuesAsync(int? limit, string? order, string? after, string? before, RequestOptions? options); public delegate ClientResult GetPageValues(int? limit, string? order, string? after, string? before, RequestOptions? options); - public static AsyncPageCollection CreateAsync( + public static AsyncPageCollection CreateAsync( ClientToken firstPageToken, GetPageValuesAsync getPageValuesAsync, - Func getToken, + Func getToken, RequestOptions? options) where TValue : notnull where TList : IJsonModel, IInternalListResponse - where TToken : OpenAIPageToken { async Task> getPageAsync(ClientToken pageToken) { @@ -48,13 +47,14 @@ async Task> getPageAsync(ClientToken pageToken) public static PageCollection Create( ClientToken firstPageToken, GetPageValues getPageValues, + Func getToken, RequestOptions? options) where TValue : notnull where TList : IJsonModel, IInternalListResponse { PageResult getPage(ClientToken pageToken) { - OpenAIPageToken token = OpenAIPageToken.FromToken(pageToken); + OpenAIPageToken token = getToken(pageToken); ClientResult result = getPageValues( limit: token.Limit, @@ -74,52 +74,54 @@ PageResult getPage(ClientToken pageToken) } public static IAsyncEnumerable CreateProtocolAsync( - int? limit, string? order, string? after, string? before, RequestOptions? options, - GetPageValuesAsync getPageValuesAsync) + ClientToken firstPageToken, + GetPageValuesAsync getPageValuesAsync, + Func getToken, + RequestOptions? options) { - OpenAIPageToken firstPageToken = OpenAIPageToken.FromOptions(limit, order, after, before); - async Task getPageAsync(ClientToken pageToken) { - OpenAIPageToken token = (OpenAIPageToken)pageToken; + OpenAIPageToken token = getToken(pageToken); return await getPageValuesAsync(token.Limit, token.Order, token.After, token.Before, options).ConfigureAwait(false); } - ClientToken? getNextPageToken(ClientResult result) + ClientToken? getNextPageToken(ClientToken pageToken, ClientResult result) { PipelineResponse response = result.GetRawResponse(); using JsonDocument doc = JsonDocument.Parse(response.Content); bool hasMore = doc.RootElement.GetProperty("has_more"u8).GetBoolean(); - after = doc.RootElement.GetProperty("last_id"u8).GetString(); + string lastId = doc.RootElement.GetProperty("last_id"u8).GetString()!; - return OpenAIPageToken.GetNextPageToken(limit, order, after, before, hasMore); + OpenAIPageToken token = getToken(pageToken); + return token.GetNextPageToken(hasMore, lastId); } return PageCollectionHelpers.CreatePrototolAsync(firstPageToken, getPageAsync, getNextPageToken); } public static IEnumerable CreateProtocol( - int? limit, string? order, string? after, string? before, RequestOptions? options, - GetPageValues getPageValues) + ClientToken firstPageToken, + GetPageValues getPageValues, + Func getToken, + RequestOptions? options) { - OpenAIPageToken firstPageToken = OpenAIPageToken.FromOptions(limit, order, after, before); - ClientResult getPage(ClientToken pageToken) { OpenAIPageToken token = (OpenAIPageToken)pageToken; return getPageValues(token.Limit, token.Order, token.After, token.Before, options); } - ClientToken? getNextPageToken(ClientResult result) + ClientToken? getNextPageToken(ClientToken pageToken, ClientResult result) { PipelineResponse response = result.GetRawResponse(); using JsonDocument doc = JsonDocument.Parse(response.Content); bool hasMore = doc.RootElement.GetProperty("has_more"u8).GetBoolean(); - after = doc.RootElement.GetProperty("last_id"u8).GetString(); + string lastId = doc.RootElement.GetProperty("last_id"u8).GetString()!; - return OpenAIPageToken.GetNextPageToken(limit, order, after, before, hasMore); + OpenAIPageToken token = getToken(pageToken); + return token.GetNextPageToken(hasMore, lastId); } return PageCollectionHelpers.CreatePrototol(firstPageToken, getPage, getNextPageToken); diff --git a/src/Utility/PageCollectionHelpers.cs b/src/Utility/PageCollectionHelpers.cs index c7582a374..86c912a23 100644 --- a/src/Utility/PageCollectionHelpers.cs +++ b/src/Utility/PageCollectionHelpers.cs @@ -21,12 +21,12 @@ public static PageCollection Create(ClientToken firstPageToken, public static IAsyncEnumerable CreatePrototolAsync(ClientToken firstPageToken, Func> getPageAsync, - Func getNextPageToken) + Func getNextPageToken) => new AsyncFuncResultEnumerable(firstPageToken, getPageAsync, getNextPageToken); public static IEnumerable CreatePrototol(ClientToken firstPageToken, Func getPage, - Func getNextPageToken) + Func getNextPageToken) => new FuncResultEnumerable(firstPageToken, getPage, getNextPageToken); private class AsyncFuncPageCollection : AsyncPageCollection where T : notnull @@ -69,11 +69,11 @@ private class AsyncFuncResultEnumerable : IAsyncEnumerable { private readonly ClientToken _firstPageToken; private readonly Func> _getPageAsync; - private readonly Func _getNextPageToken; + private readonly Func _getNextPageToken; public AsyncFuncResultEnumerable(ClientToken firstPageToken, Func> getPageAsync, - Func getNextPageToken) + Func getNextPageToken) { _firstPageToken = firstPageToken; _getPageAsync = getPageAsync; @@ -88,7 +88,7 @@ public async IAsyncEnumerator GetAsyncEnumerator(CancellationToken { ClientResult result = await _getPageAsync(pageToken).ConfigureAwait(false); yield return result; - pageToken = _getNextPageToken(result); + pageToken = _getNextPageToken(pageToken, result); } while (pageToken != null); } @@ -98,11 +98,11 @@ private class FuncResultEnumerable : IEnumerable { private readonly ClientToken _firstPageToken; private readonly Func _getPage; - private readonly Func _getNextPageToken; + private readonly Func _getNextPageToken; public FuncResultEnumerable(ClientToken firstPageToken, Func getPage, - Func getNextPageToken) + Func getNextPageToken) { _firstPageToken = firstPageToken; _getPage = getPage; @@ -117,7 +117,7 @@ public IEnumerator GetEnumerator() { ClientResult result = _getPage(pageToken); yield return result; - pageToken = _getNextPageToken(result); + pageToken = _getNextPageToken(pageToken, result); } while (pageToken != null); } diff --git a/tests/Assistants/AssistantTests.cs b/tests/Assistants/AssistantTests.cs index aaa8661f8..504027537 100644 --- a/tests/Assistants/AssistantTests.cs +++ b/tests/Assistants/AssistantTests.cs @@ -392,7 +392,7 @@ public void FunctionToolsWork() } Assert.That(run.Status, Is.EqualTo(RunStatus.Completed)); - IEnumerable messages = client.GetMessages(run.ThreadId, resultOrder: ListOrder.NewestFirst).GetAllValues(); + IEnumerable messages = client.GetMessages(run.ThreadId, ListOrder.NewestFirst).GetAllValues(); Assert.That(messages.Count, Is.GreaterThan(1)); Assert.That(messages.First().Role, Is.EqualTo(MessageRole.Assistant)); Assert.That(messages.First().Content?[0], Is.Not.Null); From 5b236a66cb54d924893d5da70754e7d5f29005d2 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Thu, 27 Jun 2024 09:26:08 -0700 Subject: [PATCH 26/72] rename ClientToken to ContinuationToken --- src/Custom/Assistants/AssistantClient.cs | 14 ++-- .../Assistants/GetAssistantsPageToken.cs | 2 +- .../Common/OpenAIPageCollectionHelpers.cs | 28 ++++---- src/Custom/Common/OpenAIPageToken.cs | 4 +- src/Utility/PageCollectionHelpers.cs | 72 +++++++++---------- tests/Assistants/AssistantTests.cs | 2 +- 6 files changed, 64 insertions(+), 58 deletions(-) diff --git a/src/Custom/Assistants/AssistantClient.cs b/src/Custom/Assistants/AssistantClient.cs index d1025fcd3..8e5bdb649 100644 --- a/src/Custom/Assistants/AssistantClient.cs +++ b/src/Custom/Assistants/AssistantClient.cs @@ -113,7 +113,13 @@ public virtual ClientResult CreateAssistant(string model, AssistantCr /// The id of the item following the last item in the collection. /// A token that can be used to cancel this method call. /// A collection of assistants that can be enumerated using await foreach. - public virtual AsyncPageCollection GetAssistantsAsync(ListOrder? order = null, int? pageSize = null, string afterId = default, string beforeId = default, CancellationToken cancellationToken = default) + public virtual AsyncPageCollection GetAssistantsAsync( + ListOrder? order = null, + int? pageSize = null, + string afterId = default, + string beforeId = default, + + CancellationToken cancellationToken = default) { GetAssistantsPageToken firstPageToken = GetAssistantsPageToken.FromOptions(limit: pageSize, order: order?.ToString(), after: afterId, before: beforeId); return OpenAIPageCollectionHelpers.CreateAsync( @@ -122,7 +128,7 @@ public virtual AsyncPageCollection GetAssistantsAsync(ListOrder? orde GetAssistantsPageToken.FromToken, cancellationToken.ToRequestOptions()); - //async Task> getPageAsync(ClientToken pageToken) + //async Task> getPageAsync(ContinuationToken pageToken) //{ // GetAssistantsPageToken token = GetAssistantsPageToken.FromToken(pageToken); @@ -148,7 +154,7 @@ public virtual AsyncPageCollection GetAssistantsAsync(ListOrder? orde /// Serialized page token indicating the first page of the collection to rehydrate. /// A token that can be used to cancel this method call. /// A collection of assistants that can be enumerated using await foreach. - public virtual AsyncPageCollection GetAssistantsAsync(ClientToken firstPageToken, CancellationToken cancellationToken = default) + public virtual AsyncPageCollection GetAssistantsAsync(ContinuationToken firstPageToken, CancellationToken cancellationToken = default) { GetAssistantsPageToken pageToken = GetAssistantsPageToken.FromToken(firstPageToken); return OpenAIPageCollectionHelpers.CreateAsync( @@ -186,7 +192,7 @@ public virtual PageCollection GetAssistants(ListOrder? order = null, /// Serialized page token indicating the first page of the collection to rehydrate. /// A token that can be used to cancel this method call. /// A collection of assistants that can be enumerated using foreach. - public virtual PageCollection GetAssistants(ClientToken firstPageToken, CancellationToken cancellationToken = default) + public virtual PageCollection GetAssistants(ContinuationToken firstPageToken, CancellationToken cancellationToken = default) { GetAssistantsPageToken pageToken = GetAssistantsPageToken.FromToken(firstPageToken); return OpenAIPageCollectionHelpers.Create( diff --git a/src/Custom/Assistants/GetAssistantsPageToken.cs b/src/Custom/Assistants/GetAssistantsPageToken.cs index 46dc634a3..ead9d2ac3 100644 --- a/src/Custom/Assistants/GetAssistantsPageToken.cs +++ b/src/Custom/Assistants/GetAssistantsPageToken.cs @@ -20,7 +20,7 @@ public GetAssistantsPageToken(int? limit, string? order, string? after, string? public static GetAssistantsPageToken FromOptions(int? limit, string? order, string? after, string? before) => new GetAssistantsPageToken(limit, order, after, before); - public static GetAssistantsPageToken FromToken(ClientToken token) + public static GetAssistantsPageToken FromToken(ContinuationToken token) { if (token is GetAssistantsPageToken pageToken) { diff --git a/src/Custom/Common/OpenAIPageCollectionHelpers.cs b/src/Custom/Common/OpenAIPageCollectionHelpers.cs index e990d6657..2aa3dcff2 100644 --- a/src/Custom/Common/OpenAIPageCollectionHelpers.cs +++ b/src/Custom/Common/OpenAIPageCollectionHelpers.cs @@ -16,14 +16,14 @@ internal class OpenAIPageCollectionHelpers public delegate ClientResult GetPageValues(int? limit, string? order, string? after, string? before, RequestOptions? options); public static AsyncPageCollection CreateAsync( - ClientToken firstPageToken, + ContinuationToken firstPageToken, GetPageValuesAsync getPageValuesAsync, - Func getToken, + Func getToken, RequestOptions? options) where TValue : notnull where TList : IJsonModel, IInternalListResponse { - async Task> getPageAsync(ClientToken pageToken) + async Task> getPageAsync(ContinuationToken pageToken) { OpenAIPageToken token = getToken(pageToken); @@ -45,14 +45,14 @@ async Task> getPageAsync(ClientToken pageToken) } public static PageCollection Create( - ClientToken firstPageToken, + ContinuationToken firstPageToken, GetPageValues getPageValues, - Func getToken, + Func getToken, RequestOptions? options) where TValue : notnull where TList : IJsonModel, IInternalListResponse { - PageResult getPage(ClientToken pageToken) + PageResult getPage(ContinuationToken pageToken) { OpenAIPageToken token = getToken(pageToken); @@ -74,18 +74,18 @@ PageResult getPage(ClientToken pageToken) } public static IAsyncEnumerable CreateProtocolAsync( - ClientToken firstPageToken, + ContinuationToken firstPageToken, GetPageValuesAsync getPageValuesAsync, - Func getToken, + Func getToken, RequestOptions? options) { - async Task getPageAsync(ClientToken pageToken) + async Task getPageAsync(ContinuationToken pageToken) { OpenAIPageToken token = getToken(pageToken); return await getPageValuesAsync(token.Limit, token.Order, token.After, token.Before, options).ConfigureAwait(false); } - ClientToken? getNextPageToken(ClientToken pageToken, ClientResult result) + ContinuationToken? getNextPageToken(ContinuationToken pageToken, ClientResult result) { PipelineResponse response = result.GetRawResponse(); @@ -101,18 +101,18 @@ async Task getPageAsync(ClientToken pageToken) } public static IEnumerable CreateProtocol( - ClientToken firstPageToken, + ContinuationToken firstPageToken, GetPageValues getPageValues, - Func getToken, + Func getToken, RequestOptions? options) { - ClientResult getPage(ClientToken pageToken) + ClientResult getPage(ContinuationToken pageToken) { OpenAIPageToken token = (OpenAIPageToken)pageToken; return getPageValues(token.Limit, token.Order, token.After, token.Before, options); } - ClientToken? getNextPageToken(ClientToken pageToken, ClientResult result) + ContinuationToken? getNextPageToken(ContinuationToken pageToken, ClientResult result) { PipelineResponse response = result.GetRawResponse(); diff --git a/src/Custom/Common/OpenAIPageToken.cs b/src/Custom/Common/OpenAIPageToken.cs index 39e8c6a53..c4c8d8ca8 100644 --- a/src/Custom/Common/OpenAIPageToken.cs +++ b/src/Custom/Common/OpenAIPageToken.cs @@ -7,7 +7,7 @@ namespace OpenAI; -internal abstract class OpenAIPageToken : ClientToken +internal abstract class OpenAIPageToken : ContinuationToken { public OpenAIPageToken(int? limit, string? order, string? after, string? before) { @@ -64,7 +64,7 @@ public override BinaryData ToBytes() //public static OpenAIPageToken FromOptions(int? limit, string? order, string? after, string? before) // => new OpenAIPageToken(limit, order, after, before); - //public static OpenAIPageToken FromToken(ClientToken token) + //public static OpenAIPageToken FromToken(ContinuationToken token) //{ // if (token is OpenAIPageToken openAIPageToken) // { diff --git a/src/Utility/PageCollectionHelpers.cs b/src/Utility/PageCollectionHelpers.cs index 86c912a23..59dc461b2 100644 --- a/src/Utility/PageCollectionHelpers.cs +++ b/src/Utility/PageCollectionHelpers.cs @@ -11,69 +11,69 @@ namespace OpenAI.Utility; internal class PageCollectionHelpers { - public static AsyncPageCollection CreateAsync(ClientToken firstPageToken, - Func>> getPageAsync) where T : notnull + public static AsyncPageCollection CreateAsync(ContinuationToken firstPageToken, + Func>> getPageAsync) where T : notnull => new AsyncFuncPageCollection(firstPageToken, getPageAsync); - public static PageCollection Create(ClientToken firstPageToken, - Func> getPage) where T : notnull + public static PageCollection Create(ContinuationToken firstPageToken, + Func> getPage) where T : notnull => new FuncPageCollection(firstPageToken, getPage); - public static IAsyncEnumerable CreatePrototolAsync(ClientToken firstPageToken, - Func> getPageAsync, - Func getNextPageToken) + public static IAsyncEnumerable CreatePrototolAsync(ContinuationToken firstPageToken, + Func> getPageAsync, + Func getNextPageToken) => new AsyncFuncResultEnumerable(firstPageToken, getPageAsync, getNextPageToken); - public static IEnumerable CreatePrototol(ClientToken firstPageToken, - Func getPage, - Func getNextPageToken) + public static IEnumerable CreatePrototol(ContinuationToken firstPageToken, + Func getPage, + Func getNextPageToken) => new FuncResultEnumerable(firstPageToken, getPage, getNextPageToken); private class AsyncFuncPageCollection : AsyncPageCollection where T : notnull { - private readonly ClientToken _firstPageToken; - private readonly Func>> _getPageAsync; + private readonly ContinuationToken _firstPageToken; + private readonly Func>> _getPageAsync; - public AsyncFuncPageCollection(ClientToken firstPageToken, - Func>> getPageAsync) + public AsyncFuncPageCollection(ContinuationToken firstPageToken, + Func>> getPageAsync) { _firstPageToken = firstPageToken; _getPageAsync = getPageAsync; } - public override ClientToken FirstPageToken => _firstPageToken; + public override ContinuationToken FirstPageToken => _firstPageToken; - public override async Task> GetPageAsyncCore(ClientToken pageToken) + public override async Task> GetPageAsyncCore(ContinuationToken pageToken) => await _getPageAsync(pageToken).ConfigureAwait(false); } private class FuncPageCollection : PageCollection where T : notnull { - private readonly ClientToken _firstPageToken; - private readonly Func> _getPage; + private readonly ContinuationToken _firstPageToken; + private readonly Func> _getPage; - public FuncPageCollection(ClientToken firstPageToken, - Func> getPage) + public FuncPageCollection(ContinuationToken firstPageToken, + Func> getPage) { _firstPageToken = firstPageToken; _getPage = getPage; } - public override ClientToken FirstPageToken => _firstPageToken; + public override ContinuationToken FirstPageToken => _firstPageToken; - public override PageResult GetPageCore(ClientToken pageToken) + public override PageResult GetPageCore(ContinuationToken pageToken) => _getPage(pageToken); } private class AsyncFuncResultEnumerable : IAsyncEnumerable { - private readonly ClientToken _firstPageToken; - private readonly Func> _getPageAsync; - private readonly Func _getNextPageToken; + private readonly ContinuationToken _firstPageToken; + private readonly Func> _getPageAsync; + private readonly Func _getNextPageToken; - public AsyncFuncResultEnumerable(ClientToken firstPageToken, - Func> getPageAsync, - Func getNextPageToken) + public AsyncFuncResultEnumerable(ContinuationToken firstPageToken, + Func> getPageAsync, + Func getNextPageToken) { _firstPageToken = firstPageToken; _getPageAsync = getPageAsync; @@ -82,7 +82,7 @@ public AsyncFuncResultEnumerable(ClientToken firstPageToken, public async IAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) { - ClientToken? pageToken = _firstPageToken; + ContinuationToken? pageToken = _firstPageToken; do { @@ -96,13 +96,13 @@ public async IAsyncEnumerator GetAsyncEnumerator(CancellationToken private class FuncResultEnumerable : IEnumerable { - private readonly ClientToken _firstPageToken; - private readonly Func _getPage; - private readonly Func _getNextPageToken; + private readonly ContinuationToken _firstPageToken; + private readonly Func _getPage; + private readonly Func _getNextPageToken; - public FuncResultEnumerable(ClientToken firstPageToken, - Func getPage, - Func getNextPageToken) + public FuncResultEnumerable(ContinuationToken firstPageToken, + Func getPage, + Func getNextPageToken) { _firstPageToken = firstPageToken; _getPage = getPage; @@ -111,7 +111,7 @@ public FuncResultEnumerable(ClientToken firstPageToken, public IEnumerator GetEnumerator() { - ClientToken? pageToken = _firstPageToken; + ContinuationToken? pageToken = _firstPageToken; do { diff --git a/tests/Assistants/AssistantTests.cs b/tests/Assistants/AssistantTests.cs index 504027537..7081067ef 100644 --- a/tests/Assistants/AssistantTests.cs +++ b/tests/Assistants/AssistantTests.cs @@ -727,7 +727,7 @@ public async Task CanRehydratePageCollectionFromBytes() // Simulate rehydration of the collection BinaryData rehydrationBytes = pages.FirstPageToken.ToBytes(); - ClientToken rehydrationToken = ClientToken.FromBytes(rehydrationBytes); + ContinuationToken rehydrationToken = ContinuationToken.FromBytes(rehydrationBytes); AsyncPageCollection rehydratedPages = client.GetAssistantsAsync(rehydrationToken); From 444bee0d51e12b0d161d84177dd605f1eb627c05 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Thu, 27 Jun 2024 10:17:10 -0700 Subject: [PATCH 27/72] nits: tidy --- src/Custom/Assistants/AssistantClient.cs | 41 +++++++++--------------- 1 file changed, 15 insertions(+), 26 deletions(-) diff --git a/src/Custom/Assistants/AssistantClient.cs b/src/Custom/Assistants/AssistantClient.cs index 8e5bdb649..563299794 100644 --- a/src/Custom/Assistants/AssistantClient.cs +++ b/src/Custom/Assistants/AssistantClient.cs @@ -114,11 +114,10 @@ public virtual ClientResult CreateAssistant(string model, AssistantCr /// A token that can be used to cancel this method call. /// A collection of assistants that can be enumerated using await foreach. public virtual AsyncPageCollection GetAssistantsAsync( - ListOrder? order = null, - int? pageSize = null, - string afterId = default, + ListOrder? order = null, + int? pageSize = null, + string afterId = default, string beforeId = default, - CancellationToken cancellationToken = default) { GetAssistantsPageToken firstPageToken = GetAssistantsPageToken.FromOptions(limit: pageSize, order: order?.ToString(), after: afterId, before: beforeId); @@ -127,25 +126,6 @@ public virtual AsyncPageCollection GetAssistantsAsync( GetAssistantsPageAsync, GetAssistantsPageToken.FromToken, cancellationToken.ToRequestOptions()); - - //async Task> getPageAsync(ContinuationToken pageToken) - //{ - // GetAssistantsPageToken token = GetAssistantsPageToken.FromToken(pageToken); - - // ClientResult result = await GetAssistantsPageAsync( - // limit: token.Limit, - // order: token.Order, - // after: token.After, - // before: token.Before, - // cancellationToken.ToRequestOptions()).ConfigureAwait(false); - - // PipelineResponse response = result.GetRawResponse(); - // InternalListAssistantsResponse list = ModelReaderWriter.Read(response.Content)!; - // OpenAIPageToken nextPageToken = token.GetNextPageToken(list.HasMore, list.LastId); - - // return PageResult.Create(list.Data, pageToken, nextPageToken, response); - //} - //return PageCollectionHelpers.CreateAsync(firstPageToken, getPageAsync); } /// @@ -154,7 +134,9 @@ public virtual AsyncPageCollection GetAssistantsAsync( /// Serialized page token indicating the first page of the collection to rehydrate. /// A token that can be used to cancel this method call. /// A collection of assistants that can be enumerated using await foreach. - public virtual AsyncPageCollection GetAssistantsAsync(ContinuationToken firstPageToken, CancellationToken cancellationToken = default) + public virtual AsyncPageCollection GetAssistantsAsync( + ContinuationToken firstPageToken, + CancellationToken cancellationToken = default) { GetAssistantsPageToken pageToken = GetAssistantsPageToken.FromToken(firstPageToken); return OpenAIPageCollectionHelpers.CreateAsync( @@ -176,7 +158,12 @@ public virtual AsyncPageCollection GetAssistantsAsync(ContinuationTok /// The id of the item following the last item in the collection. /// A token that can be used to cancel this method call. /// A collection of assistants that can be enumerated using foreach. - public virtual PageCollection GetAssistants(ListOrder? order = null, int? pageSize = null, string afterId = default, string beforeId = default, CancellationToken cancellationToken = default) + public virtual PageCollection GetAssistants( + ListOrder? order = null, + int? pageSize = null, + string afterId = default, + string beforeId = default, + CancellationToken cancellationToken = default) { GetAssistantsPageToken firstPageToken = GetAssistantsPageToken.FromOptions(limit: pageSize, order: order?.ToString(), after: afterId, before: beforeId); return OpenAIPageCollectionHelpers.Create( @@ -192,7 +179,9 @@ public virtual PageCollection GetAssistants(ListOrder? order = null, /// Serialized page token indicating the first page of the collection to rehydrate. /// A token that can be used to cancel this method call. /// A collection of assistants that can be enumerated using foreach. - public virtual PageCollection GetAssistants(ContinuationToken firstPageToken, CancellationToken cancellationToken = default) + public virtual PageCollection GetAssistants( + ContinuationToken firstPageToken, + CancellationToken cancellationToken = default) { GetAssistantsPageToken pageToken = GetAssistantsPageToken.FromToken(firstPageToken); return OpenAIPageCollectionHelpers.Create( From 0060d5f2824c638c8739b9127058073c8bbd34a9 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Fri, 28 Jun 2024 16:16:32 -0700 Subject: [PATCH 28/72] add test to illustrate convenience/protocol interop --- .../Assistants/AssistantClient.Protocol.cs | 7 ++- tests/Assistants/AssistantTests.cs | 55 ++++++++++++++++++- 2 files changed, 58 insertions(+), 4 deletions(-) diff --git a/src/Custom/Assistants/AssistantClient.Protocol.cs b/src/Custom/Assistants/AssistantClient.Protocol.cs index 8adb1a249..9ad87804a 100644 --- a/src/Custom/Assistants/AssistantClient.Protocol.cs +++ b/src/Custom/Assistants/AssistantClient.Protocol.cs @@ -2,6 +2,7 @@ using System.ClientModel; using System.ClientModel.Primitives; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; namespace OpenAI.Assistants; @@ -67,7 +68,11 @@ public virtual ClientResult CreateAssistant(BinaryContent content, RequestOption public virtual IAsyncEnumerable GetAssistantsAsync(int? limit, string order, string after, string before, RequestOptions options) { GetAssistantsPageToken firstPageToken = GetAssistantsPageToken.FromOptions(limit, order, after, before); - return OpenAIPageCollectionHelpers.CreateProtocolAsync(firstPageToken, GetAssistantsPageAsync, GetAssistantsPageToken.FromToken, options); + return OpenAIPageCollectionHelpers.CreateAsync( + firstPageToken, + GetAssistantsPageAsync, + GetAssistantsPageToken.FromToken, + options); } internal virtual async Task GetAssistantsPageAsync(int? limit, string order, string after, string before, RequestOptions options) diff --git a/tests/Assistants/AssistantTests.cs b/tests/Assistants/AssistantTests.cs index 7081067ef..101d368ac 100644 --- a/tests/Assistants/AssistantTests.cs +++ b/tests/Assistants/AssistantTests.cs @@ -1,5 +1,4 @@ - -using NUnit.Framework; +using NUnit.Framework; using OpenAI.Assistants; using OpenAI.Files; using OpenAI.VectorStores; @@ -706,7 +705,6 @@ public async Task CanPageThroughAssistantCollection() Assert.That(pageCount, Is.GreaterThanOrEqualTo(5)); } - [Test] public async Task CanRehydratePageCollectionFromBytes() { @@ -810,6 +808,57 @@ public async Task CanRehydratePageCollectionFromPageToken() Assert.That(pageCount, Is.GreaterThanOrEqualTo(5)); } + [Test] + public async Task CanCastPageCollectionToConvenienceFromProtocol() + { + AssistantClient client = GetTestClient(); + + // Create assistant collection + for (int i = 0; i < 10; i++) + { + Assistant assistant = client.CreateAssistant("gpt-3.5-turbo", new AssistantCreationOptions() + { + Name = $"Test Assistant {i}" + }); + Validate(assistant); + Assert.That(assistant.Name, Is.EqualTo($"Test Assistant {i}")); + } + + // Call the protocol method + IAsyncEnumerable pages = client.GetAssistantsAsync(limit: 2, order: "desc", after: null, before: null, options: default); + + // Cast to the convenience type + AsyncPageCollection assistantPages = (AsyncPageCollection)pages; + + int count = 0; + int pageCount = 0; + int lastIdSeen = int.MaxValue; + + await foreach (PageResult page in assistantPages) + { + foreach (Assistant assistant in page.Values) + { + Console.WriteLine($"[{count,3}] {assistant.Id} {assistant.CreatedAt:s} {assistant.Name}"); + if (assistant.Name?.StartsWith("Test Assistant ") == true) + { + Assert.That(int.TryParse(assistant.Name["Test Assistant ".Length..], out int seenId), Is.True); + Assert.That(seenId, Is.LessThan(lastIdSeen)); + lastIdSeen = seenId; + } + count++; + } + + pageCount++; + if (lastIdSeen == 0 || count > 100) + { + break; + } + } + + Assert.That(count, Is.GreaterThanOrEqualTo(10)); + Assert.That(pageCount, Is.GreaterThanOrEqualTo(5)); + } + [Test] public async Task MessagesWithRoles() { From 0aca9087b89a1b4f60cf8ec82d02979684a0bf05 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Mon, 1 Jul 2024 10:31:36 -0700 Subject: [PATCH 29/72] updates based on feedback from Krzysztof --- .../Example01_RetrievalAugmentedGeneration.cs | 2 +- ...ple01_RetrievalAugmentedGenerationAsync.cs | 2 +- .../Assistants/Example02_FunctionCalling.cs | 2 +- .../Example02_FunctionCallingAsync.cs | 2 +- examples/Assistants/Example04_AllTheTools.cs | 2 +- .../Assistants/AssistantClient.Protocol.cs | 8 +-- src/Custom/Assistants/AssistantClient.cs | 42 ++++-------- .../Assistants/AssistantCollectionOptions.cs | 31 +++++++++ ...ken.cs => AssistantCollectionPageToken.cs} | 58 +++++++++++++--- src/Custom/Common/OpenAIPageToken.cs | 67 ++++++++----------- src/Utility/PageCollectionHelpers.cs | 6 +- tests/Assistants/AssistantTests.cs | 58 ++++++++-------- 12 files changed, 161 insertions(+), 119 deletions(-) create mode 100644 src/Custom/Assistants/AssistantCollectionOptions.cs rename src/Custom/Assistants/{GetAssistantsPageToken.cs => AssistantCollectionPageToken.cs} (57%) diff --git a/examples/Assistants/Example01_RetrievalAugmentedGeneration.cs b/examples/Assistants/Example01_RetrievalAugmentedGeneration.cs index 9998162e1..549ea3db0 100644 --- a/examples/Assistants/Example01_RetrievalAugmentedGeneration.cs +++ b/examples/Assistants/Example01_RetrievalAugmentedGeneration.cs @@ -99,7 +99,7 @@ public void Example01_RetrievalAugmentedGeneration() // Finally, we'll print out the full history for the thread that includes the augmented generation PageCollection messagePages - = assistantClient.GetMessages(threadRun.ThreadId, ListOrder.OldestFirst); + = assistantClient.GetMessages(threadRun.ThreadId, new MessageCollectionOptions() { Order = ListOrder.OldestFirst }); IEnumerable messages = messagePages.GetAllValues(); foreach (ThreadMessage message in messages) diff --git a/examples/Assistants/Example01_RetrievalAugmentedGenerationAsync.cs b/examples/Assistants/Example01_RetrievalAugmentedGenerationAsync.cs index f04fd9715..83b95fb0e 100644 --- a/examples/Assistants/Example01_RetrievalAugmentedGenerationAsync.cs +++ b/examples/Assistants/Example01_RetrievalAugmentedGenerationAsync.cs @@ -100,7 +100,7 @@ public async Task Example01_RetrievalAugmentedGenerationAsync() // Finally, we'll print out the full history for the thread that includes the augmented generation AsyncPageCollection messagePages - = assistantClient.GetMessagesAsync(threadRun.ThreadId, ListOrder.OldestFirst); + = assistantClient.GetMessagesAsync(threadRun.ThreadId, new MessageCollectionOptions() { Order = ListOrder.OldestFirst }); IAsyncEnumerable messages = messagePages.GetAllValuesAsync(); await foreach (ThreadMessage message in messages) diff --git a/examples/Assistants/Example02_FunctionCalling.cs b/examples/Assistants/Example02_FunctionCalling.cs index 8fcc2580f..a0eb05637 100644 --- a/examples/Assistants/Example02_FunctionCalling.cs +++ b/examples/Assistants/Example02_FunctionCalling.cs @@ -152,7 +152,7 @@ string GetCurrentWeather(string location, string unit = "celsius") if (run.Status == RunStatus.Completed) { PageCollection messagePages - = client.GetMessages(run.ThreadId, ListOrder.OldestFirst); + = client.GetMessages(run.ThreadId, new MessageCollectionOptions() { Order = ListOrder.OldestFirst }); IEnumerable messages = messagePages.GetAllValues(); foreach (ThreadMessage message in messages) diff --git a/examples/Assistants/Example02_FunctionCallingAsync.cs b/examples/Assistants/Example02_FunctionCallingAsync.cs index fdb449473..2ee924c56 100644 --- a/examples/Assistants/Example02_FunctionCallingAsync.cs +++ b/examples/Assistants/Example02_FunctionCallingAsync.cs @@ -152,7 +152,7 @@ string GetCurrentWeather(string location, string unit = "celsius") if (run.Status == RunStatus.Completed) { AsyncPageCollection messagePages - = client.GetMessagesAsync(run.ThreadId, ListOrder.OldestFirst); + = client.GetMessagesAsync(run.ThreadId, new MessageCollectionOptions() { Order = ListOrder.OldestFirst }); IAsyncEnumerable messages = messagePages.GetAllValuesAsync(); await foreach (ThreadMessage message in messages) diff --git a/examples/Assistants/Example04_AllTheTools.cs b/examples/Assistants/Example04_AllTheTools.cs index 3fa08dda9..a13427e1e 100644 --- a/examples/Assistants/Example04_AllTheTools.cs +++ b/examples/Assistants/Example04_AllTheTools.cs @@ -138,7 +138,7 @@ static string GetNameOfFamilyMember(string relation) if (run.Status == RunStatus.Completed) { PageCollection messagePages - = client.GetMessages(run.ThreadId, ListOrder.OldestFirst); + = client.GetMessages(run.ThreadId, new MessageCollectionOptions() { Order = ListOrder.OldestFirst }); IEnumerable messages = messagePages.GetAllValues(); foreach (ThreadMessage message in messages) diff --git a/src/Custom/Assistants/AssistantClient.Protocol.cs b/src/Custom/Assistants/AssistantClient.Protocol.cs index 9ad87804a..0d9320440 100644 --- a/src/Custom/Assistants/AssistantClient.Protocol.cs +++ b/src/Custom/Assistants/AssistantClient.Protocol.cs @@ -67,11 +67,11 @@ public virtual ClientResult CreateAssistant(BinaryContent content, RequestOption /// The response returned from the service. public virtual IAsyncEnumerable GetAssistantsAsync(int? limit, string order, string after, string before, RequestOptions options) { - GetAssistantsPageToken firstPageToken = GetAssistantsPageToken.FromOptions(limit, order, after, before); + AssistantCollectionPageToken firstPageToken = AssistantCollectionPageToken.FromOptions(limit, order, after, before); return OpenAIPageCollectionHelpers.CreateAsync( firstPageToken, GetAssistantsPageAsync, - GetAssistantsPageToken.FromToken, + AssistantCollectionPageToken.FromToken, options); } @@ -107,8 +107,8 @@ internal virtual async Task GetAssistantsPageAsync(int? limit, str /// The response returned from the service. public virtual IEnumerable GetAssistants(int? limit, string order, string after, string before, RequestOptions options) { - GetAssistantsPageToken firstPageToken = GetAssistantsPageToken.FromOptions(limit, order, after, before); - return OpenAIPageCollectionHelpers.CreateProtocol(firstPageToken, GetAssistantsPage, GetAssistantsPageToken.FromToken, options); + AssistantCollectionPageToken firstPageToken = AssistantCollectionPageToken.FromOptions(limit, order, after, before); + return OpenAIPageCollectionHelpers.CreateProtocol(firstPageToken, GetAssistantsPage, AssistantCollectionPageToken.FromToken, options); } internal virtual ClientResult GetAssistantsPage(int? limit, string order, string after, string before, RequestOptions options) diff --git a/src/Custom/Assistants/AssistantClient.cs b/src/Custom/Assistants/AssistantClient.cs index 563299794..677188cb4 100644 --- a/src/Custom/Assistants/AssistantClient.cs +++ b/src/Custom/Assistants/AssistantClient.cs @@ -104,27 +104,18 @@ public virtual ClientResult CreateAssistant(string model, AssistantCr /// /// Returns a collection of instances. /// - /// - /// The order that results should appear in the list according to their created_at - /// timestamp. - /// - /// The number of values to return in a single page in the page collection. - /// The id of the item preceeding the first item in the collection. - /// The id of the item following the last item in the collection. + /// Options describing the collection to return. /// A token that can be used to cancel this method call. /// A collection of assistants that can be enumerated using await foreach. public virtual AsyncPageCollection GetAssistantsAsync( - ListOrder? order = null, - int? pageSize = null, - string afterId = default, - string beforeId = default, + AssistantCollectionOptions options = default, CancellationToken cancellationToken = default) { - GetAssistantsPageToken firstPageToken = GetAssistantsPageToken.FromOptions(limit: pageSize, order: order?.ToString(), after: afterId, before: beforeId); + AssistantCollectionPageToken firstPageToken = AssistantCollectionPageToken.FromOptions(options); return OpenAIPageCollectionHelpers.CreateAsync( firstPageToken, GetAssistantsPageAsync, - GetAssistantsPageToken.FromToken, + AssistantCollectionPageToken.FromToken, cancellationToken.ToRequestOptions()); } @@ -138,38 +129,29 @@ public virtual AsyncPageCollection GetAssistantsAsync( ContinuationToken firstPageToken, CancellationToken cancellationToken = default) { - GetAssistantsPageToken pageToken = GetAssistantsPageToken.FromToken(firstPageToken); + AssistantCollectionPageToken pageToken = AssistantCollectionPageToken.FromToken(firstPageToken); return OpenAIPageCollectionHelpers.CreateAsync( firstPageToken, GetAssistantsPageAsync, - GetAssistantsPageToken.FromToken, + AssistantCollectionPageToken.FromToken, cancellationToken.ToRequestOptions()); } /// /// Returns a collection of instances. /// - /// - /// The order that results should appear in the list according to their created_at - /// timestamp. - /// - /// The number of values to return in a single page in the page collection. - /// The id of the item preceeding the first item in the collection. - /// The id of the item following the last item in the collection. + /// Options describing the collection to return. /// A token that can be used to cancel this method call. /// A collection of assistants that can be enumerated using foreach. public virtual PageCollection GetAssistants( - ListOrder? order = null, - int? pageSize = null, - string afterId = default, - string beforeId = default, + AssistantCollectionOptions options = default, CancellationToken cancellationToken = default) { - GetAssistantsPageToken firstPageToken = GetAssistantsPageToken.FromOptions(limit: pageSize, order: order?.ToString(), after: afterId, before: beforeId); + AssistantCollectionPageToken firstPageToken = AssistantCollectionPageToken.FromOptions(options); return OpenAIPageCollectionHelpers.Create( firstPageToken, GetAssistantsPage, - GetAssistantsPageToken.FromToken, + AssistantCollectionPageToken.FromToken, cancellationToken.ToRequestOptions()); } @@ -183,11 +165,11 @@ public virtual PageCollection GetAssistants( ContinuationToken firstPageToken, CancellationToken cancellationToken = default) { - GetAssistantsPageToken pageToken = GetAssistantsPageToken.FromToken(firstPageToken); + AssistantCollectionPageToken pageToken = AssistantCollectionPageToken.FromToken(firstPageToken); return OpenAIPageCollectionHelpers.Create( pageToken, GetAssistantsPage, - GetAssistantsPageToken.FromToken, + AssistantCollectionPageToken.FromToken, cancellationToken.ToRequestOptions()); } diff --git a/src/Custom/Assistants/AssistantCollectionOptions.cs b/src/Custom/Assistants/AssistantCollectionOptions.cs new file mode 100644 index 000000000..d78696b94 --- /dev/null +++ b/src/Custom/Assistants/AssistantCollectionOptions.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace OpenAI.Assistants; + +public class AssistantCollectionOptions +{ + public AssistantCollectionOptions() { } + + /// + /// The order that results should appear in the list according to + /// their created_at timestamp. + /// + public ListOrder? Order { get; init; } + + /// + /// The number of values to return in a page result. + /// + public int? PageSize { get; init; } + + /// + /// The id of the item preceeding the first item in the collection. + /// + public string AfterId { get; init; } + + /// + /// The id of the item following the last item in the collection. + /// + public string BeforeId { get; init; } +} diff --git a/src/Custom/Assistants/GetAssistantsPageToken.cs b/src/Custom/Assistants/AssistantCollectionPageToken.cs similarity index 57% rename from src/Custom/Assistants/GetAssistantsPageToken.cs rename to src/Custom/Assistants/AssistantCollectionPageToken.cs index ead9d2ac3..f83b01fd1 100644 --- a/src/Custom/Assistants/GetAssistantsPageToken.cs +++ b/src/Custom/Assistants/AssistantCollectionPageToken.cs @@ -1,15 +1,16 @@ using System; using System.ClientModel; using System.Diagnostics; +using System.IO; using System.Text.Json; #nullable enable namespace OpenAI.Assistants; -internal class GetAssistantsPageToken : OpenAIPageToken +internal class AssistantCollectionPageToken : OpenAIPageToken { - public GetAssistantsPageToken(int? limit, string? order, string? after, string? before) + public AssistantCollectionPageToken(int? limit, string? order, string? after, string? before) : base(limit, order, after, before) { } @@ -17,12 +18,49 @@ public GetAssistantsPageToken(int? limit, string? order, string? after, string? public override OpenAIPageToken? GetNextPageToken(bool hasMore, string? lastId) => GetNextPageToken(Limit, Order, lastId, Before, hasMore); - public static GetAssistantsPageToken FromOptions(int? limit, string? order, string? after, string? before) - => new GetAssistantsPageToken(limit, order, after, before); + public override BinaryData ToBytes() + { + using MemoryStream stream = new(); + using Utf8JsonWriter writer = new(stream); + + writer.WriteStartObject(); + + if (Limit.HasValue) + { + writer.WriteNumber("limit", Limit.Value); + } + + if (Order is not null) + { + writer.WriteString("order", Order); + } + + if (After is not null) + { + writer.WriteString("after", After); + } + + if (Before is not null) + { + writer.WriteString("before", Before); + } + + writer.WriteEndObject(); - public static GetAssistantsPageToken FromToken(ContinuationToken token) + writer.Flush(); + stream.Position = 0; + + return BinaryData.FromStream(stream); + } + + // Convenience - first page request + public static AssistantCollectionPageToken FromOptions(AssistantCollectionOptions options) + => new(options?.PageSize, options?.Order?.ToString(), options?.AfterId, options?.BeforeId); + + // Convenience - continuation page request + public static AssistantCollectionPageToken FromToken(ContinuationToken token) { - if (token is GetAssistantsPageToken pageToken) + if (token is AssistantCollectionPageToken pageToken) { return pageToken; } @@ -84,13 +122,17 @@ public static GetAssistantsPageToken FromToken(ContinuationToken token) return new(limit, order, after, before); } - public static GetAssistantsPageToken? GetNextPageToken(int? limit, string? order, string? after, string? before, bool hasMore) + // Protocol + public static AssistantCollectionPageToken FromOptions(int? limit, string? order, string? after, string? before) + => new AssistantCollectionPageToken(limit, order, after, before); + + private static AssistantCollectionPageToken? GetNextPageToken(int? limit, string? order, string? after, string? before, bool hasMore) { if (!hasMore || after is null) { return null; } - return new GetAssistantsPageToken(limit, order, after, before); + return new AssistantCollectionPageToken(limit, order, after, before); } } \ No newline at end of file diff --git a/src/Custom/Common/OpenAIPageToken.cs b/src/Custom/Common/OpenAIPageToken.cs index c4c8d8ca8..c678355c0 100644 --- a/src/Custom/Common/OpenAIPageToken.cs +++ b/src/Custom/Common/OpenAIPageToken.cs @@ -25,45 +25,42 @@ public OpenAIPageToken(int? limit, string? order, string? after, string? before) public string? Before { get; } - public override BinaryData ToBytes() - { - using MemoryStream stream = new(); - using Utf8JsonWriter writer = new(stream); + //public override BinaryData ToBytes() + //{ + // using MemoryStream stream = new(); + // using Utf8JsonWriter writer = new(stream); - writer.WriteStartObject(); + // writer.WriteStartObject(); - if (Limit.HasValue) - { - writer.WriteNumber("limit", Limit.Value); - } + // if (Limit.HasValue) + // { + // writer.WriteNumber("limit", Limit.Value); + // } - if (Order is not null) - { - writer.WriteString("order", Order); - } + // if (Order is not null) + // { + // writer.WriteString("order", Order); + // } - if (After is not null) - { - writer.WriteString("after", After); - } + // if (After is not null) + // { + // writer.WriteString("after", After); + // } - if (Before is not null) - { - writer.WriteString("before", Before); - } + // if (Before is not null) + // { + // writer.WriteString("before", Before); + // } - writer.WriteEndObject(); + // writer.WriteEndObject(); - writer.Flush(); - stream.Position = 0; - return BinaryData.FromStream(stream); - } + // writer.Flush(); + // stream.Position = 0; + // return BinaryData.FromStream(stream); + //} public abstract OpenAIPageToken? GetNextPageToken(bool hasMore, string? lastId); - - //public static OpenAIPageToken FromOptions(int? limit, string? order, string? after, string? before) - // => new OpenAIPageToken(limit, order, after, before); - + //public static OpenAIPageToken FromToken(ContinuationToken token) //{ // if (token is OpenAIPageToken openAIPageToken) @@ -127,14 +124,4 @@ public override BinaryData ToBytes() // return new(limit, order, after, before); //} - - //public static OpenAIPageToken? GetNextPageToken(int? limit, string? order, string? after, string? before, bool hasMore) - //{ - // if (!hasMore || after is null) - // { - // return null; - // } - - // return new OpenAIPageToken(limit, order, after, before); - //} } \ No newline at end of file diff --git a/src/Utility/PageCollectionHelpers.cs b/src/Utility/PageCollectionHelpers.cs index 59dc461b2..c789ca891 100644 --- a/src/Utility/PageCollectionHelpers.cs +++ b/src/Utility/PageCollectionHelpers.cs @@ -41,7 +41,7 @@ public AsyncFuncPageCollection(ContinuationToken firstPageToken, _getPageAsync = getPageAsync; } - public override ContinuationToken FirstPageToken => _firstPageToken; + protected override ContinuationToken FirstPageToken => _firstPageToken; public override async Task> GetPageAsyncCore(ContinuationToken pageToken) => await _getPageAsync(pageToken).ConfigureAwait(false); @@ -59,9 +59,9 @@ public FuncPageCollection(ContinuationToken firstPageToken, _getPage = getPage; } - public override ContinuationToken FirstPageToken => _firstPageToken; + protected override ContinuationToken FirstPageToken => _firstPageToken; - public override PageResult GetPageCore(ContinuationToken pageToken) + protected override PageResult GetPageCore(ContinuationToken pageToken) => _getPage(pageToken); } diff --git a/tests/Assistants/AssistantTests.cs b/tests/Assistants/AssistantTests.cs index 101d368ac..7c647b77b 100644 --- a/tests/Assistants/AssistantTests.cs +++ b/tests/Assistants/AssistantTests.cs @@ -129,10 +129,10 @@ public void BasicMessageOperationsWork() }); Assert.That(message.Metadata.TryGetValue("messageMetadata", out metadataValue) && metadataValue == "newValue"); - IEnumerable messagePage = client.GetMessages(thread).GetAllValues(); - Assert.That(messagePage.Count, Is.EqualTo(1)); - Assert.That(messagePage.First().Id, Is.EqualTo(message.Id)); - Assert.That(messagePage.First().Metadata.TryGetValue("messageMetadata", out metadataValue) && metadataValue == "newValue"); + PageResult messagePage = client.GetMessages(thread).GetCurrentPage(); + Assert.That(messagePage.Values.Count, Is.EqualTo(1)); + Assert.That(messagePage.Values[0].Id, Is.EqualTo(message.Id)); + Assert.That(messagePage.Values[0].Metadata.TryGetValue("messageMetadata", out metadataValue) && metadataValue == "newValue"); } [Test] @@ -160,16 +160,16 @@ public void ThreadWithInitialMessagesWorks() }; AssistantThread thread = client.CreateThread(options); Validate(thread); - IEnumerable messages = client.GetMessages(thread, resultOrder: ListOrder.OldestFirst).GetAllValues(); - Assert.That(messages.Count, Is.EqualTo(2)); - Assert.That(messages.First().Role, Is.EqualTo(MessageRole.User)); - Assert.That(messages.First().Content?.Count, Is.EqualTo(1)); - Assert.That(messages.First().Content[0].Text, Is.EqualTo("Hello, world!")); - Assert.That(messages.ElementAt(1).Content?.Count, Is.EqualTo(2)); - Assert.That(messages.ElementAt(1).Content[0], Is.Not.Null); - Assert.That(messages.ElementAt(1).Content[0].Text, Is.EqualTo("Can you describe this image for me?")); - Assert.That(messages.ElementAt(1).Content[1], Is.Not.Null); - Assert.That(messages.ElementAt(1).Content[1].ImageUrl.AbsoluteUri, Is.EqualTo("https://test.openai.com/image.png")); + PageResult messagesPage = client.GetMessages(thread, new MessageCollectionOptions() { Order = ListOrder.OldestFirst }).GetCurrentPage(); + Assert.That(messagesPage.Values.Count, Is.EqualTo(2)); + Assert.That(messagesPage.Values[0].Role, Is.EqualTo(MessageRole.User)); + Assert.That(messagesPage.Values[0].Content?.Count, Is.EqualTo(1)); + Assert.That(messagesPage.Values[0].Content[0].Text, Is.EqualTo("Hello, world!")); + Assert.That(messagesPage.Values[1].Content?.Count, Is.EqualTo(2)); + Assert.That(messagesPage.Values[1].Content[0], Is.Not.Null); + Assert.That(messagesPage.Values[1].Content[0].Text, Is.EqualTo("Can you describe this image for me?")); + Assert.That(messagesPage.Values[1].Content[1], Is.Not.Null); + Assert.That(messagesPage.Values[1].Content[1].ImageUrl.AbsoluteUri, Is.EqualTo("https://test.openai.com/image.png")); } [Test] @@ -180,8 +180,8 @@ public void BasicRunOperationsWork() Validate(assistant); AssistantThread thread = client.CreateThread(); Validate(thread); - IEnumerable runs = client.GetRuns(thread).GetAllValues(); - Assert.That(runs.Count, Is.EqualTo(0)); + PageResult runsPage = client.GetRunsPage(thread); + Assert.That(runsPage.Values.Count, Is.EqualTo(0)); ThreadMessage message = client.CreateMessage(thread.Id, MessageRole.User, ["Hello, assistant!"]); Validate(message); ThreadRun run = client.CreateRun(thread.Id, assistant.Id); @@ -190,12 +190,12 @@ public void BasicRunOperationsWork() Assert.That(run.CreatedAt, Is.GreaterThan(s_2024)); ThreadRun retrievedRun = client.GetRun(thread.Id, run.Id); Assert.That(retrievedRun.Id, Is.EqualTo(run.Id)); - runs = client.GetRuns(thread).GetAllValues(); - Assert.That(runs.Count, Is.EqualTo(1)); - Assert.That(runs.First().Id, Is.EqualTo(run.Id)); + runsPage = client.GetRunsPage(thread); + Assert.That(runsPage.Values.Count, Is.EqualTo(1)); + Assert.That(runsPage.Values[0].Id, Is.EqualTo(run.Id)); - IEnumerable messages = client.GetMessages(thread).GetAllValues(); - Assert.That(messages.Count, Is.GreaterThanOrEqualTo(1)); + PageResult messagesPage = client.GetMessagesPage(thread); + Assert.That(messagesPage.Values.Count, Is.GreaterThanOrEqualTo(1)); for (int i = 0; i < 10 && !run.Status.IsTerminal; i++) { Thread.Sleep(500); @@ -208,12 +208,12 @@ public void BasicRunOperationsWork() Assert.That(run.FailedAt, Is.Null); Assert.That(run.IncompleteDetails, Is.Null); - messages = client.GetMessages(thread).GetAllValues(); - Assert.That(messages.Count, Is.EqualTo(2)); + messagesPage = client.GetMessagesPage(thread); + Assert.That(messagesPage.Values.Count, Is.EqualTo(2)); - Assert.That(messages.ElementAt(0).Role, Is.EqualTo(MessageRole.Assistant)); - Assert.That(messages.ElementAt(1).Role, Is.EqualTo(MessageRole.User)); - Assert.That(messages.ElementAt(1).Id, Is.EqualTo(message.Id)); + Assert.That(messagesPage.Values[0].Role, Is.EqualTo(MessageRole.Assistant)); + Assert.That(messagesPage.Values[1].Role, Is.EqualTo(MessageRole.User)); + Assert.That(messagesPage.Values[1].Id, Is.EqualTo(message.Id)); } [Test] @@ -269,7 +269,7 @@ public void BasicRunStepFunctionalityWorks() Assert.That(run.Usage?.TotalTokens, Is.GreaterThan(0)); PageCollection pages = client.GetRunSteps(run); - PageResult firstPage = pages.First(); + PageResult firstPage = pages.GetCurrentPage(); IEnumerable runSteps = pages.GetAllValues(); Assert.That(runSteps.Count, Is.GreaterThan(1)); @@ -391,7 +391,7 @@ public void FunctionToolsWork() } Assert.That(run.Status, Is.EqualTo(RunStatus.Completed)); - IEnumerable messages = client.GetMessages(run.ThreadId, ListOrder.NewestFirst).GetAllValues(); + CollectionResult messages = client.GetMessages(run.ThreadId, new MessageCollectionOptions() { Order = ListOrder.NewestFirst }).GetAllValues(); Assert.That(messages.Count, Is.GreaterThan(1)); Assert.That(messages.First().Role, Is.EqualTo(MessageRole.Assistant)); Assert.That(messages.First().Content?[0], Is.Not.Null); @@ -600,7 +600,7 @@ This file describes the favorite foods of several people. } while (run?.Status.IsTerminal == false); Assert.That(run.Status, Is.EqualTo(RunStatus.Completed)); - IEnumerable messages = client.GetMessages(thread, resultOrder: ListOrder.NewestFirst).GetAllValues(); + IEnumerable messages = client.GetMessages(thread, new() { Order = ListOrder.NewestFirst }).GetAllValues(); foreach (ThreadMessage message in messages) { foreach (MessageContent content in message.Content) From c4a8a637070a47c7cecf548e7344533e6127de36 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Mon, 1 Jul 2024 11:28:54 -0700 Subject: [PATCH 30/72] add protocol implementations of all Assistant-related paged methods --- .../Assistants/AssistantClient.Convenience.cs | 37 ++-- .../Assistants/AssistantClient.Protocol.cs | 108 ++++++++++-- src/Custom/Assistants/AssistantClient.cs | 45 ++--- .../Assistants/MessageCollectionOptions.cs | 31 ++++ .../Assistants/MessageCollectionPageToken.cs | 153 +++++++++++++++++ src/Custom/Assistants/RunCollectionOptions.cs | 31 ++++ .../Assistants/RunCollectionPageToken.cs | 149 +++++++++++++++++ .../Assistants/RunStepCollectionOptions.cs | 31 ++++ .../Assistants/RunStepCollectionPageToken.cs | 158 ++++++++++++++++++ .../Common/OpenAIPageCollectionHelpers.cs | 30 ++-- tests/Assistants/AssistantTests.cs | 33 +++- 11 files changed, 710 insertions(+), 96 deletions(-) create mode 100644 src/Custom/Assistants/MessageCollectionOptions.cs create mode 100644 src/Custom/Assistants/MessageCollectionPageToken.cs create mode 100644 src/Custom/Assistants/RunCollectionOptions.cs create mode 100644 src/Custom/Assistants/RunCollectionPageToken.cs create mode 100644 src/Custom/Assistants/RunStepCollectionOptions.cs create mode 100644 src/Custom/Assistants/RunStepCollectionPageToken.cs diff --git a/src/Custom/Assistants/AssistantClient.Convenience.cs b/src/Custom/Assistants/AssistantClient.Convenience.cs index 1c48698b1..5ff10ca49 100644 --- a/src/Custom/Assistants/AssistantClient.Convenience.cs +++ b/src/Custom/Assistants/AssistantClient.Convenience.cs @@ -129,36 +129,30 @@ public virtual ClientResult CreateMessage( /// Returns a collection of instances from an existing . /// /// The thread to list messages from. - /// - /// The order that results should appear in the list according to their created_at - /// timestamp. - /// + /// Options describing the collection to return. /// A collection of messages that can be enumerated using await foreach. public virtual AsyncPageCollection GetMessagesAsync( AssistantThread thread, - ListOrder? resultOrder = default) + MessageCollectionOptions options = default) { Argument.AssertNotNull(thread, nameof(thread)); - return GetMessagesAsync(thread.Id, resultOrder); + return GetMessagesAsync(thread.Id, options); } /// /// Returns a collection of instances from an existing . /// /// The thread to list messages from. - /// - /// The order that results should appear in the list according to their created_at - /// timestamp. - /// + /// Options describing the collection to return. /// A collection of messages that can be enumerated using foreach. public virtual PageCollection GetMessages( AssistantThread thread, - ListOrder? resultOrder = default) + MessageCollectionOptions options = default) { Argument.AssertNotNull(thread, nameof(thread)); - return GetMessages(thread.Id, resultOrder); + return GetMessages(thread.Id, options); } /// @@ -313,38 +307,33 @@ public virtual CollectionResult CreateThreadAndRunStreaming( /// Returns a collection of instances associated with an existing . /// /// The thread that runs in the list should be associated with. - /// - /// The order that results should appear in the list according to their created_at - /// timestamp. - /// + /// Options describing the collection to return. /// A collection of runs that can be enumerated using await foreach. public virtual AsyncPageCollection GetRunsAsync( AssistantThread thread, - ListOrder? resultOrder = default) + RunCollectionOptions options = default) { Argument.AssertNotNull(thread, nameof(thread)); - return GetRunsAsync(thread.Id, resultOrder); + return GetRunsAsync(thread.Id, options); } /// /// Returns a collection of instances associated with an existing . /// /// The thread that runs in the list should be associated with. - /// - /// The order that results should appear in the list according to their created_at - /// timestamp. - /// + /// Options describing the collection to return. /// A collection of runs that can be enumerated using foreach. public virtual PageCollection GetRuns( AssistantThread thread, - ListOrder? resultOrder = default) + RunCollectionOptions options = default) { Argument.AssertNotNull(thread, nameof(thread)); - return GetRuns(thread.Id, resultOrder); + return GetRuns(thread.Id, options); } + /// /// Gets a refreshed instance of an existing . /// diff --git a/src/Custom/Assistants/AssistantClient.Protocol.cs b/src/Custom/Assistants/AssistantClient.Protocol.cs index 0d9320440..fa591a2bf 100644 --- a/src/Custom/Assistants/AssistantClient.Protocol.cs +++ b/src/Custom/Assistants/AssistantClient.Protocol.cs @@ -68,11 +68,13 @@ public virtual ClientResult CreateAssistant(BinaryContent content, RequestOption public virtual IAsyncEnumerable GetAssistantsAsync(int? limit, string order, string after, string before, RequestOptions options) { AssistantCollectionPageToken firstPageToken = AssistantCollectionPageToken.FromOptions(limit, order, after, before); - return OpenAIPageCollectionHelpers.CreateAsync( - firstPageToken, - GetAssistantsPageAsync, - AssistantCollectionPageToken.FromToken, - options); + return OpenAIPageCollectionHelpers.CreateProtocolAsync(firstPageToken, GetAssistantsPageAsync, AssistantCollectionPageToken.FromToken, options); + } + + internal virtual async Task GetAssistantsPageAsync(ContinuationToken pageToken, RequestOptions options) + { + AssistantCollectionPageToken token = AssistantCollectionPageToken.FromToken(pageToken); + return await GetAssistantsPageAsync(token.Limit, token.Order, token.After, token.Before, options).ConfigureAwait(false); } internal virtual async Task GetAssistantsPageAsync(int? limit, string order, string after, string before, RequestOptions options) @@ -111,6 +113,12 @@ public virtual IEnumerable GetAssistants(int? limit, string order, return OpenAIPageCollectionHelpers.CreateProtocol(firstPageToken, GetAssistantsPage, AssistantCollectionPageToken.FromToken, options); } + internal virtual ClientResult GetAssistantsPage(ContinuationToken pageToken, RequestOptions options) + { + AssistantCollectionPageToken token = AssistantCollectionPageToken.FromToken(pageToken); + return GetAssistantsPage(token.Limit, token.Order, token.After, token.Before, options); + } + internal virtual ClientResult GetAssistantsPage(int? limit, string order, string after, string before, RequestOptions options) { using PipelineMessage message = CreateGetAssistantsRequest(limit, order, after, before, options); @@ -231,12 +239,36 @@ public virtual Task CreateMessageAsync(string threadId, BinaryCont public virtual ClientResult CreateMessage(string threadId, BinaryContent content, RequestOptions options = null) => _messageSubClient.CreateMessage(threadId, content, options); + public virtual IAsyncEnumerable GetMessagesAsync(string threadId, int? limit, string order, string after, string before, RequestOptions options) + { + MessageCollectionPageToken firstPageToken = MessageCollectionPageToken.FromOptions(threadId, limit, order, after, before); + return OpenAIPageCollectionHelpers.CreateProtocolAsync(firstPageToken, GetMessagesPageAsync, MessageCollectionPageToken.FromToken, options); + } + + internal virtual async Task GetMessagesPageAsync(ContinuationToken pageToken, RequestOptions options) + { + MessageCollectionPageToken token = MessageCollectionPageToken.FromToken(pageToken); + return await GetMessagesPageAsync(token.ThreadId, token.Limit, token.Order, token.After, token.Before, options).ConfigureAwait(false); + } + /// - public virtual Task GetMessagesAsync(string threadId, int? limit, string order, string after, string before, RequestOptions options) - => _messageSubClient.GetMessagesAsync(threadId, limit, order, after, before, options); + internal virtual async Task GetMessagesPageAsync(string threadId, int? limit, string order, string after, string before, RequestOptions options) + => await _messageSubClient.GetMessagesAsync(threadId, limit, order, after, before, options).ConfigureAwait(false); + + public virtual IEnumerable GetMessages(string threadId, int? limit, string order, string after, string before, RequestOptions options) + { + MessageCollectionPageToken firstPageToken = MessageCollectionPageToken.FromOptions(threadId, limit, order, after, before); + return OpenAIPageCollectionHelpers.CreateProtocol(firstPageToken, GetMessagesPage, MessageCollectionPageToken.FromToken, options); + } + + internal virtual ClientResult GetMessagesPage(ContinuationToken pageToken, RequestOptions options) + { + MessageCollectionPageToken token = MessageCollectionPageToken.FromToken(pageToken); + return GetMessagesPage(token.ThreadId, token.Limit, token.Order, token.After, token.Before, options); + } /// - public virtual ClientResult GetMessages(string threadId, int? limit, string order, string after, string before, RequestOptions options) + internal virtual ClientResult GetMessagesPage(string threadId, int? limit, string order, string after, string before, RequestOptions options) => _messageSubClient.GetMessages(threadId, limit, order, after, before, options); /// @@ -277,12 +309,36 @@ public virtual Task CreateRunAsync(string threadId, BinaryContent public virtual ClientResult CreateRun(string threadId, BinaryContent content, RequestOptions options = null) => _runSubClient.CreateRun(threadId, content, options); + public virtual IAsyncEnumerable GetRunsAsync(string threadId, int? limit, string order, string after, string before, RequestOptions options) + { + RunCollectionPageToken firstPageToken = RunCollectionPageToken.FromOptions(threadId, limit, order, after, before); + return OpenAIPageCollectionHelpers.CreateProtocolAsync(firstPageToken, GetRunsPageAsync, RunCollectionPageToken.FromToken, options); + } + + internal async virtual Task GetRunsPageAsync(ContinuationToken pageToken, RequestOptions options) + { + RunCollectionPageToken token = RunCollectionPageToken.FromToken(pageToken); + return await GetRunsPageAsync(token.ThreadId, token.Limit, token.Order, token.After, token.Before, options).ConfigureAwait(false); + } + /// - public virtual Task GetRunsAsync(string threadId, int? limit, string order, string after, string before, RequestOptions options) - => _runSubClient.GetRunsAsync(threadId, limit, order, after, before, options); + internal async virtual Task GetRunsPageAsync(string threadId, int? limit, string order, string after, string before, RequestOptions options) + => await _runSubClient.GetRunsAsync(threadId, limit, order, after, before, options).ConfigureAwait(false); + + public virtual IEnumerable GetRuns(string threadId, int? limit, string order, string after, string before, RequestOptions options) + { + RunCollectionPageToken firstPageToken = RunCollectionPageToken.FromOptions(threadId, limit, order, after, before); + return OpenAIPageCollectionHelpers.CreateProtocol(firstPageToken, GetRunsPage, RunCollectionPageToken.FromToken, options); + } + + internal virtual ClientResult GetRunsPage(ContinuationToken pageToken, RequestOptions options) + { + RunCollectionPageToken token = RunCollectionPageToken.FromToken(pageToken); + return GetRunsPage(token.ThreadId, token.Limit, token.Order, token.After, token.Before, options); + } /// - public virtual ClientResult GetRuns(string threadId, int? limit, string order, string after, string before, RequestOptions options) + internal virtual ClientResult GetRunsPage(string threadId, int? limit, string order, string after, string before, RequestOptions options) => _runSubClient.GetRuns(threadId, limit, order, after, before, options); /// @@ -317,12 +373,36 @@ public virtual Task SubmitToolOutputsToRunAsync(string threadId, s public virtual ClientResult SubmitToolOutputsToRun(string threadId, string runId, BinaryContent content, RequestOptions options = null) => _runSubClient.SubmitToolOutputsToRun(threadId, runId, content, options); + public virtual IAsyncEnumerable GetRunStepsAsync(string threadId, string runId, int? limit, string order, string after, string before, RequestOptions options) + { + RunStepCollectionPageToken firstPageToken = RunStepCollectionPageToken.FromOptions(threadId, runId, limit, order, after, before); + return OpenAIPageCollectionHelpers.CreateProtocolAsync(firstPageToken, GetRunStepsPageAsync, RunStepCollectionPageToken.FromToken, options); + } + + internal virtual async Task GetRunStepsPageAsync(ContinuationToken pageToken, RequestOptions options) + { + RunStepCollectionPageToken token = RunStepCollectionPageToken.FromToken(pageToken); + return await GetRunStepsPageAsync(token.ThreadId, token.RunId, token.Limit, token.Order, token.After, token.Before, options).ConfigureAwait(false); + } + /// - public virtual Task GetRunStepsAsync(string threadId, string runId, int? limit, string order, string after, string before, RequestOptions options) - => _runSubClient.GetRunStepsAsync(threadId, runId, limit, order, after, before, options); + internal virtual async Task GetRunStepsPageAsync(string threadId, string runId, int? limit, string order, string after, string before, RequestOptions options) + => await _runSubClient.GetRunStepsAsync(threadId, runId, limit, order, after, before, options).ConfigureAwait(false); + + public virtual IEnumerable GetRunSteps(string threadId, string runId, int? limit, string order, string after, string before, RequestOptions options) + { + RunStepCollectionPageToken firstPageToken = RunStepCollectionPageToken.FromOptions(threadId, runId, limit, order, after, before); + return OpenAIPageCollectionHelpers.CreateProtocol(firstPageToken, GetRunStepsPage, RunStepCollectionPageToken.FromToken, options); + } + + internal virtual ClientResult GetRunStepsPage(ContinuationToken pageToken, RequestOptions options) + { + RunStepCollectionPageToken token = RunStepCollectionPageToken.FromToken(pageToken); + return GetRunStepsPage(token.ThreadId, token.RunId, token.Limit, token.Order, token.After, token.Before, options); + } /// - public virtual ClientResult GetRunSteps(string threadId, string runId, int? limit, string order, string after, string before, RequestOptions options) + internal virtual ClientResult GetRunStepsPage(string threadId, string runId, int? limit, string order, string after, string before, RequestOptions options) => _runSubClient.GetRunSteps(threadId, runId, limit, order, after, before, options); /// diff --git a/src/Custom/Assistants/AssistantClient.cs b/src/Custom/Assistants/AssistantClient.cs index 677188cb4..351f7df94 100644 --- a/src/Custom/Assistants/AssistantClient.cs +++ b/src/Custom/Assistants/AssistantClient.cs @@ -380,18 +380,14 @@ public virtual ClientResult CreateMessage( /// Returns a collection of instances from an existing . /// /// The ID of the thread to list messages from. - /// - /// The order that results should appear in the list according to their created_at - /// timestamp. - /// - /// The number of values to return in a single page in the page collection. - /// The id of the item preceeding the first item in the collection. - /// The id of the item following the last item in the collection. + /// Options describing the collection to return. /// A token that can be used to cancel this method call. /// A collection of messages that can be enumerated using await foreach. public virtual AsyncPageCollection GetMessagesAsync( string threadId, - ListOrder? order = null, int? pageSize = null, string afterId = default, string beforeId = default, CancellationToken cancellationToken = default) + + MessageCollectionOptions options = default, + CancellationToken cancellationToken = default) { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); @@ -404,18 +400,13 @@ public virtual AsyncPageCollection GetMessagesAsync( /// Returns a collection of instances from an existing . /// /// The ID of the thread to list messages from. - /// - /// The order that results should appear in the list according to their created_at - /// timestamp. - /// - /// The number of values to return in a single page in the page collection. - /// The id of the item preceeding the first item in the collection. - /// The id of the item following the last item in the collection. + /// Options describing the collection to return. /// A token that can be used to cancel this method call. /// A collection of messages that can be enumerated using foreach. public virtual PageCollection GetMessages( string threadId, - ListOrder? order = null, int? pageSize = null, string afterId = default, string beforeId = default, CancellationToken cancellationToken = default) + MessageCollectionOptions options = default, + CancellationToken cancellationToken = default) { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); @@ -720,18 +711,13 @@ public virtual CollectionResult CreateThreadAndRunStreaming( /// Returns a collection of instances associated with an existing . /// /// The ID of the thread that runs in the list should be associated with. - /// - /// The order that results should appear in the list according to their created_at - /// timestamp. - /// - /// The number of values to return in a single page in the page collection. - /// The id of the item preceeding the first item in the collection. - /// The id of the item following the last item in the collection. + /// Options describing the collection to return. /// A token that can be used to cancel this method call. /// A collection of runs that can be enumerated using await foreach. public virtual AsyncPageCollection GetRunsAsync( string threadId, - ListOrder? order = null, int? pageSize = null, string afterId = default, string beforeId = default, CancellationToken cancellationToken = default) + RunCollectionOptions options = default, + CancellationToken cancellationToken = default) { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); @@ -744,18 +730,13 @@ public virtual AsyncPageCollection GetRunsAsync( /// Returns a collection of instances associated with an existing . /// /// The ID of the thread that runs in the list should be associated with. - /// - /// The order that results should appear in the list according to their created_at - /// timestamp. - /// - /// The number of values to return in a single page in the page collection. - /// The id of the item preceeding the first item in the collection. - /// The id of the item following the last item in the collection. + /// Options describing the collection to return. /// A token that can be used to cancel this method call. /// A collection of runs that can be enumerated using foreach. public virtual PageCollection GetRuns( string threadId, - ListOrder? order = null, int? pageSize = null, string afterId = default, string beforeId = default, CancellationToken cancellationToken = default) + RunCollectionOptions options = default, + CancellationToken cancellationToken = default) { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); diff --git a/src/Custom/Assistants/MessageCollectionOptions.cs b/src/Custom/Assistants/MessageCollectionOptions.cs new file mode 100644 index 000000000..e4aa159fa --- /dev/null +++ b/src/Custom/Assistants/MessageCollectionOptions.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace OpenAI.Assistants; + +public class MessageCollectionOptions +{ + public MessageCollectionOptions() { } + + /// + /// The order that results should appear in the list according to + /// their created_at timestamp. + /// + public ListOrder? Order { get; init; } + + /// + /// The number of values to return in a page result. + /// + public int? PageSize { get; init; } + + /// + /// The id of the item preceeding the first item in the collection. + /// + public string AfterId { get; init; } + + /// + /// The id of the item following the last item in the collection. + /// + public string BeforeId { get; init; } +} diff --git a/src/Custom/Assistants/MessageCollectionPageToken.cs b/src/Custom/Assistants/MessageCollectionPageToken.cs new file mode 100644 index 000000000..971adf8aa --- /dev/null +++ b/src/Custom/Assistants/MessageCollectionPageToken.cs @@ -0,0 +1,153 @@ +using System; +using System.ClientModel; +using System.Diagnostics; +using System.IO; +using System.Text.Json; + +#nullable enable + +namespace OpenAI.Assistants; + +internal class MessageCollectionPageToken : OpenAIPageToken +{ + public MessageCollectionPageToken(string threadId, int? limit, string? order, string? after, string? before) + : base(limit, order, after, before) + { + ThreadId = threadId; + } + + public string ThreadId { get; } + + public override BinaryData ToBytes() + { + using MemoryStream stream = new(); + using Utf8JsonWriter writer = new(stream); + + writer.WriteStartObject(); + writer.WriteString("threadId", ThreadId); + + if (Limit.HasValue) + { + writer.WriteNumber("limit", Limit.Value); + } + + if (Order is not null) + { + writer.WriteString("order", Order); + } + + if (After is not null) + { + writer.WriteString("after", After); + } + + if (Before is not null) + { + writer.WriteString("before", Before); + } + + writer.WriteEndObject(); + + writer.Flush(); + stream.Position = 0; + + return BinaryData.FromStream(stream); + } + + public override OpenAIPageToken? GetNextPageToken(bool hasMore, string? lastId) + => GetNextPageToken(ThreadId, Limit, Order, lastId, Before, hasMore); + + // Convenience - first page request + public static MessageCollectionPageToken FromOptions(string threadId, MessageCollectionOptions options) + => new(threadId, options?.PageSize, options?.Order?.ToString(), options?.AfterId, options?.BeforeId); + + // Convenience - continuation page request + public static MessageCollectionPageToken FromToken(ContinuationToken pageToken) + { + if (pageToken is MessageCollectionPageToken token) + { + return token; + } + + BinaryData data = pageToken.ToBytes(); + + if (data.ToMemory().Length == 0) + { + return new(string.Empty, default, default, default, default); + } + + Utf8JsonReader reader = new(data); + + string threadId = null!; + int? limit = null; + string? order = null; + string? after = null; + string? before = null; + + reader.Read(); + Debug.Assert(reader.TokenType == JsonTokenType.StartObject); + + while (reader.Read()) + { + if (reader.TokenType == JsonTokenType.EndObject) + { + break; + } + + Debug.Assert(reader.TokenType == JsonTokenType.PropertyName); + string propertyName = reader.GetString()!; + + switch (propertyName) + { + case "threadId": + reader.Read(); + Debug.Assert(reader.TokenType == JsonTokenType.String); + threadId = reader.GetString()!; + break; + case "limit": + reader.Read(); + Debug.Assert(reader.TokenType == JsonTokenType.Number); + limit = reader.GetInt32(); + break; + case "order": + reader.Read(); + Debug.Assert(reader.TokenType == JsonTokenType.String); + order = reader.GetString(); + break; + case "after": + reader.Read(); + Debug.Assert(reader.TokenType == JsonTokenType.String); + after = reader.GetString(); + break; + case "before": + reader.Read(); + Debug.Assert(reader.TokenType == JsonTokenType.String); + before = reader.GetString(); + break; + default: + throw new JsonException($"Unrecognized property '{propertyName}'."); + } + } + + if (threadId is null) + { + throw new ArgumentException("Failed to create MessageCollectionPageToken from provided pageToken.", nameof(pageToken)); + } + + return new(threadId, limit, order, after, before); + } + + // Protocol + public static MessageCollectionPageToken FromOptions(string threadId, int? limit, string? order, string? after, string? before) + => new MessageCollectionPageToken(threadId, limit, order, after, before); + + private static MessageCollectionPageToken? GetNextPageToken(string threadId, int? limit, string? order, string? after, string? before, bool hasMore) + { + if (!hasMore || after is null) + { + return null; + } + + return new MessageCollectionPageToken(threadId, limit, order, after, before); + } +} \ No newline at end of file diff --git a/src/Custom/Assistants/RunCollectionOptions.cs b/src/Custom/Assistants/RunCollectionOptions.cs new file mode 100644 index 000000000..53d503ba3 --- /dev/null +++ b/src/Custom/Assistants/RunCollectionOptions.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace OpenAI.Assistants; + +public class RunCollectionOptions +{ + public RunCollectionOptions() { } + + /// + /// The order that results should appear in the list according to + /// their created_at timestamp. + /// + public ListOrder? Order { get; init; } + + /// + /// The number of values to return in a page result. + /// + public int? PageSize { get; init; } + + /// + /// The id of the item preceeding the first item in the collection. + /// + public string AfterId { get; init; } + + /// + /// The id of the item following the last item in the collection. + /// + public string BeforeId { get; init; } +} diff --git a/src/Custom/Assistants/RunCollectionPageToken.cs b/src/Custom/Assistants/RunCollectionPageToken.cs new file mode 100644 index 000000000..094ceb0ae --- /dev/null +++ b/src/Custom/Assistants/RunCollectionPageToken.cs @@ -0,0 +1,149 @@ +using System; +using System.ClientModel; +using System.Diagnostics; +using System.IO; +using System.Text.Json; + +#nullable enable + +namespace OpenAI.Assistants; + +internal class RunCollectionPageToken : OpenAIPageToken +{ + public RunCollectionPageToken(string threadId, int? limit, string? order, string? after, string? before) + : base(limit, order, after, before) + { + ThreadId = threadId; + } + + public string ThreadId { get; } + + public override BinaryData ToBytes() + { + using MemoryStream stream = new(); + using Utf8JsonWriter writer = new(stream); + + writer.WriteStartObject(); + writer.WriteString("threadId", ThreadId); + + if (Limit.HasValue) + { + writer.WriteNumber("limit", Limit.Value); + } + + if (Order is not null) + { + writer.WriteString("order", Order); + } + + if (After is not null) + { + writer.WriteString("after", After); + } + + if (Before is not null) + { + writer.WriteString("before", Before); + } + + writer.WriteEndObject(); + + writer.Flush(); + stream.Position = 0; + + return BinaryData.FromStream(stream); + } + + public override OpenAIPageToken? GetNextPageToken(bool hasMore, string? lastId) + => GetNextPageToken(ThreadId, Limit, Order, lastId, Before, hasMore); + + // Convenience - continuation page request + public static RunCollectionPageToken FromToken(ContinuationToken pageToken) + { + if (pageToken is RunCollectionPageToken token) + { + return token; + } + + BinaryData data = pageToken.ToBytes(); + + if (data.ToMemory().Length == 0) + { + return new(string.Empty, default, default, default, default); + } + + Utf8JsonReader reader = new(data); + + string threadId = null!; + int? limit = null; + string? order = null; + string? after = null; + string? before = null; + + reader.Read(); + Debug.Assert(reader.TokenType == JsonTokenType.StartObject); + + while (reader.Read()) + { + if (reader.TokenType == JsonTokenType.EndObject) + { + break; + } + + Debug.Assert(reader.TokenType == JsonTokenType.PropertyName); + string propertyName = reader.GetString()!; + + switch (propertyName) + { + case "threadId": + reader.Read(); + Debug.Assert(reader.TokenType == JsonTokenType.String); + threadId = reader.GetString()!; + break; + case "limit": + reader.Read(); + Debug.Assert(reader.TokenType == JsonTokenType.Number); + limit = reader.GetInt32(); + break; + case "order": + reader.Read(); + Debug.Assert(reader.TokenType == JsonTokenType.String); + order = reader.GetString(); + break; + case "after": + reader.Read(); + Debug.Assert(reader.TokenType == JsonTokenType.String); + after = reader.GetString(); + break; + case "before": + reader.Read(); + Debug.Assert(reader.TokenType == JsonTokenType.String); + before = reader.GetString(); + break; + default: + throw new JsonException($"Unrecognized property '{propertyName}'."); + } + } + + if (threadId is null) + { + throw new ArgumentException("Failed to create MessageCollectionPageToken from provided pageToken.", nameof(pageToken)); + } + + return new(threadId, limit, order, after, before); + } + + // Protocol + public static RunCollectionPageToken FromOptions(string threadId, int? limit, string? order, string? after, string? before) + => new RunCollectionPageToken(threadId, limit, order, after, before); + + private static RunCollectionPageToken? GetNextPageToken(string threadId, int? limit, string? order, string? after, string? before, bool hasMore) + { + if (!hasMore || after is null) + { + return null; + } + + return new RunCollectionPageToken(threadId, limit, order, after, before); + } +} \ No newline at end of file diff --git a/src/Custom/Assistants/RunStepCollectionOptions.cs b/src/Custom/Assistants/RunStepCollectionOptions.cs new file mode 100644 index 000000000..aeb3d9813 --- /dev/null +++ b/src/Custom/Assistants/RunStepCollectionOptions.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace OpenAI.Assistants; + +public class RunStepCollectionOptions +{ + public RunStepCollectionOptions() { } + + /// + /// The order that results should appear in the list according to + /// their created_at timestamp. + /// + public ListOrder? Order { get; init; } + + /// + /// The number of values to return in a page result. + /// + public int? PageSize { get; init; } + + /// + /// The id of the item preceeding the first item in the collection. + /// + public string AfterId { get; init; } + + /// + /// The id of the item following the last item in the collection. + /// + public string BeforeId { get; init; } +} diff --git a/src/Custom/Assistants/RunStepCollectionPageToken.cs b/src/Custom/Assistants/RunStepCollectionPageToken.cs new file mode 100644 index 000000000..97aa424dc --- /dev/null +++ b/src/Custom/Assistants/RunStepCollectionPageToken.cs @@ -0,0 +1,158 @@ +using System; +using System.ClientModel; +using System.Diagnostics; +using System.IO; +using System.Text.Json; + +#nullable enable + +namespace OpenAI.Assistants; + +internal class RunStepCollectionPageToken : OpenAIPageToken +{ + public RunStepCollectionPageToken(string threadId, string runId, int? limit, string? order, string? after, string? before) + : base(limit, order, after, before) + { + ThreadId = threadId; + RunId = runId; + } + + public string ThreadId { get; } + public string RunId { get; } + + public override BinaryData ToBytes() + { + using MemoryStream stream = new(); + using Utf8JsonWriter writer = new(stream); + + writer.WriteStartObject(); + writer.WriteString("threadId", ThreadId); + writer.WriteString("runId", ThreadId); + + if (Limit.HasValue) + { + writer.WriteNumber("limit", Limit.Value); + } + + if (Order is not null) + { + writer.WriteString("order", Order); + } + + if (After is not null) + { + writer.WriteString("after", After); + } + + if (Before is not null) + { + writer.WriteString("before", Before); + } + + writer.WriteEndObject(); + + writer.Flush(); + stream.Position = 0; + + return BinaryData.FromStream(stream); + } + + public override OpenAIPageToken? GetNextPageToken(bool hasMore, string? lastId) + => GetNextPageToken(ThreadId, RunId, Limit, Order, lastId, Before, hasMore); + + // Convenience - continuation page request + public static RunStepCollectionPageToken FromToken(ContinuationToken pageToken) + { + if (pageToken is RunStepCollectionPageToken token) + { + return token; + } + + BinaryData data = pageToken.ToBytes(); + + if (data.ToMemory().Length == 0) + { + throw new ArgumentException("Failed to create MessageCollectionPageToken from provided pageToken.", nameof(pageToken)); + } + + Utf8JsonReader reader = new(data); + + string threadId = null!; + string runId = null!; + int? limit = null; + string? order = null; + string? after = null; + string? before = null; + + reader.Read(); + Debug.Assert(reader.TokenType == JsonTokenType.StartObject); + + while (reader.Read()) + { + if (reader.TokenType == JsonTokenType.EndObject) + { + break; + } + + Debug.Assert(reader.TokenType == JsonTokenType.PropertyName); + string propertyName = reader.GetString()!; + + switch (propertyName) + { + case "threadId": + reader.Read(); + Debug.Assert(reader.TokenType == JsonTokenType.String); + threadId = reader.GetString()!; + break; + case "runId": + reader.Read(); + Debug.Assert(reader.TokenType == JsonTokenType.String); + threadId = reader.GetString()!; + break; + case "limit": + reader.Read(); + Debug.Assert(reader.TokenType == JsonTokenType.Number); + limit = reader.GetInt32(); + break; + case "order": + reader.Read(); + Debug.Assert(reader.TokenType == JsonTokenType.String); + order = reader.GetString(); + break; + case "after": + reader.Read(); + Debug.Assert(reader.TokenType == JsonTokenType.String); + after = reader.GetString(); + break; + case "before": + reader.Read(); + Debug.Assert(reader.TokenType == JsonTokenType.String); + before = reader.GetString(); + break; + default: + throw new JsonException($"Unrecognized property '{propertyName}'."); + } + } + + if (threadId is null || runId is null) + { + throw new ArgumentException("Failed to create MessageCollectionPageToken from provided pageToken.", nameof(pageToken)); + } + + return new(threadId, runId, limit, order, after, before); + } + + // Protocol + public static RunStepCollectionPageToken FromOptions(string threadId, string runId, int? limit, string? order, string? after, string? before) + => new RunStepCollectionPageToken(threadId, runId, limit, order, after, before); + + private static RunStepCollectionPageToken? GetNextPageToken(string threadId, string runId, int? limit, string? order, string? after, string? before, bool hasMore) + { + if (!hasMore || after is null) + { + return null; + } + + return new RunStepCollectionPageToken(threadId, runId, limit, order, after, before); + } +} \ No newline at end of file diff --git a/src/Custom/Common/OpenAIPageCollectionHelpers.cs b/src/Custom/Common/OpenAIPageCollectionHelpers.cs index 2aa3dcff2..b828a6804 100644 --- a/src/Custom/Common/OpenAIPageCollectionHelpers.cs +++ b/src/Custom/Common/OpenAIPageCollectionHelpers.cs @@ -12,12 +12,12 @@ namespace OpenAI; internal class OpenAIPageCollectionHelpers { - public delegate Task GetPageValuesAsync(int? limit, string? order, string? after, string? before, RequestOptions? options); - public delegate ClientResult GetPageValues(int? limit, string? order, string? after, string? before, RequestOptions? options); + public delegate Task GetPageResultAsync(OpenAIPageToken pageToken, RequestOptions? options); + public delegate ClientResult GetPageResult(OpenAIPageToken pageToken, RequestOptions? options); public static AsyncPageCollection CreateAsync( ContinuationToken firstPageToken, - GetPageValuesAsync getPageValuesAsync, + GetPageResultAsync getPageResultAsync, Func getToken, RequestOptions? options) where TValue : notnull @@ -27,11 +27,8 @@ async Task> getPageAsync(ContinuationToken pageToken) { OpenAIPageToken token = getToken(pageToken); - ClientResult result = await getPageValuesAsync( - limit: token.Limit, - order: token.Order, - after: token.After, - before: token.Before, + ClientResult result = await getPageResultAsync( + token, options).ConfigureAwait(false); PipelineResponse response = result.GetRawResponse(); @@ -46,7 +43,7 @@ async Task> getPageAsync(ContinuationToken pageToken) public static PageCollection Create( ContinuationToken firstPageToken, - GetPageValues getPageValues, + GetPageResult getPageResult, Func getToken, RequestOptions? options) where TValue : notnull @@ -56,11 +53,8 @@ PageResult getPage(ContinuationToken pageToken) { OpenAIPageToken token = getToken(pageToken); - ClientResult result = getPageValues( - limit: token.Limit, - order: token.Order, - after: token.After, - before: token.Before, + ClientResult result = getPageResult( + token, options); PipelineResponse response = result.GetRawResponse(); @@ -75,14 +69,14 @@ PageResult getPage(ContinuationToken pageToken) public static IAsyncEnumerable CreateProtocolAsync( ContinuationToken firstPageToken, - GetPageValuesAsync getPageValuesAsync, + GetPageResultAsync getPageResultAsync, Func getToken, RequestOptions? options) { async Task getPageAsync(ContinuationToken pageToken) { OpenAIPageToken token = getToken(pageToken); - return await getPageValuesAsync(token.Limit, token.Order, token.After, token.Before, options).ConfigureAwait(false); + return await getPageResultAsync(token, options).ConfigureAwait(false); } ContinuationToken? getNextPageToken(ContinuationToken pageToken, ClientResult result) @@ -102,14 +96,14 @@ async Task getPageAsync(ContinuationToken pageToken) public static IEnumerable CreateProtocol( ContinuationToken firstPageToken, - GetPageValues getPageValues, + GetPageResult getPageResult, Func getToken, RequestOptions? options) { ClientResult getPage(ContinuationToken pageToken) { OpenAIPageToken token = (OpenAIPageToken)pageToken; - return getPageValues(token.Limit, token.Order, token.After, token.Before, options); + return getPageResult(token, options); } ContinuationToken? getNextPageToken(ContinuationToken pageToken, ClientResult result) diff --git a/tests/Assistants/AssistantTests.cs b/tests/Assistants/AssistantTests.cs index 7c647b77b..9904314d5 100644 --- a/tests/Assistants/AssistantTests.cs +++ b/tests/Assistants/AssistantTests.cs @@ -634,7 +634,7 @@ public async Task CanEnumerateAssistants() // Page through collection int count = 0; - IAsyncEnumerable assistants = client.GetAssistantsAsync(ListOrder.NewestFirst).GetAllValuesAsync(); + IAsyncEnumerable assistants = client.GetAssistantsAsync(new AssistantCollectionOptions() { Order = ListOrder.NewestFirst }).GetAllValuesAsync(); int lastIdSeen = int.MaxValue; @@ -676,8 +676,13 @@ public async Task CanPageThroughAssistantCollection() // Page through collection int count = 0; int pageCount = 0; - AsyncPageCollection pages = client.GetAssistantsAsync(ListOrder.NewestFirst, pageSize: 2); - + AsyncPageCollection pages = client.GetAssistantsAsync( + new AssistantCollectionOptions() + { + Order = ListOrder.NewestFirst, + PageSize = 2 + }); + int lastIdSeen = int.MaxValue; await foreach (PageResult page in pages) @@ -720,11 +725,17 @@ public async Task CanRehydratePageCollectionFromBytes() Validate(assistant); Assert.That(assistant.Name, Is.EqualTo($"Test Assistant {i}")); } - - AsyncPageCollection pages = client.GetAssistantsAsync(ListOrder.NewestFirst, pageSize: 2); + + AsyncPageCollection pages = client.GetAssistantsAsync( + new AssistantCollectionOptions() + { + Order = ListOrder.NewestFirst, + PageSize = 2 + }); // Simulate rehydration of the collection - BinaryData rehydrationBytes = pages.FirstPageToken.ToBytes(); + // TODO: too complicated? + BinaryData rehydrationBytes = (await pages.GetCurrentPageAsync().ConfigureAwait(false)).PageToken.ToBytes(); ContinuationToken rehydrationToken = ContinuationToken.FromBytes(rehydrationBytes); AsyncPageCollection rehydratedPages = client.GetAssistantsAsync(rehydrationToken); @@ -774,10 +785,16 @@ public async Task CanRehydratePageCollectionFromPageToken() Assert.That(assistant.Name, Is.EqualTo($"Test Assistant {i}")); } - AsyncPageCollection pages = client.GetAssistantsAsync(ListOrder.NewestFirst, pageSize: 2); + AsyncPageCollection pages = client.GetAssistantsAsync( + new AssistantCollectionOptions() + { + Order = ListOrder.NewestFirst, + PageSize = 2 + }); // Call the rehydration method, passing a typed OpenAIPageToken - AsyncPageCollection rehydratedPages = client.GetAssistantsAsync(pages.FirstPageToken); + PageResult firstPage = await pages.GetCurrentPageAsync().ConfigureAwait(false); + AsyncPageCollection rehydratedPages = client.GetAssistantsAsync(firstPage.PageToken); int count = 0; int pageCount = 0; From 4a9d6afbb52730582401efca296d60a9732b7e3d Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Mon, 1 Jul 2024 11:48:53 -0700 Subject: [PATCH 31/72] add convenience implementations of Assistant-related paged methods --- examples/Assistants/Example04_AllTheTools.cs | 4 +- .../Assistants/AssistantClient.Convenience.cs | 32 ++-- src/Custom/Assistants/AssistantClient.cs | 140 ++++++++++++------ .../Assistants/RunCollectionPageToken.cs | 4 + .../Assistants/RunStepCollectionPageToken.cs | 4 + tests/Assistants/AssistantTests.cs | 10 +- 6 files changed, 123 insertions(+), 71 deletions(-) diff --git a/examples/Assistants/Example04_AllTheTools.cs b/examples/Assistants/Example04_AllTheTools.cs index a13427e1e..94b801f95 100644 --- a/examples/Assistants/Example04_AllTheTools.cs +++ b/examples/Assistants/Example04_AllTheTools.cs @@ -138,7 +138,7 @@ static string GetNameOfFamilyMember(string relation) if (run.Status == RunStatus.Completed) { PageCollection messagePages - = client.GetMessages(run.ThreadId, new MessageCollectionOptions() { Order = ListOrder.OldestFirst }); + = client.GetMessages(run.ThreadId, new MessageCollectionOptions() { Order = ListOrder.OldestFirst }); IEnumerable messages = messagePages.GetAllValues(); foreach (ThreadMessage message in messages) @@ -172,7 +172,7 @@ PageCollection messagePages #endregion #region List run steps for details about tool calls - PageCollection runSteps = client.GetRunSteps(run, resultOrder: ListOrder.OldestFirst); + PageCollection runSteps = client.GetRunSteps(run, new() { Order = ListOrder.OldestFirst }); foreach (RunStep step in runSteps.GetAllValues()) { Console.WriteLine($"Run step: {step.Status}"); diff --git a/src/Custom/Assistants/AssistantClient.Convenience.cs b/src/Custom/Assistants/AssistantClient.Convenience.cs index 5ff10ca49..67a382471 100644 --- a/src/Custom/Assistants/AssistantClient.Convenience.cs +++ b/src/Custom/Assistants/AssistantClient.Convenience.cs @@ -28,7 +28,6 @@ public virtual Task> ModifyAssistantAsync(Assistant assi public virtual ClientResult ModifyAssistant(Assistant assistant, AssistantModificationOptions options) => ModifyAssistant(assistant?.Id, options); - /// /// Deletes an existing . /// @@ -130,7 +129,7 @@ public virtual ClientResult CreateMessage( /// /// The thread to list messages from. /// Options describing the collection to return. - /// A collection of messages that can be enumerated using await foreach. + /// public virtual AsyncPageCollection GetMessagesAsync( AssistantThread thread, MessageCollectionOptions options = default) @@ -145,7 +144,7 @@ public virtual AsyncPageCollection GetMessagesAsync( /// /// The thread to list messages from. /// Options describing the collection to return. - /// A collection of messages that can be enumerated using foreach. + /// public virtual PageCollection GetMessages( AssistantThread thread, MessageCollectionOptions options = default) @@ -308,7 +307,7 @@ public virtual CollectionResult CreateThreadAndRunStreaming( /// /// The thread that runs in the list should be associated with. /// Options describing the collection to return. - /// A collection of runs that can be enumerated using await foreach. + /// public virtual AsyncPageCollection GetRunsAsync( AssistantThread thread, RunCollectionOptions options = default) @@ -323,7 +322,7 @@ public virtual AsyncPageCollection GetRunsAsync( /// /// The thread that runs in the list should be associated with. /// Options describing the collection to return. - /// A collection of runs that can be enumerated using foreach. + /// public virtual PageCollection GetRuns( AssistantThread thread, RunCollectionOptions options = default) @@ -333,7 +332,6 @@ public virtual PageCollection GetRuns( return GetRuns(thread.Id, options); } - /// /// Gets a refreshed instance of an existing . /// @@ -420,35 +418,29 @@ public virtual ClientResult CancelRun(ThreadRun run) /// Gets a collection of instances associated with a . /// /// The run to list run steps from. - /// - /// The order that results should appear in the list according to their created_at - /// timestamp. - /// - /// A collection of run steps that can be enumerated using await foreach. + /// Options describing the collection to return. + /// public virtual PageCollection GetRunSteps( ThreadRun run, - ListOrder? resultOrder = default) + RunStepCollectionOptions options = default) { Argument.AssertNotNull(run, nameof(run)); - return GetRunSteps(run.ThreadId, run.Id, resultOrder); + return GetRunSteps(run.ThreadId, run.Id, options); } /// /// Gets a collection of instances associated with a . /// /// The run to list run steps from. - /// - /// The order that results should appear in the list according to their created_at - /// timestamp. - /// - /// A collection of run steps that can be enumerated using foreach. + /// Options describing the collection to return. + /// public virtual AsyncPageCollection GetRunStepsAsync( ThreadRun run, - ListOrder? resultOrder = default) + RunStepCollectionOptions options = default) { Argument.AssertNotNull(run, nameof(run)); - return GetRunStepsAsync(run.ThreadId, run.Id, resultOrder); + return GetRunStepsAsync(run.ThreadId, run.Id, options); } } diff --git a/src/Custom/Assistants/AssistantClient.cs b/src/Custom/Assistants/AssistantClient.cs index 351f7df94..39fc60d24 100644 --- a/src/Custom/Assistants/AssistantClient.cs +++ b/src/Custom/Assistants/AssistantClient.cs @@ -106,7 +106,7 @@ public virtual ClientResult CreateAssistant(string model, AssistantCr /// /// Options describing the collection to return. /// A token that can be used to cancel this method call. - /// A collection of assistants that can be enumerated using await foreach. + /// public virtual AsyncPageCollection GetAssistantsAsync( AssistantCollectionOptions options = default, CancellationToken cancellationToken = default) @@ -124,7 +124,7 @@ public virtual AsyncPageCollection GetAssistantsAsync( /// /// Serialized page token indicating the first page of the collection to rehydrate. /// A token that can be used to cancel this method call. - /// A collection of assistants that can be enumerated using await foreach. + /// public virtual AsyncPageCollection GetAssistantsAsync( ContinuationToken firstPageToken, CancellationToken cancellationToken = default) @@ -142,7 +142,7 @@ public virtual AsyncPageCollection GetAssistantsAsync( /// /// Options describing the collection to return. /// A token that can be used to cancel this method call. - /// A collection of assistants that can be enumerated using foreach. + /// public virtual PageCollection GetAssistants( AssistantCollectionOptions options = default, CancellationToken cancellationToken = default) @@ -160,9 +160,9 @@ public virtual PageCollection GetAssistants( /// /// Serialized page token indicating the first page of the collection to rehydrate. /// A token that can be used to cancel this method call. - /// A collection of assistants that can be enumerated using foreach. + /// public virtual PageCollection GetAssistants( - ContinuationToken firstPageToken, + ContinuationToken firstPageToken, CancellationToken cancellationToken = default) { AssistantCollectionPageToken pageToken = AssistantCollectionPageToken.FromToken(firstPageToken); @@ -382,18 +382,32 @@ public virtual ClientResult CreateMessage( /// The ID of the thread to list messages from. /// Options describing the collection to return. /// A token that can be used to cancel this method call. - /// A collection of messages that can be enumerated using await foreach. + /// public virtual AsyncPageCollection GetMessagesAsync( string threadId, - MessageCollectionOptions options = default, CancellationToken cancellationToken = default) { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); - throw new NotImplementedException(); - //return CreateAsyncPageable((continuationToken, pageSize) - // => GetMessagesAsync(threadId, pageSize, resultOrder?.ToString(), continuationToken, null, cancellationToken.ToRequestOptions())); + MessageCollectionPageToken firstPageToken = MessageCollectionPageToken.FromOptions(threadId, options); + return OpenAIPageCollectionHelpers.CreateAsync( + firstPageToken, + GetMessagesPageAsync, + MessageCollectionPageToken.FromToken, + cancellationToken.ToRequestOptions()); + } + + public virtual AsyncPageCollection GetMessagesAsync( + ContinuationToken firstPageToken, + CancellationToken cancellationToken = default) + { + MessageCollectionPageToken pageToken = MessageCollectionPageToken.FromToken(firstPageToken); + return OpenAIPageCollectionHelpers.CreateAsync( + firstPageToken, + GetMessagesPageAsync, + MessageCollectionPageToken.FromToken, + cancellationToken.ToRequestOptions()); } /// @@ -402,17 +416,32 @@ public virtual AsyncPageCollection GetMessagesAsync( /// The ID of the thread to list messages from. /// Options describing the collection to return. /// A token that can be used to cancel this method call. - /// A collection of messages that can be enumerated using foreach. + /// public virtual PageCollection GetMessages( string threadId, - MessageCollectionOptions options = default, + MessageCollectionOptions options = default, CancellationToken cancellationToken = default) { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); - throw new NotImplementedException(); - //return CreatePageable((continuationToken, pageSize) - // => GetMessages(threadId, pageSize, resultOrder?.ToString(), continuationToken, null, cancellationToken.ToRequestOptions())); + MessageCollectionPageToken firstPageToken = MessageCollectionPageToken.FromOptions(threadId, options); + return OpenAIPageCollectionHelpers.Create( + firstPageToken, + GetMessagesPage, + MessageCollectionPageToken.FromToken, + cancellationToken.ToRequestOptions()); + } + + public virtual PageCollection GetMessages( + ContinuationToken firstPageToken, + CancellationToken cancellationToken = default) + { + MessageCollectionPageToken pageToken = MessageCollectionPageToken.FromToken(firstPageToken); + return OpenAIPageCollectionHelpers.Create( + firstPageToken, + GetMessagesPage, + MessageCollectionPageToken.FromToken, + cancellationToken.ToRequestOptions()); } /// @@ -713,7 +742,7 @@ public virtual CollectionResult CreateThreadAndRunStreaming( /// The ID of the thread that runs in the list should be associated with. /// Options describing the collection to return. /// A token that can be used to cancel this method call. - /// A collection of runs that can be enumerated using await foreach. + /// public virtual AsyncPageCollection GetRunsAsync( string threadId, RunCollectionOptions options = default, @@ -721,9 +750,24 @@ public virtual AsyncPageCollection GetRunsAsync( { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); - throw new NotImplementedException(); - //return CreateAsyncPageable((continuationToken, pageSize) - // => GetRunsAsync(threadId, pageSize, resultOrder?.ToString(), continuationToken, null, cancellationToken.ToRequestOptions())); + RunCollectionPageToken firstPageToken = RunCollectionPageToken.FromOptions(threadId, options); + return OpenAIPageCollectionHelpers.CreateAsync( + firstPageToken, + GetRunsPageAsync, + RunCollectionPageToken.FromToken, + cancellationToken.ToRequestOptions()); + } + + public virtual AsyncPageCollection GetRunsAsync( + ContinuationToken firstPageToken, + CancellationToken cancellationToken = default) + { + RunCollectionPageToken pageToken = RunCollectionPageToken.FromToken(firstPageToken); + return OpenAIPageCollectionHelpers.CreateAsync( + firstPageToken, + GetRunsPageAsync, + RunCollectionPageToken.FromToken, + cancellationToken.ToRequestOptions()); } /// @@ -732,7 +776,7 @@ public virtual AsyncPageCollection GetRunsAsync( /// The ID of the thread that runs in the list should be associated with. /// Options describing the collection to return. /// A token that can be used to cancel this method call. - /// A collection of runs that can be enumerated using foreach. + /// public virtual PageCollection GetRuns( string threadId, RunCollectionOptions options = default, @@ -745,6 +789,18 @@ public virtual PageCollection GetRuns( // => GetRuns(threadId, pageSize, resultOrder?.ToString(), continuationToken, null, cancellationToken.ToRequestOptions())); } + public virtual PageCollection GetRuns( + ContinuationToken firstPageToken, + CancellationToken cancellationToken = default) + { + RunCollectionPageToken pageToken = RunCollectionPageToken.FromToken(firstPageToken); + return OpenAIPageCollectionHelpers.Create( + firstPageToken, + GetRunsPage, + RunCollectionPageToken.FromToken, + cancellationToken.ToRequestOptions()); + } + /// /// Gets an existing from a known . /// @@ -917,26 +973,24 @@ public virtual ClientResult CancelRun(string threadId, string runId, /// /// The ID of the thread associated with the run. /// The ID of the run to list run steps from. - /// - /// The order that results should appear in the list according to their created_at - /// timestamp. - /// - /// The number of values to return in a single page in the page collection. - /// The id of the item preceeding the first item in the collection. - /// The id of the item following the last item in the collection. + /// /// A token that can be used to cancel this method call. - /// A collection of run steps that can be enumerated using await foreach. + /// public virtual AsyncPageCollection GetRunStepsAsync( string threadId, string runId, -ListOrder? order = null, int? pageSize = null, string afterId = default, string beforeId = default, CancellationToken cancellationToken = default) + RunStepCollectionOptions options = default, + CancellationToken cancellationToken = default) { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); Argument.AssertNotNullOrEmpty(runId, nameof(runId)); - throw new NotImplementedException(); - //return CreateAsyncPageable((continuationToken, pageSize) - // => GetRunStepsAsync(threadId, runId, pageSize, resultOrder?.ToString(), continuationToken, null, cancellationToken.ToRequestOptions())); + RunStepCollectionPageToken firstPageToken = RunStepCollectionPageToken.FromOptions(threadId, runId, options); + return OpenAIPageCollectionHelpers.CreateAsync( + firstPageToken, + GetRunStepsPageAsync, + RunStepCollectionPageToken.FromToken, + cancellationToken.ToRequestOptions()); } /// @@ -944,26 +998,24 @@ public virtual AsyncPageCollection GetRunStepsAsync( /// /// The ID of the thread associated with the run. /// The ID of the run to list run steps from. - /// - /// The order that results should appear in the list according to their created_at - /// timestamp. - /// - /// The number of values to return in a single page in the page collection. - /// The id of the item preceeding the first item in the collection. - /// The id of the item following the last item in the collection. + /// /// A token that can be used to cancel this method call. - /// A collection of run steps that can be enumerated using foreach. + /// public virtual PageCollection GetRunSteps( string threadId, string runId, -ListOrder? order = null, int? pageSize = null, string afterId = default, string beforeId = default, CancellationToken cancellationToken = default) + RunStepCollectionOptions options = default, + CancellationToken cancellationToken = default) { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); Argument.AssertNotNullOrEmpty(runId, nameof(runId)); - throw new NotImplementedException(); - //return CreatePageable((continuationToken, pageSize) - // => GetRunSteps(threadId, runId, pageSize, resultOrder?.ToString(), continuationToken, null, cancellationToken.ToRequestOptions())); + RunStepCollectionPageToken firstPageToken = RunStepCollectionPageToken.FromOptions(threadId, runId, options); + return OpenAIPageCollectionHelpers.Create( + firstPageToken, + GetRunStepsPage, + RunStepCollectionPageToken.FromToken, + cancellationToken.ToRequestOptions()); } /// diff --git a/src/Custom/Assistants/RunCollectionPageToken.cs b/src/Custom/Assistants/RunCollectionPageToken.cs index 094ceb0ae..f31ccc544 100644 --- a/src/Custom/Assistants/RunCollectionPageToken.cs +++ b/src/Custom/Assistants/RunCollectionPageToken.cs @@ -57,6 +57,10 @@ public override BinaryData ToBytes() public override OpenAIPageToken? GetNextPageToken(bool hasMore, string? lastId) => GetNextPageToken(ThreadId, Limit, Order, lastId, Before, hasMore); + // Convenience - first page request + public static RunCollectionPageToken FromOptions(string threadId, RunCollectionOptions options) + => new(threadId, options?.PageSize, options?.Order?.ToString(), options?.AfterId, options?.BeforeId); + // Convenience - continuation page request public static RunCollectionPageToken FromToken(ContinuationToken pageToken) { diff --git a/src/Custom/Assistants/RunStepCollectionPageToken.cs b/src/Custom/Assistants/RunStepCollectionPageToken.cs index 97aa424dc..008eb9f8e 100644 --- a/src/Custom/Assistants/RunStepCollectionPageToken.cs +++ b/src/Custom/Assistants/RunStepCollectionPageToken.cs @@ -60,6 +60,10 @@ public override BinaryData ToBytes() public override OpenAIPageToken? GetNextPageToken(bool hasMore, string? lastId) => GetNextPageToken(ThreadId, RunId, Limit, Order, lastId, Before, hasMore); + // Convenience - first page request + public static RunStepCollectionPageToken FromOptions(string threadId, string runId,RunStepCollectionOptions options) + => new(threadId, runId, options?.PageSize, options?.Order?.ToString(), options?.AfterId, options?.BeforeId); + // Convenience - continuation page request public static RunStepCollectionPageToken FromToken(ContinuationToken pageToken) { diff --git a/tests/Assistants/AssistantTests.cs b/tests/Assistants/AssistantTests.cs index 9904314d5..580edb76c 100644 --- a/tests/Assistants/AssistantTests.cs +++ b/tests/Assistants/AssistantTests.cs @@ -180,7 +180,7 @@ public void BasicRunOperationsWork() Validate(assistant); AssistantThread thread = client.CreateThread(); Validate(thread); - PageResult runsPage = client.GetRunsPage(thread); + PageResult runsPage = client.GetRuns(thread).GetCurrentPage(); Assert.That(runsPage.Values.Count, Is.EqualTo(0)); ThreadMessage message = client.CreateMessage(thread.Id, MessageRole.User, ["Hello, assistant!"]); Validate(message); @@ -190,11 +190,11 @@ public void BasicRunOperationsWork() Assert.That(run.CreatedAt, Is.GreaterThan(s_2024)); ThreadRun retrievedRun = client.GetRun(thread.Id, run.Id); Assert.That(retrievedRun.Id, Is.EqualTo(run.Id)); - runsPage = client.GetRunsPage(thread); + runsPage = client.GetRuns(thread).GetCurrentPage(); Assert.That(runsPage.Values.Count, Is.EqualTo(1)); Assert.That(runsPage.Values[0].Id, Is.EqualTo(run.Id)); - PageResult messagesPage = client.GetMessagesPage(thread); + PageResult messagesPage = client.GetMessages(thread).GetCurrentPage(); Assert.That(messagesPage.Values.Count, Is.GreaterThanOrEqualTo(1)); for (int i = 0; i < 10 && !run.Status.IsTerminal; i++) { @@ -208,7 +208,7 @@ public void BasicRunOperationsWork() Assert.That(run.FailedAt, Is.Null); Assert.That(run.IncompleteDetails, Is.Null); - messagesPage = client.GetMessagesPage(thread); + messagesPage = client.GetMessages(thread).GetCurrentPage(); Assert.That(messagesPage.Values.Count, Is.EqualTo(2)); Assert.That(messagesPage.Values[0].Role, Is.EqualTo(MessageRole.Assistant)); @@ -391,7 +391,7 @@ public void FunctionToolsWork() } Assert.That(run.Status, Is.EqualTo(RunStatus.Completed)); - CollectionResult messages = client.GetMessages(run.ThreadId, new MessageCollectionOptions() { Order = ListOrder.NewestFirst }).GetAllValues(); + IEnumerable messages = client.GetMessages(run.ThreadId, new MessageCollectionOptions() { Order = ListOrder.NewestFirst }).GetAllValues(); Assert.That(messages.Count, Is.GreaterThan(1)); Assert.That(messages.First().Role, Is.EqualTo(MessageRole.Assistant)); Assert.That(messages.First().Content?[0], Is.Not.Null); From f91969f8259a1e3929a49c03e4d595fbbd9237c1 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Mon, 1 Jul 2024 12:05:19 -0700 Subject: [PATCH 32/72] move to CurrentPageToken instead of FirstPageToken --- .../Common/OpenAIPageCollectionHelpers.cs | 8 +--- src/Utility/PageCollectionHelpers.cs | 41 +++++++++++++------ 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/src/Custom/Common/OpenAIPageCollectionHelpers.cs b/src/Custom/Common/OpenAIPageCollectionHelpers.cs index b828a6804..b846e3f4c 100644 --- a/src/Custom/Common/OpenAIPageCollectionHelpers.cs +++ b/src/Custom/Common/OpenAIPageCollectionHelpers.cs @@ -27,9 +27,7 @@ async Task> getPageAsync(ContinuationToken pageToken) { OpenAIPageToken token = getToken(pageToken); - ClientResult result = await getPageResultAsync( - token, - options).ConfigureAwait(false); + ClientResult result = await getPageResultAsync(token, options).ConfigureAwait(false); PipelineResponse response = result.GetRawResponse(); IInternalListResponse list = ModelReaderWriter.Read(response.Content)!; @@ -53,9 +51,7 @@ PageResult getPage(ContinuationToken pageToken) { OpenAIPageToken token = getToken(pageToken); - ClientResult result = getPageResult( - token, - options); + ClientResult result = getPageResult(token, options); PipelineResponse response = result.GetRawResponse(); IInternalListResponse list = ModelReaderWriter.Read(response.Content)!; diff --git a/src/Utility/PageCollectionHelpers.cs b/src/Utility/PageCollectionHelpers.cs index c789ca891..8c39229fd 100644 --- a/src/Utility/PageCollectionHelpers.cs +++ b/src/Utility/PageCollectionHelpers.cs @@ -11,15 +11,18 @@ namespace OpenAI.Utility; internal class PageCollectionHelpers { - public static AsyncPageCollection CreateAsync(ContinuationToken firstPageToken, + public static AsyncPageCollection CreateAsync( + ContinuationToken firstPageToken, Func>> getPageAsync) where T : notnull => new AsyncFuncPageCollection(firstPageToken, getPageAsync); - public static PageCollection Create(ContinuationToken firstPageToken, + public static PageCollection Create( + ContinuationToken firstPageToken, Func> getPage) where T : notnull => new FuncPageCollection(firstPageToken, getPage); - public static IAsyncEnumerable CreatePrototolAsync(ContinuationToken firstPageToken, + public static IAsyncEnumerable CreatePrototolAsync( + ContinuationToken firstPageToken, Func> getPageAsync, Func getNextPageToken) => new AsyncFuncResultEnumerable(firstPageToken, getPageAsync, getNextPageToken); @@ -31,17 +34,23 @@ public static IEnumerable CreatePrototol(ContinuationToken firstPa private class AsyncFuncPageCollection : AsyncPageCollection where T : notnull { - private readonly ContinuationToken _firstPageToken; - private readonly Func>> _getPageAsync; + private readonly Func>> _getPageAsync; + + private ContinuationToken _currentPageToken; - public AsyncFuncPageCollection(ContinuationToken firstPageToken, + public AsyncFuncPageCollection( + ContinuationToken firstPageToken, Func>> getPageAsync) { - _firstPageToken = firstPageToken; + _currentPageToken = firstPageToken; _getPageAsync = getPageAsync; } - protected override ContinuationToken FirstPageToken => _firstPageToken; + protected override ContinuationToken CurrentPageToken + { + get => _currentPageToken; + set => _currentPageToken = value; + } public override async Task> GetPageAsyncCore(ContinuationToken pageToken) => await _getPageAsync(pageToken).ConfigureAwait(false); @@ -49,17 +58,23 @@ public override async Task> GetPageAsyncCore(ContinuationToken pag private class FuncPageCollection : PageCollection where T : notnull { - private readonly ContinuationToken _firstPageToken; - private readonly Func> _getPage; + private readonly Func> _getPage; + + private ContinuationToken _currentPageToken; - public FuncPageCollection(ContinuationToken firstPageToken, + public FuncPageCollection( + ContinuationToken firstPageToken, Func> getPage) { - _firstPageToken = firstPageToken; + _currentPageToken = firstPageToken; _getPage = getPage; } - protected override ContinuationToken FirstPageToken => _firstPageToken; + protected override ContinuationToken CurrentPageToken + { + get => _currentPageToken; + set => _currentPageToken = value; + } protected override PageResult GetPageCore(ContinuationToken pageToken) => _getPage(pageToken); From 90eed1136ea4cec31c395afe59d6e717521857a7 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Mon, 1 Jul 2024 14:58:54 -0700 Subject: [PATCH 33/72] starting idea around client as enumerator; backing up --- .../Assistants/AssistantClient.Protocol.cs | 16 +- .../Common/OpenAIPageCollectionHelpers.cs | 238 +++++++++--------- .../Internal/PageCollectionHelpers.cs | 171 +++++++++++++ .../Internal/PageEnumerator.cs | 29 +++ .../Internal/PageResultEnumerator.cs | 42 ++++ .../MessageCollectionClient.cs | 56 +++++ src/Utility/PageCollectionHelpers.cs | 142 ----------- 7 files changed, 420 insertions(+), 274 deletions(-) create mode 100644 src/To.Be.Generated/Internal/PageCollectionHelpers.cs create mode 100644 src/To.Be.Generated/Internal/PageEnumerator.cs create mode 100644 src/To.Be.Generated/Internal/PageResultEnumerator.cs create mode 100644 src/To.Be.Generated/MessageCollectionClient.cs delete mode 100644 src/Utility/PageCollectionHelpers.cs diff --git a/src/Custom/Assistants/AssistantClient.Protocol.cs b/src/Custom/Assistants/AssistantClient.Protocol.cs index fa591a2bf..b938208d2 100644 --- a/src/Custom/Assistants/AssistantClient.Protocol.cs +++ b/src/Custom/Assistants/AssistantClient.Protocol.cs @@ -1,8 +1,8 @@ +using OpenAI.Utility; using System; using System.ClientModel; using System.ClientModel.Primitives; using System.Collections.Generic; -using System.Threading; using System.Threading.Tasks; namespace OpenAI.Assistants; @@ -257,20 +257,10 @@ internal virtual async Task GetMessagesPageAsync(string threadId, public virtual IEnumerable GetMessages(string threadId, int? limit, string order, string after, string before, RequestOptions options) { - MessageCollectionPageToken firstPageToken = MessageCollectionPageToken.FromOptions(threadId, limit, order, after, before); - return OpenAIPageCollectionHelpers.CreateProtocol(firstPageToken, GetMessagesPage, MessageCollectionPageToken.FromToken, options); - } - - internal virtual ClientResult GetMessagesPage(ContinuationToken pageToken, RequestOptions options) - { - MessageCollectionPageToken token = MessageCollectionPageToken.FromToken(pageToken); - return GetMessagesPage(token.ThreadId, token.Limit, token.Order, token.After, token.Before, options); + IEnumerator subclient = new MessageCollectionClient(_messageSubClient, threadId, limit, order, after, before, options); + return PageCollectionHelpers.CreateProtocol(subclient); } - /// - internal virtual ClientResult GetMessagesPage(string threadId, int? limit, string order, string after, string before, RequestOptions options) - => _messageSubClient.GetMessages(threadId, limit, order, after, before, options); - /// public virtual Task GetMessageAsync(string threadId, string messageId, RequestOptions options) => _messageSubClient.GetMessageAsync(threadId, messageId, options); diff --git a/src/Custom/Common/OpenAIPageCollectionHelpers.cs b/src/Custom/Common/OpenAIPageCollectionHelpers.cs index b846e3f4c..242eb5892 100644 --- a/src/Custom/Common/OpenAIPageCollectionHelpers.cs +++ b/src/Custom/Common/OpenAIPageCollectionHelpers.cs @@ -1,119 +1,119 @@ -using System; -using System.ClientModel; -using System.ClientModel.Primitives; -using System.Collections.Generic; -using System.Text.Json; -using System.Threading.Tasks; -using OpenAI.Utility; - -#nullable enable - -namespace OpenAI; - -internal class OpenAIPageCollectionHelpers -{ - public delegate Task GetPageResultAsync(OpenAIPageToken pageToken, RequestOptions? options); - public delegate ClientResult GetPageResult(OpenAIPageToken pageToken, RequestOptions? options); - - public static AsyncPageCollection CreateAsync( - ContinuationToken firstPageToken, - GetPageResultAsync getPageResultAsync, - Func getToken, - RequestOptions? options) - where TValue : notnull - where TList : IJsonModel, IInternalListResponse - { - async Task> getPageAsync(ContinuationToken pageToken) - { - OpenAIPageToken token = getToken(pageToken); - - ClientResult result = await getPageResultAsync(token, options).ConfigureAwait(false); - - PipelineResponse response = result.GetRawResponse(); - IInternalListResponse list = ModelReaderWriter.Read(response.Content)!; - OpenAIPageToken? nextPageToken = token.GetNextPageToken(list.HasMore, list.LastId); - - return PageResult.Create(list.Data, pageToken, nextPageToken, response); - } - - return PageCollectionHelpers.CreateAsync(firstPageToken, getPageAsync); - } - - public static PageCollection Create( - ContinuationToken firstPageToken, - GetPageResult getPageResult, - Func getToken, - RequestOptions? options) - where TValue : notnull - where TList : IJsonModel, IInternalListResponse - { - PageResult getPage(ContinuationToken pageToken) - { - OpenAIPageToken token = getToken(pageToken); - - ClientResult result = getPageResult(token, options); - - PipelineResponse response = result.GetRawResponse(); - IInternalListResponse list = ModelReaderWriter.Read(response.Content)!; - OpenAIPageToken? nextPageToken = token.GetNextPageToken(list.HasMore, list.LastId); - - return PageResult.Create(list.Data, pageToken, nextPageToken, response); - } - - return PageCollectionHelpers.Create(firstPageToken, getPage); - } - - public static IAsyncEnumerable CreateProtocolAsync( - ContinuationToken firstPageToken, - GetPageResultAsync getPageResultAsync, - Func getToken, - RequestOptions? options) - { - async Task getPageAsync(ContinuationToken pageToken) - { - OpenAIPageToken token = getToken(pageToken); - return await getPageResultAsync(token, options).ConfigureAwait(false); - } - - ContinuationToken? getNextPageToken(ContinuationToken pageToken, ClientResult result) - { - PipelineResponse response = result.GetRawResponse(); - - using JsonDocument doc = JsonDocument.Parse(response.Content); - bool hasMore = doc.RootElement.GetProperty("has_more"u8).GetBoolean(); - string lastId = doc.RootElement.GetProperty("last_id"u8).GetString()!; - - OpenAIPageToken token = getToken(pageToken); - return token.GetNextPageToken(hasMore, lastId); - } - - return PageCollectionHelpers.CreatePrototolAsync(firstPageToken, getPageAsync, getNextPageToken); - } - - public static IEnumerable CreateProtocol( - ContinuationToken firstPageToken, - GetPageResult getPageResult, - Func getToken, - RequestOptions? options) - { - ClientResult getPage(ContinuationToken pageToken) - { - OpenAIPageToken token = (OpenAIPageToken)pageToken; - return getPageResult(token, options); - } - - ContinuationToken? getNextPageToken(ContinuationToken pageToken, ClientResult result) - { - PipelineResponse response = result.GetRawResponse(); - - using JsonDocument doc = JsonDocument.Parse(response.Content); - bool hasMore = doc.RootElement.GetProperty("has_more"u8).GetBoolean(); - string lastId = doc.RootElement.GetProperty("last_id"u8).GetString()!; - - OpenAIPageToken token = getToken(pageToken); - return token.GetNextPageToken(hasMore, lastId); - } - - return PageCollectionHelpers.CreatePrototol(firstPageToken, getPage, getNextPageToken); - } -} \ No newline at end of file +//using System; +//using System.ClientModel; +//using System.ClientModel.Primitives; +//using System.Collections.Generic; +//using System.Text.Json; +//using System.Threading.Tasks; +//using OpenAI.Utility; + +//#nullable enable + +//namespace OpenAI; + +//internal class OpenAIPageCollectionHelpers +//{ +// public delegate Task GetPageResultAsync(OpenAIPageToken pageToken, RequestOptions? options); +// public delegate ClientResult GetPageResult(OpenAIPageToken pageToken, RequestOptions? options); + +// public static AsyncPageCollection CreateAsync( +// ContinuationToken firstPageToken, +// GetPageResultAsync getPageResultAsync, +// Func getToken, +// RequestOptions? options) +// where TValue : notnull +// where TList : IJsonModel, IInternalListResponse +// { +// async Task> getPageAsync(ContinuationToken pageToken) +// { +// OpenAIPageToken token = getToken(pageToken); + +// ClientResult result = await getPageResultAsync(token, options).ConfigureAwait(false); + +// PipelineResponse response = result.GetRawResponse(); +// IInternalListResponse list = ModelReaderWriter.Read(response.Content)!; +// OpenAIPageToken? nextPageToken = token.GetNextPageToken(list.HasMore, list.LastId); + +// return PageResult.Create(list.Data, pageToken, nextPageToken, response); +// } + +// return PageCollectionHelpers.CreateAsync(firstPageToken, getPageAsync); +// } + +// public static PageCollection Create( +// ContinuationToken firstPageToken, +// GetPageResult getPageResult, +// Func getToken, +// RequestOptions? options) +// where TValue : notnull +// where TList : IJsonModel, IInternalListResponse +// { +// PageResult getPage(ContinuationToken pageToken) +// { +// OpenAIPageToken token = getToken(pageToken); + +// ClientResult result = getPageResult(token, options); + +// PipelineResponse response = result.GetRawResponse(); +// IInternalListResponse list = ModelReaderWriter.Read(response.Content)!; +// OpenAIPageToken? nextPageToken = token.GetNextPageToken(list.HasMore, list.LastId); + +// return PageResult.Create(list.Data, pageToken, nextPageToken, response); +// } + +// return PageCollectionHelpers.Create(firstPageToken, getPage); +// } + +// public static IAsyncEnumerable CreateProtocolAsync( +// ContinuationToken firstPageToken, +// GetPageResultAsync getPageResultAsync, +// Func getToken, +// RequestOptions? options) +// { +// async Task getPageAsync(ContinuationToken pageToken) +// { +// OpenAIPageToken token = getToken(pageToken); +// return await getPageResultAsync(token, options).ConfigureAwait(false); +// } + +// ContinuationToken? getNextPageToken(ContinuationToken pageToken, ClientResult result) +// { +// PipelineResponse response = result.GetRawResponse(); + +// using JsonDocument doc = JsonDocument.Parse(response.Content); +// bool hasMore = doc.RootElement.GetProperty("has_more"u8).GetBoolean(); +// string lastId = doc.RootElement.GetProperty("last_id"u8).GetString()!; + +// OpenAIPageToken token = getToken(pageToken); +// return token.GetNextPageToken(hasMore, lastId); +// } + +// return PageCollectionHelpers.CreatePrototolAsync(firstPageToken, getPageAsync, getNextPageToken); +// } + +// public static IEnumerable CreateProtocol( +// ContinuationToken firstPageToken, +// GetPageResult getPageResult, +// Func getToken, +// RequestOptions? options) +// { +// ClientResult getPage(ContinuationToken pageToken) +// { +// OpenAIPageToken token = (OpenAIPageToken)pageToken; +// return getPageResult(token, options); +// } + +// ContinuationToken? getNextPageToken(ContinuationToken pageToken, ClientResult result) +// { +// PipelineResponse response = result.GetRawResponse(); + +// using JsonDocument doc = JsonDocument.Parse(response.Content); +// bool hasMore = doc.RootElement.GetProperty("has_more"u8).GetBoolean(); +// string lastId = doc.RootElement.GetProperty("last_id"u8).GetString()!; + +// OpenAIPageToken token = getToken(pageToken); +// return token.GetNextPageToken(hasMore, lastId); +// } + +// return PageCollectionHelpers.CreatePrototol(firstPageToken, getPage, getNextPageToken); +// } +//} \ No newline at end of file diff --git a/src/To.Be.Generated/Internal/PageCollectionHelpers.cs b/src/To.Be.Generated/Internal/PageCollectionHelpers.cs new file mode 100644 index 000000000..22cfa43ca --- /dev/null +++ b/src/To.Be.Generated/Internal/PageCollectionHelpers.cs @@ -0,0 +1,171 @@ +using System; +using System.ClientModel; +using System.Collections; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +#nullable enable + +namespace OpenAI.Utility; + +internal class PageCollectionHelpers +{ + public static PageCollection Create(IEnumerator> enumerator) + => new PageCollectionClient(enumerator); + + public static IEnumerable CreateProtocol(IEnumerator enumerator) + { + while (enumerator.MoveNext()) + { + yield return enumerator.Current; + } + } + + private class PageCollectionClient : PageCollection + { + private readonly IEnumerator> _enumerator; + + public PageCollectionClient(IEnumerator> enumerator) + { + _enumerator = enumerator; + } + + public override IEnumerator> GetEnumerator() + { + while (_enumerator.MoveNext()) + { + yield return _enumerator.Current; + } + } + } + + //public static AsyncPageCollection CreateAsync( + // ContinuationToken firstPageToken, + // Func>> getPageAsync) where T : notnull + // => new AsyncFuncPageCollection(firstPageToken, getPageAsync); + + //public static PageCollection Create( + // ContinuationToken firstPageToken, + // Func> getPage) where T : notnull + // => new FuncPageCollection(firstPageToken, getPage); + + //public static IAsyncEnumerable CreatePrototolAsync( + // ContinuationToken firstPageToken, + // Func> getPageAsync, + // Func getNextPageToken) + // => new AsyncFuncResultEnumerable(firstPageToken, getPageAsync, getNextPageToken); + + //public static IEnumerable CreatePrototol(ContinuationToken firstPageToken, + // Func getPage, + // Func getNextPageToken) + // => new FuncResultEnumerable(firstPageToken, getPage, getNextPageToken); + + //private class AsyncFuncPageCollection : AsyncPageCollection where T : notnull + //{ + // private readonly Func>> _getPageAsync; + + // private ContinuationToken _currentPageToken; + + // public AsyncFuncPageCollection( + // ContinuationToken firstPageToken, + // Func>> getPageAsync) + // { + // _currentPageToken = firstPageToken; + // _getPageAsync = getPageAsync; + // } + + // protected override ContinuationToken CurrentPageToken + // { + // get => _currentPageToken; + // set => _currentPageToken = value; + // } + + // public override async Task> GetPageAsyncCore(ContinuationToken pageToken) + // => await _getPageAsync(pageToken).ConfigureAwait(false); + //} + + //private class FuncPageCollection : PageCollection where T : notnull + //{ + // private readonly Func> _getPage; + + // private ContinuationToken _currentPageToken; + + // public FuncPageCollection( + // ContinuationToken firstPageToken, + // Func> getPage) + // { + // _currentPageToken = firstPageToken; + // _getPage = getPage; + // } + + // protected override ContinuationToken CurrentPageToken + // { + // get => _currentPageToken; + // set => _currentPageToken = value; + // } + + // protected override PageResult GetPageCore(ContinuationToken pageToken) + // => _getPage(pageToken); + //} + + //private class AsyncFuncResultEnumerable : IAsyncEnumerable + //{ + // private readonly ContinuationToken _firstPageToken; + // private readonly Func> _getPageAsync; + // private readonly Func _getNextPageToken; + + // public AsyncFuncResultEnumerable(ContinuationToken firstPageToken, + // Func> getPageAsync, + // Func getNextPageToken) + // { + // _firstPageToken = firstPageToken; + // _getPageAsync = getPageAsync; + // _getNextPageToken = getNextPageToken; + // } + + // public async IAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + // { + // ContinuationToken? pageToken = _firstPageToken; + + // do + // { + // ClientResult result = await _getPageAsync(pageToken).ConfigureAwait(false); + // yield return result; + // pageToken = _getNextPageToken(pageToken, result); + // } + // while (pageToken != null); + // } + //} + + //private class FuncResultEnumerable : IEnumerable + //{ + // private readonly ContinuationToken _firstPageToken; + // private readonly Func _getPage; + // private readonly Func _getNextPageToken; + + // public FuncResultEnumerable(ContinuationToken firstPageToken, + // Func getPage, + // Func getNextPageToken) + // { + // _firstPageToken = firstPageToken; + // _getPage = getPage; + // _getNextPageToken = getNextPageToken; + // } + + // public IEnumerator GetEnumerator() + // { + // ContinuationToken? pageToken = _firstPageToken; + + // do + // { + // ClientResult result = _getPage(pageToken); + // yield return result; + // pageToken = _getNextPageToken(pageToken, result); + // } + // while (pageToken != null); + // } + + // IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + //} +} diff --git a/src/To.Be.Generated/Internal/PageEnumerator.cs b/src/To.Be.Generated/Internal/PageEnumerator.cs new file mode 100644 index 000000000..a4acde0d3 --- /dev/null +++ b/src/To.Be.Generated/Internal/PageEnumerator.cs @@ -0,0 +1,29 @@ +using System.ClientModel; +using System.Collections; +using System.Collections.Generic; + +#nullable enable + +namespace OpenAI; + +internal abstract class PageEnumerator : IEnumerator> +{ + private readonly PageResultEnumerator _resultEnumerator; + + public PageEnumerator(PageResultEnumerator resultEnumerator) + { + _resultEnumerator = resultEnumerator; + } + + public abstract PageResult GetPageFromResult(ClientResult result); + + public PageResult Current => GetPageFromResult(_resultEnumerator.Current); + + object IEnumerator.Current => Current; + + public bool MoveNext() => _resultEnumerator.MoveNext(); + + public void Reset() => _resultEnumerator.Reset(); + + public void Dispose() => _resultEnumerator.Dispose(); +} diff --git a/src/To.Be.Generated/Internal/PageResultEnumerator.cs b/src/To.Be.Generated/Internal/PageResultEnumerator.cs new file mode 100644 index 000000000..cbbaeeb11 --- /dev/null +++ b/src/To.Be.Generated/Internal/PageResultEnumerator.cs @@ -0,0 +1,42 @@ +using System.ClientModel; +using System.Collections; +using System.Collections.Generic; + +#nullable enable + +namespace OpenAI; + +internal abstract class PageResultEnumerator : IEnumerator +{ + private ClientResult? _current; + + public ClientResult Current => _current!; + + object IEnumerator.Current => Current; + + public bool MoveNext() + { + if (_current == null) + { + _current = GetFirst(); + } + else + { + _current = GetNext(_current); + } + + return HasNext(_current); + } + + public void Reset() => _current = null; + + // Idea is that this is generated on the client + public abstract ClientResult GetFirst(); + + // Idea is that this is generated on the client + public abstract ClientResult GetNext(ClientResult result); + + public abstract bool HasNext(ClientResult result); + + public virtual void Dispose() { } +} \ No newline at end of file diff --git a/src/To.Be.Generated/MessageCollectionClient.cs b/src/To.Be.Generated/MessageCollectionClient.cs new file mode 100644 index 000000000..4d3bc2170 --- /dev/null +++ b/src/To.Be.Generated/MessageCollectionClient.cs @@ -0,0 +1,56 @@ +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Text.Json; + +namespace OpenAI.Assistants; + +internal class MessageCollectionClient : PageResultEnumerator +{ + private readonly InternalAssistantMessageClient _messageSubClient; + + private readonly string _threadId; + private readonly int? _limit; + private readonly string _order; + private readonly string _after; + private readonly string _before; + private readonly RequestOptions _options; + + public MessageCollectionClient(InternalAssistantMessageClient subclient, string threadId, int? limit, string order, string after, string before, RequestOptions options) + { + _threadId = threadId; + _limit = limit; + _order = order; + _after = after; + _before = before; + _options = options; + + _messageSubClient = subclient; + } + + public override ClientResult GetFirst() + => GetMessagesPage(_threadId, _limit, _order, _after, _before, _options); + + public override ClientResult GetNext(ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + + using JsonDocument doc = JsonDocument.Parse(response.Content); + string lastId = doc.RootElement.GetProperty("last_id"u8).GetString()!; + + return GetMessagesPage(_threadId, _limit, _order, lastId, _before, _options); + } + + public override bool HasNext(ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + + using JsonDocument doc = JsonDocument.Parse(response.Content); + bool hasMore = doc.RootElement.GetProperty("has_more"u8).GetBoolean(); + + return hasMore; + } + + /// + internal virtual ClientResult GetMessagesPage(string threadId, int? limit, string order, string after, string before, RequestOptions options) + => _messageSubClient.GetMessages(threadId, limit, order, after, before, options); +} diff --git a/src/Utility/PageCollectionHelpers.cs b/src/Utility/PageCollectionHelpers.cs deleted file mode 100644 index 8c39229fd..000000000 --- a/src/Utility/PageCollectionHelpers.cs +++ /dev/null @@ -1,142 +0,0 @@ -using System; -using System.ClientModel; -using System.Collections; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; - -#nullable enable - -namespace OpenAI.Utility; - -internal class PageCollectionHelpers -{ - public static AsyncPageCollection CreateAsync( - ContinuationToken firstPageToken, - Func>> getPageAsync) where T : notnull - => new AsyncFuncPageCollection(firstPageToken, getPageAsync); - - public static PageCollection Create( - ContinuationToken firstPageToken, - Func> getPage) where T : notnull - => new FuncPageCollection(firstPageToken, getPage); - - public static IAsyncEnumerable CreatePrototolAsync( - ContinuationToken firstPageToken, - Func> getPageAsync, - Func getNextPageToken) - => new AsyncFuncResultEnumerable(firstPageToken, getPageAsync, getNextPageToken); - - public static IEnumerable CreatePrototol(ContinuationToken firstPageToken, - Func getPage, - Func getNextPageToken) - => new FuncResultEnumerable(firstPageToken, getPage, getNextPageToken); - - private class AsyncFuncPageCollection : AsyncPageCollection where T : notnull - { - private readonly Func>> _getPageAsync; - - private ContinuationToken _currentPageToken; - - public AsyncFuncPageCollection( - ContinuationToken firstPageToken, - Func>> getPageAsync) - { - _currentPageToken = firstPageToken; - _getPageAsync = getPageAsync; - } - - protected override ContinuationToken CurrentPageToken - { - get => _currentPageToken; - set => _currentPageToken = value; - } - - public override async Task> GetPageAsyncCore(ContinuationToken pageToken) - => await _getPageAsync(pageToken).ConfigureAwait(false); - } - - private class FuncPageCollection : PageCollection where T : notnull - { - private readonly Func> _getPage; - - private ContinuationToken _currentPageToken; - - public FuncPageCollection( - ContinuationToken firstPageToken, - Func> getPage) - { - _currentPageToken = firstPageToken; - _getPage = getPage; - } - - protected override ContinuationToken CurrentPageToken - { - get => _currentPageToken; - set => _currentPageToken = value; - } - - protected override PageResult GetPageCore(ContinuationToken pageToken) - => _getPage(pageToken); - } - - private class AsyncFuncResultEnumerable : IAsyncEnumerable - { - private readonly ContinuationToken _firstPageToken; - private readonly Func> _getPageAsync; - private readonly Func _getNextPageToken; - - public AsyncFuncResultEnumerable(ContinuationToken firstPageToken, - Func> getPageAsync, - Func getNextPageToken) - { - _firstPageToken = firstPageToken; - _getPageAsync = getPageAsync; - _getNextPageToken = getNextPageToken; - } - - public async IAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) - { - ContinuationToken? pageToken = _firstPageToken; - - do - { - ClientResult result = await _getPageAsync(pageToken).ConfigureAwait(false); - yield return result; - pageToken = _getNextPageToken(pageToken, result); - } - while (pageToken != null); - } - } - - private class FuncResultEnumerable : IEnumerable - { - private readonly ContinuationToken _firstPageToken; - private readonly Func _getPage; - private readonly Func _getNextPageToken; - - public FuncResultEnumerable(ContinuationToken firstPageToken, - Func getPage, - Func getNextPageToken) - { - _firstPageToken = firstPageToken; - _getPage = getPage; - _getNextPageToken = getNextPageToken; - } - - public IEnumerator GetEnumerator() - { - ContinuationToken? pageToken = _firstPageToken; - - do - { - ClientResult result = _getPage(pageToken); - yield return result; - pageToken = _getNextPageToken(pageToken, result); - } - while (pageToken != null); - } - - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - } -} From 313753e76892578d0bcecca963c51ef2e0817ec3 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Mon, 1 Jul 2024 15:48:15 -0700 Subject: [PATCH 34/72] more backup --- .../Assistants/AssistantClient.Protocol.cs | 4 +- src/Custom/Assistants/AssistantClient.cs | 14 +- .../Internal/PageCollectionHelpers.cs | 21 ++- .../Internal/PageEnumerator.cs | 16 +-- src/To.Be.Generated/Internal/PageToken.cs | 13 ++ .../MessageCollectionClient.cs | 124 ++++++++++-------- .../MessageCollectionPageToken.cs | 18 ++- src/To.Be.Generated/MessagePageEnumerator.cs | 36 +++++ .../MessagePageResultEnumerator.cs | 72 ++++++++++ 9 files changed, 232 insertions(+), 86 deletions(-) create mode 100644 src/To.Be.Generated/Internal/PageToken.cs rename src/{Custom/Assistants => To.Be.Generated}/MessageCollectionPageToken.cs (92%) create mode 100644 src/To.Be.Generated/MessagePageEnumerator.cs create mode 100644 src/To.Be.Generated/MessagePageResultEnumerator.cs diff --git a/src/Custom/Assistants/AssistantClient.Protocol.cs b/src/Custom/Assistants/AssistantClient.Protocol.cs index b938208d2..7a228690a 100644 --- a/src/Custom/Assistants/AssistantClient.Protocol.cs +++ b/src/Custom/Assistants/AssistantClient.Protocol.cs @@ -257,8 +257,8 @@ internal virtual async Task GetMessagesPageAsync(string threadId, public virtual IEnumerable GetMessages(string threadId, int? limit, string order, string after, string before, RequestOptions options) { - IEnumerator subclient = new MessageCollectionClient(_messageSubClient, threadId, limit, order, after, before, options); - return PageCollectionHelpers.CreateProtocol(subclient); + IEnumerator enumerator = new MessagePageResultEnumerator(_messageSubClient, threadId, limit, order, after, before, options); + return PageCollectionHelpers.CreateProtocol(enumerator); } /// diff --git a/src/Custom/Assistants/AssistantClient.cs b/src/Custom/Assistants/AssistantClient.cs index 39fc60d24..c1944fd18 100644 --- a/src/Custom/Assistants/AssistantClient.cs +++ b/src/Custom/Assistants/AssistantClient.cs @@ -1,3 +1,4 @@ +using OpenAI.Utility; using System; using System.ClientModel; using System.ClientModel.Primitives; @@ -424,12 +425,15 @@ public virtual PageCollection GetMessages( { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); - MessageCollectionPageToken firstPageToken = MessageCollectionPageToken.FromOptions(threadId, options); - return OpenAIPageCollectionHelpers.Create( - firstPageToken, - GetMessagesPage, - MessageCollectionPageToken.FromToken, + IEnumerable enumerable = GetMessages( + threadId, + options?.PageSize, + options?.Order?.ToString(), + options?.AfterId, + options?.BeforeId, cancellationToken.ToRequestOptions()); + MessagePageEnumerator enumerator = new(enumerable.GetEnumerator()); + return PageCollectionHelpers.Create(enumerator); } public virtual PageCollection GetMessages( diff --git a/src/To.Be.Generated/Internal/PageCollectionHelpers.cs b/src/To.Be.Generated/Internal/PageCollectionHelpers.cs index 22cfa43ca..902f4c45b 100644 --- a/src/To.Be.Generated/Internal/PageCollectionHelpers.cs +++ b/src/To.Be.Generated/Internal/PageCollectionHelpers.cs @@ -1,9 +1,5 @@ -using System; -using System.ClientModel; -using System.Collections; +using System.ClientModel; using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; #nullable enable @@ -11,8 +7,8 @@ namespace OpenAI.Utility; internal class PageCollectionHelpers { - public static PageCollection Create(IEnumerator> enumerator) - => new PageCollectionClient(enumerator); + public static PageCollection Create(PageEnumerator enumerator) + => new FuncPageCollection(enumerator); public static IEnumerable CreateProtocol(IEnumerator enumerator) { @@ -22,11 +18,11 @@ public static IEnumerable CreateProtocol(IEnumerator } } - private class PageCollectionClient : PageCollection + private class FuncPageCollection : PageCollection { - private readonly IEnumerator> _enumerator; - - public PageCollectionClient(IEnumerator> enumerator) + private readonly PageEnumerator _enumerator; + + public FuncPageCollection(PageEnumerator enumerator) { _enumerator = enumerator; } @@ -35,7 +31,8 @@ public override IEnumerator> GetEnumerator() { while (_enumerator.MoveNext()) { - yield return _enumerator.Current; + ClientResult result = _enumerator.Current; + yield return _enumerator.GetPageFromResult(result); } } } diff --git a/src/To.Be.Generated/Internal/PageEnumerator.cs b/src/To.Be.Generated/Internal/PageEnumerator.cs index a4acde0d3..d42ec6419 100644 --- a/src/To.Be.Generated/Internal/PageEnumerator.cs +++ b/src/To.Be.Generated/Internal/PageEnumerator.cs @@ -8,22 +8,22 @@ namespace OpenAI; internal abstract class PageEnumerator : IEnumerator> { - private readonly PageResultEnumerator _resultEnumerator; - - public PageEnumerator(PageResultEnumerator resultEnumerator) + public PageEnumerator(IEnumerator resultEnumerator) { - _resultEnumerator = resultEnumerator; + ResultEnumerator = resultEnumerator; } + public IEnumerator ResultEnumerator { get; } + public abstract PageResult GetPageFromResult(ClientResult result); - public PageResult Current => GetPageFromResult(_resultEnumerator.Current); + public PageResult Current => GetPageFromResult(ResultEnumerator.Current); object IEnumerator.Current => Current; - public bool MoveNext() => _resultEnumerator.MoveNext(); + public bool MoveNext() => ResultEnumerator.MoveNext(); - public void Reset() => _resultEnumerator.Reset(); + public void Reset() => ResultEnumerator.Reset(); - public void Dispose() => _resultEnumerator.Dispose(); + public void Dispose() => ResultEnumerator.Dispose(); } diff --git a/src/To.Be.Generated/Internal/PageToken.cs b/src/To.Be.Generated/Internal/PageToken.cs new file mode 100644 index 000000000..f82096b15 --- /dev/null +++ b/src/To.Be.Generated/Internal/PageToken.cs @@ -0,0 +1,13 @@ +//using System; +//using System.ClientModel; +//using System.Collections.Generic; +//using System.Text; + +//#nullable enable + +//namespace OpenAI; + +//internal abstract class PageToken : ContinuationToken +//{ +// public abstract PageToken? GetNextPageToken(); +//} diff --git a/src/To.Be.Generated/MessageCollectionClient.cs b/src/To.Be.Generated/MessageCollectionClient.cs index 4d3bc2170..1f5d98521 100644 --- a/src/To.Be.Generated/MessageCollectionClient.cs +++ b/src/To.Be.Generated/MessageCollectionClient.cs @@ -1,56 +1,68 @@ -using System.ClientModel; -using System.ClientModel.Primitives; -using System.Text.Json; - -namespace OpenAI.Assistants; - -internal class MessageCollectionClient : PageResultEnumerator -{ - private readonly InternalAssistantMessageClient _messageSubClient; - - private readonly string _threadId; - private readonly int? _limit; - private readonly string _order; - private readonly string _after; - private readonly string _before; - private readonly RequestOptions _options; - - public MessageCollectionClient(InternalAssistantMessageClient subclient, string threadId, int? limit, string order, string after, string before, RequestOptions options) - { - _threadId = threadId; - _limit = limit; - _order = order; - _after = after; - _before = before; - _options = options; - - _messageSubClient = subclient; - } - - public override ClientResult GetFirst() - => GetMessagesPage(_threadId, _limit, _order, _after, _before, _options); - - public override ClientResult GetNext(ClientResult result) - { - PipelineResponse response = result.GetRawResponse(); - - using JsonDocument doc = JsonDocument.Parse(response.Content); - string lastId = doc.RootElement.GetProperty("last_id"u8).GetString()!; - - return GetMessagesPage(_threadId, _limit, _order, lastId, _before, _options); - } - - public override bool HasNext(ClientResult result) - { - PipelineResponse response = result.GetRawResponse(); - - using JsonDocument doc = JsonDocument.Parse(response.Content); - bool hasMore = doc.RootElement.GetProperty("has_more"u8).GetBoolean(); - - return hasMore; - } - - /// - internal virtual ClientResult GetMessagesPage(string threadId, int? limit, string order, string after, string before, RequestOptions options) - => _messageSubClient.GetMessages(threadId, limit, order, after, before, options); -} +//using System.ClientModel; +//using System.ClientModel.Primitives; +//using System.Text.Json; + +//#nullable enable + +//namespace OpenAI.Assistants; + +//internal class MessageCollectionClient : PageResultEnumerator +//{ +// private readonly InternalAssistantMessageClient _messageSubClient; + +// private readonly string _threadId; +// private readonly int? _limit; +// private readonly string _order; +// private readonly string _after; +// private readonly string _before; +// private readonly RequestOptions _options; + +// public MessageCollectionClient(InternalAssistantMessageClient subclient, string threadId, int? limit, string order, string after, string before, RequestOptions options) +// { +// _threadId = threadId; +// _limit = limit; +// _order = order; +// _after = after; +// _before = before; +// _options = options; + +// _messageSubClient = subclient; +// } + +// public override ClientResult GetFirst() +// => GetMessagesPage(_threadId, _limit, _order, _after, _before, _options); + +// public override ClientResult GetNext(ClientResult result) +// { +// PipelineResponse response = result.GetRawResponse(); + +// using JsonDocument doc = JsonDocument.Parse(response.Content); +// string lastId = doc.RootElement.GetProperty("last_id"u8).GetString()!; + +// return GetMessagesPage(_threadId, _limit, _order, lastId, _before, _options); +// } + +// public override bool HasNext(ClientResult result) +// { +// PipelineResponse response = result.GetRawResponse(); + +// using JsonDocument doc = JsonDocument.Parse(response.Content); +// bool hasMore = doc.RootElement.GetProperty("has_more"u8).GetBoolean(); + +// return hasMore; +// } + +// /// +// internal virtual ClientResult GetMessagesPage(string threadId, int? limit, string order, string after, string before, RequestOptions options) +// => _messageSubClient.GetMessages(threadId, limit, order, after, before, options); + +// //// This could live in a different class +// //public PageResult GetPageFromResult(ClientResult result) +// //{ +// // PipelineResponse response = result.GetRawResponse(); +// // InternalListMessagesResponse list = ModelReaderWriter.Read(response.Content)!; +// // MessageCollectionPageToken pageToken = MessageCollectionPageToken.FromOptions(_threadId, _limit, _order, ) +// // return PageResult.Create(list.Data, pageToken, nextPageToken, response); + +// //} +//} diff --git a/src/Custom/Assistants/MessageCollectionPageToken.cs b/src/To.Be.Generated/MessageCollectionPageToken.cs similarity index 92% rename from src/Custom/Assistants/MessageCollectionPageToken.cs rename to src/To.Be.Generated/MessageCollectionPageToken.cs index 971adf8aa..914cff7a7 100644 --- a/src/Custom/Assistants/MessageCollectionPageToken.cs +++ b/src/To.Be.Generated/MessageCollectionPageToken.cs @@ -8,16 +8,28 @@ namespace OpenAI.Assistants; -internal class MessageCollectionPageToken : OpenAIPageToken +internal class MessageCollectionPageToken : ContinuationToken { public MessageCollectionPageToken(string threadId, int? limit, string? order, string? after, string? before) - : base(limit, order, after, before) { ThreadId = threadId; + + Limit = limit; + Order = order; + After = after; + Before = before; } public string ThreadId { get; } + public int? Limit { get; } + + public string? Order { get; } + + public string? After { get; } + + public string? Before { get; } + public override BinaryData ToBytes() { using MemoryStream stream = new(); @@ -54,7 +66,7 @@ public override BinaryData ToBytes() return BinaryData.FromStream(stream); } - public override OpenAIPageToken? GetNextPageToken(bool hasMore, string? lastId) + public MessageCollectionPageToken? GetNextPageToken(bool hasMore, string? lastId) => GetNextPageToken(ThreadId, Limit, Order, lastId, Before, hasMore); // Convenience - first page request diff --git a/src/To.Be.Generated/MessagePageEnumerator.cs b/src/To.Be.Generated/MessagePageEnumerator.cs new file mode 100644 index 000000000..da67f1b76 --- /dev/null +++ b/src/To.Be.Generated/MessagePageEnumerator.cs @@ -0,0 +1,36 @@ +using System; + +#nullable enable + +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Collections.Generic; + +namespace OpenAI.Assistants; + +internal class MessagePageEnumerator : PageEnumerator +{ + public MessagePageEnumerator(IEnumerator resultEnumerator) + : base(resultEnumerator) + { + } + + public override PageResult GetPageFromResult(ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + InternalListMessagesResponse list = ModelReaderWriter.Read(response.Content)!; + + MessagePageResultEnumerator resultEnumerator = (MessagePageResultEnumerator)ResultEnumerator; + + MessageCollectionPageToken pageToken = MessageCollectionPageToken.FromOptions( + resultEnumerator.ThreadId, + resultEnumerator.Limit, + resultEnumerator.Order, + resultEnumerator.After, + resultEnumerator.Before); + + MessageCollectionPageToken? nextPageToken = pageToken.GetNextPageToken(list.HasMore, list.LastId); + + return PageResult.Create(list.Data, pageToken, nextPageToken, response); + } +} diff --git a/src/To.Be.Generated/MessagePageResultEnumerator.cs b/src/To.Be.Generated/MessagePageResultEnumerator.cs new file mode 100644 index 000000000..6cde0fc7d --- /dev/null +++ b/src/To.Be.Generated/MessagePageResultEnumerator.cs @@ -0,0 +1,72 @@ +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Text.Json; + +#nullable enable + +namespace OpenAI.Assistants; + +internal class MessagePageResultEnumerator : PageResultEnumerator +{ + private readonly InternalAssistantMessageClient _messageSubClient; + + private readonly string _threadId; + private readonly int? _limit; + private readonly string _order; + + // Note: this one is special + private string _after; + + private readonly string _before; + private readonly RequestOptions _options; + + public MessagePageResultEnumerator(InternalAssistantMessageClient subclient, string threadId, int? limit, string order, string after, string before, RequestOptions options) + { + _threadId = threadId; + _limit = limit; + _order = order; + _after = after; + _before = before; + _options = options; + + _messageSubClient = subclient; + } + + // TODO: do we need these in so many places? + public string ThreadId => _threadId; + + public int? Limit => _limit; + + public string? Order => _order; + + public string? After => _after; + + public string? Before => _before; + + public override ClientResult GetFirst() + => GetMessagesPage(_threadId, _limit, _order, _after, _before, _options); + + public override ClientResult GetNext(ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + + using JsonDocument doc = JsonDocument.Parse(response.Content); + _after = doc.RootElement.GetProperty("last_id"u8).GetString()!; + + return GetMessagesPage(_threadId, _limit, _order, _after, _before, _options); + } + + public override bool HasNext(ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + + using JsonDocument doc = JsonDocument.Parse(response.Content); + bool hasMore = doc.RootElement.GetProperty("has_more"u8).GetBoolean(); + + return hasMore; + } + + // Note: this is the protocol method + internal virtual ClientResult GetMessagesPage(string threadId, int? limit, string order, string after, string before, RequestOptions options) + => _messageSubClient.GetMessages(threadId, limit, order, after, before, options); +} From a8e17e3a5f7a04a24b78547594d4940fbe79dcab Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Mon, 1 Jul 2024 15:53:30 -0700 Subject: [PATCH 35/72] tidy up before taking inventory --- src/Custom/Assistants/AssistantClient.cs | 7 +- .../Internal/PageCollectionHelpers.cs | 129 ------------------ 2 files changed, 6 insertions(+), 130 deletions(-) diff --git a/src/Custom/Assistants/AssistantClient.cs b/src/Custom/Assistants/AssistantClient.cs index c1944fd18..2d42956a9 100644 --- a/src/Custom/Assistants/AssistantClient.cs +++ b/src/Custom/Assistants/AssistantClient.cs @@ -425,6 +425,7 @@ public virtual PageCollection GetMessages( { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); + // Call protocol method to get protocol subclient IEnumerable enumerable = GetMessages( threadId, options?.PageSize, @@ -432,8 +433,12 @@ public virtual PageCollection GetMessages( options?.AfterId, options?.BeforeId, cancellationToken.ToRequestOptions()); + + // Create convenience subclient MessagePageEnumerator enumerator = new(enumerable.GetEnumerator()); - return PageCollectionHelpers.Create(enumerator); + + // Wrap it in the outer collection + return PageCollectionHelpers.Create(enumerator); } public virtual PageCollection GetMessages( diff --git a/src/To.Be.Generated/Internal/PageCollectionHelpers.cs b/src/To.Be.Generated/Internal/PageCollectionHelpers.cs index 902f4c45b..da37fc764 100644 --- a/src/To.Be.Generated/Internal/PageCollectionHelpers.cs +++ b/src/To.Be.Generated/Internal/PageCollectionHelpers.cs @@ -36,133 +36,4 @@ public override IEnumerator> GetEnumerator() } } } - - //public static AsyncPageCollection CreateAsync( - // ContinuationToken firstPageToken, - // Func>> getPageAsync) where T : notnull - // => new AsyncFuncPageCollection(firstPageToken, getPageAsync); - - //public static PageCollection Create( - // ContinuationToken firstPageToken, - // Func> getPage) where T : notnull - // => new FuncPageCollection(firstPageToken, getPage); - - //public static IAsyncEnumerable CreatePrototolAsync( - // ContinuationToken firstPageToken, - // Func> getPageAsync, - // Func getNextPageToken) - // => new AsyncFuncResultEnumerable(firstPageToken, getPageAsync, getNextPageToken); - - //public static IEnumerable CreatePrototol(ContinuationToken firstPageToken, - // Func getPage, - // Func getNextPageToken) - // => new FuncResultEnumerable(firstPageToken, getPage, getNextPageToken); - - //private class AsyncFuncPageCollection : AsyncPageCollection where T : notnull - //{ - // private readonly Func>> _getPageAsync; - - // private ContinuationToken _currentPageToken; - - // public AsyncFuncPageCollection( - // ContinuationToken firstPageToken, - // Func>> getPageAsync) - // { - // _currentPageToken = firstPageToken; - // _getPageAsync = getPageAsync; - // } - - // protected override ContinuationToken CurrentPageToken - // { - // get => _currentPageToken; - // set => _currentPageToken = value; - // } - - // public override async Task> GetPageAsyncCore(ContinuationToken pageToken) - // => await _getPageAsync(pageToken).ConfigureAwait(false); - //} - - //private class FuncPageCollection : PageCollection where T : notnull - //{ - // private readonly Func> _getPage; - - // private ContinuationToken _currentPageToken; - - // public FuncPageCollection( - // ContinuationToken firstPageToken, - // Func> getPage) - // { - // _currentPageToken = firstPageToken; - // _getPage = getPage; - // } - - // protected override ContinuationToken CurrentPageToken - // { - // get => _currentPageToken; - // set => _currentPageToken = value; - // } - - // protected override PageResult GetPageCore(ContinuationToken pageToken) - // => _getPage(pageToken); - //} - - //private class AsyncFuncResultEnumerable : IAsyncEnumerable - //{ - // private readonly ContinuationToken _firstPageToken; - // private readonly Func> _getPageAsync; - // private readonly Func _getNextPageToken; - - // public AsyncFuncResultEnumerable(ContinuationToken firstPageToken, - // Func> getPageAsync, - // Func getNextPageToken) - // { - // _firstPageToken = firstPageToken; - // _getPageAsync = getPageAsync; - // _getNextPageToken = getNextPageToken; - // } - - // public async IAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) - // { - // ContinuationToken? pageToken = _firstPageToken; - - // do - // { - // ClientResult result = await _getPageAsync(pageToken).ConfigureAwait(false); - // yield return result; - // pageToken = _getNextPageToken(pageToken, result); - // } - // while (pageToken != null); - // } - //} - - //private class FuncResultEnumerable : IEnumerable - //{ - // private readonly ContinuationToken _firstPageToken; - // private readonly Func _getPage; - // private readonly Func _getNextPageToken; - - // public FuncResultEnumerable(ContinuationToken firstPageToken, - // Func getPage, - // Func getNextPageToken) - // { - // _firstPageToken = firstPageToken; - // _getPage = getPage; - // _getNextPageToken = getNextPageToken; - // } - - // public IEnumerator GetEnumerator() - // { - // ContinuationToken? pageToken = _firstPageToken; - - // do - // { - // ClientResult result = _getPage(pageToken); - // yield return result; - // pageToken = _getNextPageToken(pageToken, result); - // } - // while (pageToken != null); - // } - - // IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - //} } From c5261d18876d69744d9a8cf6c7f7d93f570286cc Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Mon, 1 Jul 2024 16:09:06 -0700 Subject: [PATCH 36/72] backup prior to attempt to converge around single internal collection subclient per operation --- src/Custom/Assistants/AssistantClient.cs | 24 +++++++++---- .../Internal/PageCollectionHelpers.cs | 22 +++++++----- .../Internal/PageEnumerator.cs | 29 --------------- src/To.Be.Generated/MessagePageEnumerator.cs | 36 ------------------- .../MessagePageResultEnumerator.cs | 20 +++++++++++ 5 files changed, 52 insertions(+), 79 deletions(-) delete mode 100644 src/To.Be.Generated/Internal/PageEnumerator.cs delete mode 100644 src/To.Be.Generated/MessagePageEnumerator.cs diff --git a/src/Custom/Assistants/AssistantClient.cs b/src/Custom/Assistants/AssistantClient.cs index 2d42956a9..28d8d1f71 100644 --- a/src/Custom/Assistants/AssistantClient.cs +++ b/src/Custom/Assistants/AssistantClient.cs @@ -435,22 +435,34 @@ public virtual PageCollection GetMessages( cancellationToken.ToRequestOptions()); // Create convenience subclient - MessagePageEnumerator enumerator = new(enumerable.GetEnumerator()); + MessagePageResultEnumerator enumerator = (MessagePageResultEnumerator)enumerable.GetEnumerator(); // Wrap it in the outer collection - return PageCollectionHelpers.Create(enumerator); + return PageCollectionHelpers.Create(enumerator, result => MessagePageResultEnumerator.GetPageFromResult(enumerator, result)); } public virtual PageCollection GetMessages( ContinuationToken firstPageToken, CancellationToken cancellationToken = default) { + Argument.AssertNotNull(firstPageToken, nameof(firstPageToken)); + MessageCollectionPageToken pageToken = MessageCollectionPageToken.FromToken(firstPageToken); - return OpenAIPageCollectionHelpers.Create( - firstPageToken, - GetMessagesPage, - MessageCollectionPageToken.FromToken, + + // Call protocol method to get protocol subclient + IEnumerable enumerable = GetMessages( + pageToken.ThreadId, + pageToken.Limit, + pageToken.Order, + pageToken.After, + pageToken.Before, cancellationToken.ToRequestOptions()); + + // Create convenience subclient + MessagePageResultEnumerator enumerator = (MessagePageResultEnumerator)enumerable.GetEnumerator(); + + // Wrap it in the outer collection + return PageCollectionHelpers.Create(enumerator, result => MessagePageResultEnumerator.GetPageFromResult(enumerator, result)); } /// diff --git a/src/To.Be.Generated/Internal/PageCollectionHelpers.cs b/src/To.Be.Generated/Internal/PageCollectionHelpers.cs index da37fc764..a0389d188 100644 --- a/src/To.Be.Generated/Internal/PageCollectionHelpers.cs +++ b/src/To.Be.Generated/Internal/PageCollectionHelpers.cs @@ -1,4 +1,5 @@ -using System.ClientModel; +using System; +using System.ClientModel; using System.Collections.Generic; #nullable enable @@ -7,8 +8,10 @@ namespace OpenAI.Utility; internal class PageCollectionHelpers { - public static PageCollection Create(PageEnumerator enumerator) - => new FuncPageCollection(enumerator); + public static PageCollection Create( + IEnumerator enumerator, + Func> getPageFromResult) + => new FuncPageCollection(enumerator, getPageFromResult); public static IEnumerable CreateProtocol(IEnumerator enumerator) { @@ -20,19 +23,22 @@ public static IEnumerable CreateProtocol(IEnumerator private class FuncPageCollection : PageCollection { - private readonly PageEnumerator _enumerator; - - public FuncPageCollection(PageEnumerator enumerator) + private readonly IEnumerator _enumerator; + private readonly Func> _getPageFromResult; + + public FuncPageCollection( + IEnumerator enumerator, + Func> getPageFromResult) { _enumerator = enumerator; + _getPageFromResult = getPageFromResult; } public override IEnumerator> GetEnumerator() { while (_enumerator.MoveNext()) { - ClientResult result = _enumerator.Current; - yield return _enumerator.GetPageFromResult(result); + yield return _getPageFromResult(_enumerator.Current); } } } diff --git a/src/To.Be.Generated/Internal/PageEnumerator.cs b/src/To.Be.Generated/Internal/PageEnumerator.cs deleted file mode 100644 index d42ec6419..000000000 --- a/src/To.Be.Generated/Internal/PageEnumerator.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.ClientModel; -using System.Collections; -using System.Collections.Generic; - -#nullable enable - -namespace OpenAI; - -internal abstract class PageEnumerator : IEnumerator> -{ - public PageEnumerator(IEnumerator resultEnumerator) - { - ResultEnumerator = resultEnumerator; - } - - public IEnumerator ResultEnumerator { get; } - - public abstract PageResult GetPageFromResult(ClientResult result); - - public PageResult Current => GetPageFromResult(ResultEnumerator.Current); - - object IEnumerator.Current => Current; - - public bool MoveNext() => ResultEnumerator.MoveNext(); - - public void Reset() => ResultEnumerator.Reset(); - - public void Dispose() => ResultEnumerator.Dispose(); -} diff --git a/src/To.Be.Generated/MessagePageEnumerator.cs b/src/To.Be.Generated/MessagePageEnumerator.cs deleted file mode 100644 index da67f1b76..000000000 --- a/src/To.Be.Generated/MessagePageEnumerator.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System; - -#nullable enable - -using System.ClientModel; -using System.ClientModel.Primitives; -using System.Collections.Generic; - -namespace OpenAI.Assistants; - -internal class MessagePageEnumerator : PageEnumerator -{ - public MessagePageEnumerator(IEnumerator resultEnumerator) - : base(resultEnumerator) - { - } - - public override PageResult GetPageFromResult(ClientResult result) - { - PipelineResponse response = result.GetRawResponse(); - InternalListMessagesResponse list = ModelReaderWriter.Read(response.Content)!; - - MessagePageResultEnumerator resultEnumerator = (MessagePageResultEnumerator)ResultEnumerator; - - MessageCollectionPageToken pageToken = MessageCollectionPageToken.FromOptions( - resultEnumerator.ThreadId, - resultEnumerator.Limit, - resultEnumerator.Order, - resultEnumerator.After, - resultEnumerator.Before); - - MessageCollectionPageToken? nextPageToken = pageToken.GetNextPageToken(list.HasMore, list.LastId); - - return PageResult.Create(list.Data, pageToken, nextPageToken, response); - } -} diff --git a/src/To.Be.Generated/MessagePageResultEnumerator.cs b/src/To.Be.Generated/MessagePageResultEnumerator.cs index 6cde0fc7d..d219fb84a 100644 --- a/src/To.Be.Generated/MessagePageResultEnumerator.cs +++ b/src/To.Be.Generated/MessagePageResultEnumerator.cs @@ -69,4 +69,24 @@ public override bool HasNext(ClientResult result) // Note: this is the protocol method internal virtual ClientResult GetMessagesPage(string threadId, int? limit, string order, string after, string before, RequestOptions options) => _messageSubClient.GetMessages(threadId, limit, order, after, before, options); + + // Note: this is the static page deserialization method + public static PageResult GetPageFromResult( + MessagePageResultEnumerator resultEnumerator, + ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + InternalListMessagesResponse list = ModelReaderWriter.Read(response.Content)!; + + MessageCollectionPageToken pageToken = MessageCollectionPageToken.FromOptions( + resultEnumerator.ThreadId, + resultEnumerator.Limit, + resultEnumerator.Order, + resultEnumerator.After, + resultEnumerator.Before); + + MessageCollectionPageToken? nextPageToken = pageToken.GetNextPageToken(list.HasMore, list.LastId); + + return PageResult.Create(list.Data, pageToken, nextPageToken, response); + } } From 9c05fc298b008d62226337084ff47bef0951934a Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Mon, 1 Jul 2024 16:17:21 -0700 Subject: [PATCH 37/72] more refining --- .../Assistants/AssistantClient.Protocol.cs | 2 +- src/Custom/Assistants/AssistantClient.cs | 20 +-- .../Internal/PageResultEnumerator.cs | 1 + src/To.Be.Generated/Internal/PageToken.cs | 13 -- .../MessageCollectionClient.cs | 160 ++++++++++-------- .../MessagePageResultEnumerator.cs | 92 ---------- 6 files changed, 100 insertions(+), 188 deletions(-) delete mode 100644 src/To.Be.Generated/Internal/PageToken.cs delete mode 100644 src/To.Be.Generated/MessagePageResultEnumerator.cs diff --git a/src/Custom/Assistants/AssistantClient.Protocol.cs b/src/Custom/Assistants/AssistantClient.Protocol.cs index 7a228690a..feaac2b31 100644 --- a/src/Custom/Assistants/AssistantClient.Protocol.cs +++ b/src/Custom/Assistants/AssistantClient.Protocol.cs @@ -257,7 +257,7 @@ internal virtual async Task GetMessagesPageAsync(string threadId, public virtual IEnumerable GetMessages(string threadId, int? limit, string order, string after, string before, RequestOptions options) { - IEnumerator enumerator = new MessagePageResultEnumerator(_messageSubClient, threadId, limit, order, after, before, options); + IEnumerator enumerator = new MessageCollectionClient(_messageSubClient, threadId, limit, order, after, before, options); return PageCollectionHelpers.CreateProtocol(enumerator); } diff --git a/src/Custom/Assistants/AssistantClient.cs b/src/Custom/Assistants/AssistantClient.cs index 28d8d1f71..4b72fecde 100644 --- a/src/Custom/Assistants/AssistantClient.cs +++ b/src/Custom/Assistants/AssistantClient.cs @@ -425,8 +425,7 @@ public virtual PageCollection GetMessages( { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); - // Call protocol method to get protocol subclient - IEnumerable enumerable = GetMessages( + MessageCollectionClient enumerator = new(_messageSubClient, threadId, options?.PageSize, options?.Order?.ToString(), @@ -434,11 +433,8 @@ public virtual PageCollection GetMessages( options?.BeforeId, cancellationToken.ToRequestOptions()); - // Create convenience subclient - MessagePageResultEnumerator enumerator = (MessagePageResultEnumerator)enumerable.GetEnumerator(); - - // Wrap it in the outer collection - return PageCollectionHelpers.Create(enumerator, result => MessagePageResultEnumerator.GetPageFromResult(enumerator, result)); + return PageCollectionHelpers.Create(enumerator, + result => MessageCollectionClient.GetPageFromResult(enumerator, result)); } public virtual PageCollection GetMessages( @@ -449,8 +445,7 @@ public virtual PageCollection GetMessages( MessageCollectionPageToken pageToken = MessageCollectionPageToken.FromToken(firstPageToken); - // Call protocol method to get protocol subclient - IEnumerable enumerable = GetMessages( + MessageCollectionClient enumerator = new(_messageSubClient, pageToken.ThreadId, pageToken.Limit, pageToken.Order, @@ -458,11 +453,8 @@ public virtual PageCollection GetMessages( pageToken.Before, cancellationToken.ToRequestOptions()); - // Create convenience subclient - MessagePageResultEnumerator enumerator = (MessagePageResultEnumerator)enumerable.GetEnumerator(); - - // Wrap it in the outer collection - return PageCollectionHelpers.Create(enumerator, result => MessagePageResultEnumerator.GetPageFromResult(enumerator, result)); + return PageCollectionHelpers.Create(enumerator, + result => MessageCollectionClient.GetPageFromResult(enumerator, result)); } /// diff --git a/src/To.Be.Generated/Internal/PageResultEnumerator.cs b/src/To.Be.Generated/Internal/PageResultEnumerator.cs index cbbaeeb11..f434548b2 100644 --- a/src/To.Be.Generated/Internal/PageResultEnumerator.cs +++ b/src/To.Be.Generated/Internal/PageResultEnumerator.cs @@ -36,6 +36,7 @@ public bool MoveNext() // Idea is that this is generated on the client public abstract ClientResult GetNext(ClientResult result); + // Idea is that this is generated on the client public abstract bool HasNext(ClientResult result); public virtual void Dispose() { } diff --git a/src/To.Be.Generated/Internal/PageToken.cs b/src/To.Be.Generated/Internal/PageToken.cs deleted file mode 100644 index f82096b15..000000000 --- a/src/To.Be.Generated/Internal/PageToken.cs +++ /dev/null @@ -1,13 +0,0 @@ -//using System; -//using System.ClientModel; -//using System.Collections.Generic; -//using System.Text; - -//#nullable enable - -//namespace OpenAI; - -//internal abstract class PageToken : ContinuationToken -//{ -// public abstract PageToken? GetNextPageToken(); -//} diff --git a/src/To.Be.Generated/MessageCollectionClient.cs b/src/To.Be.Generated/MessageCollectionClient.cs index 1f5d98521..9179586b1 100644 --- a/src/To.Be.Generated/MessageCollectionClient.cs +++ b/src/To.Be.Generated/MessageCollectionClient.cs @@ -1,68 +1,92 @@ -//using System.ClientModel; -//using System.ClientModel.Primitives; -//using System.Text.Json; - -//#nullable enable - -//namespace OpenAI.Assistants; - -//internal class MessageCollectionClient : PageResultEnumerator -//{ -// private readonly InternalAssistantMessageClient _messageSubClient; - -// private readonly string _threadId; -// private readonly int? _limit; -// private readonly string _order; -// private readonly string _after; -// private readonly string _before; -// private readonly RequestOptions _options; - -// public MessageCollectionClient(InternalAssistantMessageClient subclient, string threadId, int? limit, string order, string after, string before, RequestOptions options) -// { -// _threadId = threadId; -// _limit = limit; -// _order = order; -// _after = after; -// _before = before; -// _options = options; - -// _messageSubClient = subclient; -// } - -// public override ClientResult GetFirst() -// => GetMessagesPage(_threadId, _limit, _order, _after, _before, _options); - -// public override ClientResult GetNext(ClientResult result) -// { -// PipelineResponse response = result.GetRawResponse(); - -// using JsonDocument doc = JsonDocument.Parse(response.Content); -// string lastId = doc.RootElement.GetProperty("last_id"u8).GetString()!; - -// return GetMessagesPage(_threadId, _limit, _order, lastId, _before, _options); -// } - -// public override bool HasNext(ClientResult result) -// { -// PipelineResponse response = result.GetRawResponse(); - -// using JsonDocument doc = JsonDocument.Parse(response.Content); -// bool hasMore = doc.RootElement.GetProperty("has_more"u8).GetBoolean(); - -// return hasMore; -// } - -// /// -// internal virtual ClientResult GetMessagesPage(string threadId, int? limit, string order, string after, string before, RequestOptions options) -// => _messageSubClient.GetMessages(threadId, limit, order, after, before, options); - -// //// This could live in a different class -// //public PageResult GetPageFromResult(ClientResult result) -// //{ -// // PipelineResponse response = result.GetRawResponse(); -// // InternalListMessagesResponse list = ModelReaderWriter.Read(response.Content)!; -// // MessageCollectionPageToken pageToken = MessageCollectionPageToken.FromOptions(_threadId, _limit, _order, ) -// // return PageResult.Create(list.Data, pageToken, nextPageToken, response); - -// //} -//} +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Text.Json; + +#nullable enable + +namespace OpenAI.Assistants; + +internal class MessageCollectionClient : PageResultEnumerator +{ + private readonly InternalAssistantMessageClient _messageSubClient; + + private readonly string _threadId; + private readonly int? _limit; + private readonly string _order; + + // Note: this one is special + private string _after; + + private readonly string _before; + private readonly RequestOptions _options; + + public MessageCollectionClient(InternalAssistantMessageClient subclient, string threadId, int? limit, string order, string after, string before, RequestOptions options) + { + _threadId = threadId; + _limit = limit; + _order = order; + _after = after; + _before = before; + _options = options; + + _messageSubClient = subclient; + } + + // TODO: do we need these in so many places? + public string ThreadId => _threadId; + + public int? Limit => _limit; + + public string? Order => _order; + + public string? After => _after; + + public string? Before => _before; + + public override ClientResult GetFirst() + => GetMessagesPage(_threadId, _limit, _order, _after, _before, _options); + + public override ClientResult GetNext(ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + + using JsonDocument doc = JsonDocument.Parse(response.Content); + _after = doc.RootElement.GetProperty("last_id"u8).GetString()!; + + return GetMessagesPage(_threadId, _limit, _order, _after, _before, _options); + } + + public override bool HasNext(ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + + using JsonDocument doc = JsonDocument.Parse(response.Content); + bool hasMore = doc.RootElement.GetProperty("has_more"u8).GetBoolean(); + + return hasMore; + } + + // Note: this is the protocol method + internal virtual ClientResult GetMessagesPage(string threadId, int? limit, string order, string after, string before, RequestOptions options) + => _messageSubClient.GetMessages(threadId, limit, order, after, before, options); + + // Note: this is the static page deserialization method + public static PageResult GetPageFromResult( + MessageCollectionClient resultEnumerator, + ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + InternalListMessagesResponse list = ModelReaderWriter.Read(response.Content)!; + + MessageCollectionPageToken pageToken = MessageCollectionPageToken.FromOptions( + resultEnumerator.ThreadId, + resultEnumerator.Limit, + resultEnumerator.Order, + resultEnumerator.After, + resultEnumerator.Before); + + MessageCollectionPageToken? nextPageToken = pageToken.GetNextPageToken(list.HasMore, list.LastId); + + return PageResult.Create(list.Data, pageToken, nextPageToken, response); + } +} diff --git a/src/To.Be.Generated/MessagePageResultEnumerator.cs b/src/To.Be.Generated/MessagePageResultEnumerator.cs deleted file mode 100644 index d219fb84a..000000000 --- a/src/To.Be.Generated/MessagePageResultEnumerator.cs +++ /dev/null @@ -1,92 +0,0 @@ -using System.ClientModel; -using System.ClientModel.Primitives; -using System.Text.Json; - -#nullable enable - -namespace OpenAI.Assistants; - -internal class MessagePageResultEnumerator : PageResultEnumerator -{ - private readonly InternalAssistantMessageClient _messageSubClient; - - private readonly string _threadId; - private readonly int? _limit; - private readonly string _order; - - // Note: this one is special - private string _after; - - private readonly string _before; - private readonly RequestOptions _options; - - public MessagePageResultEnumerator(InternalAssistantMessageClient subclient, string threadId, int? limit, string order, string after, string before, RequestOptions options) - { - _threadId = threadId; - _limit = limit; - _order = order; - _after = after; - _before = before; - _options = options; - - _messageSubClient = subclient; - } - - // TODO: do we need these in so many places? - public string ThreadId => _threadId; - - public int? Limit => _limit; - - public string? Order => _order; - - public string? After => _after; - - public string? Before => _before; - - public override ClientResult GetFirst() - => GetMessagesPage(_threadId, _limit, _order, _after, _before, _options); - - public override ClientResult GetNext(ClientResult result) - { - PipelineResponse response = result.GetRawResponse(); - - using JsonDocument doc = JsonDocument.Parse(response.Content); - _after = doc.RootElement.GetProperty("last_id"u8).GetString()!; - - return GetMessagesPage(_threadId, _limit, _order, _after, _before, _options); - } - - public override bool HasNext(ClientResult result) - { - PipelineResponse response = result.GetRawResponse(); - - using JsonDocument doc = JsonDocument.Parse(response.Content); - bool hasMore = doc.RootElement.GetProperty("has_more"u8).GetBoolean(); - - return hasMore; - } - - // Note: this is the protocol method - internal virtual ClientResult GetMessagesPage(string threadId, int? limit, string order, string after, string before, RequestOptions options) - => _messageSubClient.GetMessages(threadId, limit, order, after, before, options); - - // Note: this is the static page deserialization method - public static PageResult GetPageFromResult( - MessagePageResultEnumerator resultEnumerator, - ClientResult result) - { - PipelineResponse response = result.GetRawResponse(); - InternalListMessagesResponse list = ModelReaderWriter.Read(response.Content)!; - - MessageCollectionPageToken pageToken = MessageCollectionPageToken.FromOptions( - resultEnumerator.ThreadId, - resultEnumerator.Limit, - resultEnumerator.Order, - resultEnumerator.After, - resultEnumerator.Before); - - MessageCollectionPageToken? nextPageToken = pageToken.GetNextPageToken(list.HasMore, list.LastId); - - return PageResult.Create(list.Data, pageToken, nextPageToken, response); - } -} From 209b71d9ac8a50c4d3e9bbfb5e5f868f1ef37a47 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Mon, 1 Jul 2024 16:23:32 -0700 Subject: [PATCH 38/72] implement interface explicitly --- src/To.Be.Generated/Internal/PageCollectionHelpers.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/To.Be.Generated/Internal/PageCollectionHelpers.cs b/src/To.Be.Generated/Internal/PageCollectionHelpers.cs index a0389d188..c36be5ed5 100644 --- a/src/To.Be.Generated/Internal/PageCollectionHelpers.cs +++ b/src/To.Be.Generated/Internal/PageCollectionHelpers.cs @@ -34,7 +34,7 @@ public FuncPageCollection( _getPageFromResult = getPageFromResult; } - public override IEnumerator> GetEnumerator() + protected override IEnumerator> GetEnumeratorCore() { while (_enumerator.MoveNext()) { From b0d5f04d7ce96d502da515328f0e4426e1d78236 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Mon, 1 Jul 2024 16:28:06 -0700 Subject: [PATCH 39/72] more tidy --- .../Common/OpenAIPageCollectionHelpers.cs | 119 ---------------- src/Custom/Common/OpenAIPageToken.cs | 127 ------------------ 2 files changed, 246 deletions(-) delete mode 100644 src/Custom/Common/OpenAIPageCollectionHelpers.cs delete mode 100644 src/Custom/Common/OpenAIPageToken.cs diff --git a/src/Custom/Common/OpenAIPageCollectionHelpers.cs b/src/Custom/Common/OpenAIPageCollectionHelpers.cs deleted file mode 100644 index 242eb5892..000000000 --- a/src/Custom/Common/OpenAIPageCollectionHelpers.cs +++ /dev/null @@ -1,119 +0,0 @@ -//using System; -//using System.ClientModel; -//using System.ClientModel.Primitives; -//using System.Collections.Generic; -//using System.Text.Json; -//using System.Threading.Tasks; -//using OpenAI.Utility; - -//#nullable enable - -//namespace OpenAI; - -//internal class OpenAIPageCollectionHelpers -//{ -// public delegate Task GetPageResultAsync(OpenAIPageToken pageToken, RequestOptions? options); -// public delegate ClientResult GetPageResult(OpenAIPageToken pageToken, RequestOptions? options); - -// public static AsyncPageCollection CreateAsync( -// ContinuationToken firstPageToken, -// GetPageResultAsync getPageResultAsync, -// Func getToken, -// RequestOptions? options) -// where TValue : notnull -// where TList : IJsonModel, IInternalListResponse -// { -// async Task> getPageAsync(ContinuationToken pageToken) -// { -// OpenAIPageToken token = getToken(pageToken); - -// ClientResult result = await getPageResultAsync(token, options).ConfigureAwait(false); - -// PipelineResponse response = result.GetRawResponse(); -// IInternalListResponse list = ModelReaderWriter.Read(response.Content)!; -// OpenAIPageToken? nextPageToken = token.GetNextPageToken(list.HasMore, list.LastId); - -// return PageResult.Create(list.Data, pageToken, nextPageToken, response); -// } - -// return PageCollectionHelpers.CreateAsync(firstPageToken, getPageAsync); -// } - -// public static PageCollection Create( -// ContinuationToken firstPageToken, -// GetPageResult getPageResult, -// Func getToken, -// RequestOptions? options) -// where TValue : notnull -// where TList : IJsonModel, IInternalListResponse -// { -// PageResult getPage(ContinuationToken pageToken) -// { -// OpenAIPageToken token = getToken(pageToken); - -// ClientResult result = getPageResult(token, options); - -// PipelineResponse response = result.GetRawResponse(); -// IInternalListResponse list = ModelReaderWriter.Read(response.Content)!; -// OpenAIPageToken? nextPageToken = token.GetNextPageToken(list.HasMore, list.LastId); - -// return PageResult.Create(list.Data, pageToken, nextPageToken, response); -// } - -// return PageCollectionHelpers.Create(firstPageToken, getPage); -// } - -// public static IAsyncEnumerable CreateProtocolAsync( -// ContinuationToken firstPageToken, -// GetPageResultAsync getPageResultAsync, -// Func getToken, -// RequestOptions? options) -// { -// async Task getPageAsync(ContinuationToken pageToken) -// { -// OpenAIPageToken token = getToken(pageToken); -// return await getPageResultAsync(token, options).ConfigureAwait(false); -// } - -// ContinuationToken? getNextPageToken(ContinuationToken pageToken, ClientResult result) -// { -// PipelineResponse response = result.GetRawResponse(); - -// using JsonDocument doc = JsonDocument.Parse(response.Content); -// bool hasMore = doc.RootElement.GetProperty("has_more"u8).GetBoolean(); -// string lastId = doc.RootElement.GetProperty("last_id"u8).GetString()!; - -// OpenAIPageToken token = getToken(pageToken); -// return token.GetNextPageToken(hasMore, lastId); -// } - -// return PageCollectionHelpers.CreatePrototolAsync(firstPageToken, getPageAsync, getNextPageToken); -// } - -// public static IEnumerable CreateProtocol( -// ContinuationToken firstPageToken, -// GetPageResult getPageResult, -// Func getToken, -// RequestOptions? options) -// { -// ClientResult getPage(ContinuationToken pageToken) -// { -// OpenAIPageToken token = (OpenAIPageToken)pageToken; -// return getPageResult(token, options); -// } - -// ContinuationToken? getNextPageToken(ContinuationToken pageToken, ClientResult result) -// { -// PipelineResponse response = result.GetRawResponse(); - -// using JsonDocument doc = JsonDocument.Parse(response.Content); -// bool hasMore = doc.RootElement.GetProperty("has_more"u8).GetBoolean(); -// string lastId = doc.RootElement.GetProperty("last_id"u8).GetString()!; - -// OpenAIPageToken token = getToken(pageToken); -// return token.GetNextPageToken(hasMore, lastId); -// } - -// return PageCollectionHelpers.CreatePrototol(firstPageToken, getPage, getNextPageToken); -// } -//} \ No newline at end of file diff --git a/src/Custom/Common/OpenAIPageToken.cs b/src/Custom/Common/OpenAIPageToken.cs deleted file mode 100644 index c678355c0..000000000 --- a/src/Custom/Common/OpenAIPageToken.cs +++ /dev/null @@ -1,127 +0,0 @@ -using System; -using System.ClientModel; -using System.IO; -using System.Text.Json; - -#nullable enable - -namespace OpenAI; - -internal abstract class OpenAIPageToken : ContinuationToken -{ - public OpenAIPageToken(int? limit, string? order, string? after, string? before) - { - Limit = limit; - Order = order; - After = after; - Before = before; - } - - public int? Limit { get; } - - public string? Order { get; } - - public string? After { get; } - - public string? Before { get; } - - //public override BinaryData ToBytes() - //{ - // using MemoryStream stream = new(); - // using Utf8JsonWriter writer = new(stream); - - // writer.WriteStartObject(); - - // if (Limit.HasValue) - // { - // writer.WriteNumber("limit", Limit.Value); - // } - - // if (Order is not null) - // { - // writer.WriteString("order", Order); - // } - - // if (After is not null) - // { - // writer.WriteString("after", After); - // } - - // if (Before is not null) - // { - // writer.WriteString("before", Before); - // } - - // writer.WriteEndObject(); - - // writer.Flush(); - // stream.Position = 0; - // return BinaryData.FromStream(stream); - //} - - public abstract OpenAIPageToken? GetNextPageToken(bool hasMore, string? lastId); - - //public static OpenAIPageToken FromToken(ContinuationToken token) - //{ - // if (token is OpenAIPageToken openAIPageToken) - // { - // return openAIPageToken; - // } - - // BinaryData data = token.ToBytes(); - - // if (data.ToMemory().Length == 0) - // { - // return new(default, default, default, default); - // } - - // Utf8JsonReader reader = new(data); - - // int? limit = null; - // string? order = null; - // string? after = null; - // string? before = null; - - // reader.Read(); - // Debug.Assert(reader.TokenType == JsonTokenType.StartObject); - - // while (reader.Read()) - // { - // if (reader.TokenType == JsonTokenType.EndObject) - // { - // break; - // } - - // Debug.Assert(reader.TokenType == JsonTokenType.PropertyName); - // string propertyName = reader.GetString()!; - - // switch (propertyName) - // { - // case "limit": - // reader.Read(); - // Debug.Assert(reader.TokenType == JsonTokenType.Number); - // limit = reader.GetInt32(); - // break; - // case "order": - // reader.Read(); - // Debug.Assert(reader.TokenType == JsonTokenType.String); - // order = reader.GetString(); - // break; - // case "after": - // reader.Read(); - // Debug.Assert(reader.TokenType == JsonTokenType.String); - // after = reader.GetString(); - // break; - // case "before": - // reader.Read(); - // Debug.Assert(reader.TokenType == JsonTokenType.String); - // before = reader.GetString(); - // break; - // default: - // throw new JsonException($"Unrecognized property '{propertyName}'."); - // } - // } - - // return new(limit, order, after, before); - //} -} \ No newline at end of file From c5b568de06778eaa53cbaaefbcff13db4d0bcbde Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Mon, 1 Jul 2024 16:45:17 -0700 Subject: [PATCH 40/72] Make it work for async --- .../Assistants/AssistantClient.Protocol.cs | 14 ++------ src/Custom/Assistants/AssistantClient.cs | 28 ++++++++++----- .../Internal/PageCollectionHelpers.cs | 36 +++++++++++++++++++ .../Internal/PageResultEnumerator.cs | 33 ++++++++++++++++- .../MessageCollectionClient.cs | 21 +++++++++-- 5 files changed, 108 insertions(+), 24 deletions(-) diff --git a/src/Custom/Assistants/AssistantClient.Protocol.cs b/src/Custom/Assistants/AssistantClient.Protocol.cs index feaac2b31..fffff22e1 100644 --- a/src/Custom/Assistants/AssistantClient.Protocol.cs +++ b/src/Custom/Assistants/AssistantClient.Protocol.cs @@ -241,20 +241,10 @@ public virtual ClientResult CreateMessage(string threadId, BinaryContent content public virtual IAsyncEnumerable GetMessagesAsync(string threadId, int? limit, string order, string after, string before, RequestOptions options) { - MessageCollectionPageToken firstPageToken = MessageCollectionPageToken.FromOptions(threadId, limit, order, after, before); - return OpenAIPageCollectionHelpers.CreateProtocolAsync(firstPageToken, GetMessagesPageAsync, MessageCollectionPageToken.FromToken, options); + IAsyncEnumerator enumerator = new MessageCollectionClient(_messageSubClient, threadId, limit, order, after, before, options); + return PageCollectionHelpers.CreateProtocolAsync(enumerator); } - internal virtual async Task GetMessagesPageAsync(ContinuationToken pageToken, RequestOptions options) - { - MessageCollectionPageToken token = MessageCollectionPageToken.FromToken(pageToken); - return await GetMessagesPageAsync(token.ThreadId, token.Limit, token.Order, token.After, token.Before, options).ConfigureAwait(false); - } - - /// - internal virtual async Task GetMessagesPageAsync(string threadId, int? limit, string order, string after, string before, RequestOptions options) - => await _messageSubClient.GetMessagesAsync(threadId, limit, order, after, before, options).ConfigureAwait(false); - public virtual IEnumerable GetMessages(string threadId, int? limit, string order, string after, string before, RequestOptions options) { IEnumerator enumerator = new MessageCollectionClient(_messageSubClient, threadId, limit, order, after, before, options); diff --git a/src/Custom/Assistants/AssistantClient.cs b/src/Custom/Assistants/AssistantClient.cs index 4b72fecde..72b423322 100644 --- a/src/Custom/Assistants/AssistantClient.cs +++ b/src/Custom/Assistants/AssistantClient.cs @@ -391,12 +391,16 @@ public virtual AsyncPageCollection GetMessagesAsync( { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); - MessageCollectionPageToken firstPageToken = MessageCollectionPageToken.FromOptions(threadId, options); - return OpenAIPageCollectionHelpers.CreateAsync( - firstPageToken, - GetMessagesPageAsync, - MessageCollectionPageToken.FromToken, + MessageCollectionClient enumerator = new(_messageSubClient, + threadId, + options?.PageSize, + options?.Order?.ToString(), + options?.AfterId, + options?.BeforeId, cancellationToken.ToRequestOptions()); + + return PageCollectionHelpers.CreateAsync(enumerator, + result => MessageCollectionClient.GetPageFromResult(enumerator, result)); } public virtual AsyncPageCollection GetMessagesAsync( @@ -404,11 +408,17 @@ public virtual AsyncPageCollection GetMessagesAsync( CancellationToken cancellationToken = default) { MessageCollectionPageToken pageToken = MessageCollectionPageToken.FromToken(firstPageToken); - return OpenAIPageCollectionHelpers.CreateAsync( - firstPageToken, - GetMessagesPageAsync, - MessageCollectionPageToken.FromToken, + + MessageCollectionClient enumerator = new(_messageSubClient, + pageToken.ThreadId, + pageToken.Limit, + pageToken.Order, + pageToken.After, + pageToken.Before, cancellationToken.ToRequestOptions()); + + return PageCollectionHelpers.CreateAsync(enumerator, + result => MessageCollectionClient.GetPageFromResult(enumerator, result)); } /// diff --git a/src/To.Be.Generated/Internal/PageCollectionHelpers.cs b/src/To.Be.Generated/Internal/PageCollectionHelpers.cs index c36be5ed5..2abdfd72d 100644 --- a/src/To.Be.Generated/Internal/PageCollectionHelpers.cs +++ b/src/To.Be.Generated/Internal/PageCollectionHelpers.cs @@ -1,6 +1,7 @@ using System; using System.ClientModel; using System.Collections.Generic; +using System.Threading; #nullable enable @@ -8,6 +9,11 @@ namespace OpenAI.Utility; internal class PageCollectionHelpers { + public static AsyncPageCollection CreateAsync( + IAsyncEnumerator enumerator, + Func> getPageFromResult) + => new AsyncFuncPageCollection(enumerator, getPageFromResult); + public static PageCollection Create( IEnumerator enumerator, Func> getPageFromResult) @@ -21,6 +27,36 @@ public static IEnumerable CreateProtocol(IEnumerator } } + public static async IAsyncEnumerable CreateProtocolAsync(IAsyncEnumerator enumerator) + { + while (await enumerator.MoveNextAsync().ConfigureAwait(false)) + { + yield return enumerator.Current; + } + } + + private class AsyncFuncPageCollection : AsyncPageCollection + { + private readonly IAsyncEnumerator _enumerator; + private readonly Func> _getPageFromResult; + + public AsyncFuncPageCollection( + IAsyncEnumerator enumerator, + Func> getPageFromResult) + { + _enumerator = enumerator; + _getPageFromResult = getPageFromResult; + } + + protected override async IAsyncEnumerator> GetAsyncEnumeratorCore(CancellationToken cancellationToken = default) + { + while (await _enumerator.MoveNextAsync().ConfigureAwait(false)) + { + yield return _getPageFromResult(_enumerator.Current); + } + } + } + private class FuncPageCollection : PageCollection { private readonly IEnumerator _enumerator; diff --git a/src/To.Be.Generated/Internal/PageResultEnumerator.cs b/src/To.Be.Generated/Internal/PageResultEnumerator.cs index f434548b2..aa8b3936d 100644 --- a/src/To.Be.Generated/Internal/PageResultEnumerator.cs +++ b/src/To.Be.Generated/Internal/PageResultEnumerator.cs @@ -1,12 +1,15 @@ using System.ClientModel; using System.Collections; using System.Collections.Generic; +using System.Threading.Tasks; #nullable enable namespace OpenAI; -internal abstract class PageResultEnumerator : IEnumerator +// Note: implements both sync and async enumerator interfaces. +internal abstract class PageResultEnumerator : IEnumerator, + IAsyncEnumerator { private ClientResult? _current; @@ -14,6 +17,8 @@ internal abstract class PageResultEnumerator : IEnumerator object IEnumerator.Current => Current; + #region IEnumerable implementation + public bool MoveNext() { if (_current == null) @@ -40,4 +45,30 @@ public bool MoveNext() public abstract bool HasNext(ClientResult result); public virtual void Dispose() { } + #endregion + + #region IAsyncEnumerable implementation + + public async ValueTask MoveNextAsync() + { + if (_current == null) + { + _current = await GetFirstAsync().ConfigureAwait(false); + } + else + { + _current = await GetNextAsync(_current).ConfigureAwait(false); + } + + return HasNext(_current); + } + + // Idea is that this is generated on the client + public abstract Task GetFirstAsync(); + + // Idea is that this is generated on the client + public abstract Task GetNextAsync(ClientResult result); + + public virtual ValueTask DisposeAsync() => new(); + #endregion } \ No newline at end of file diff --git a/src/To.Be.Generated/MessageCollectionClient.cs b/src/To.Be.Generated/MessageCollectionClient.cs index 9179586b1..8c0b946ea 100644 --- a/src/To.Be.Generated/MessageCollectionClient.cs +++ b/src/To.Be.Generated/MessageCollectionClient.cs @@ -1,6 +1,7 @@ using System.ClientModel; using System.ClientModel.Primitives; using System.Text.Json; +using System.Threading.Tasks; #nullable enable @@ -43,9 +44,22 @@ public MessageCollectionClient(InternalAssistantMessageClient subclient, string public string? Before => _before; + public override async Task GetFirstAsync() + => await GetMessagesPageAsync(_threadId, _limit, _order, _after, _before, _options).ConfigureAwait(false); + public override ClientResult GetFirst() => GetMessagesPage(_threadId, _limit, _order, _after, _before, _options); + public override async Task GetNextAsync(ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + + using JsonDocument doc = JsonDocument.Parse(response.Content); + _after = doc.RootElement.GetProperty("last_id"u8).GetString()!; + + return await GetMessagesPageAsync(_threadId, _limit, _order, _after, _before, _options).ConfigureAwait(false); + } + public override ClientResult GetNext(ClientResult result) { PipelineResponse response = result.GetRawResponse(); @@ -65,8 +79,11 @@ public override bool HasNext(ClientResult result) return hasMore; } - - // Note: this is the protocol method + + // Note: these are the protocol methods - they are generated here + internal virtual async Task GetMessagesPageAsync(string threadId, int? limit, string order, string after, string before, RequestOptions options) + => await _messageSubClient.GetMessagesAsync(threadId, limit, order, after, before, options).ConfigureAwait(false); + internal virtual ClientResult GetMessagesPage(string threadId, int? limit, string order, string after, string before, RequestOptions options) => _messageSubClient.GetMessages(threadId, limit, order, after, before, options); From e07fb0b05af257297f3b5891d53991b439084666 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Mon, 1 Jul 2024 17:11:59 -0700 Subject: [PATCH 41/72] restructure to look more like mini-client --- .../Assistants/AssistantClient.Protocol.cs | 5 +- src/Custom/Assistants/AssistantClient.cs | 5 +- .../Internal/PageCollectionHelpers.cs | 2 +- .../Internal/PageResultEnumerator.cs | 43 +++++----- .../MessageCollectionClient.cs | 80 ++++++++++++++++--- .../MessageCollectionPageToken.cs | 6 +- 6 files changed, 97 insertions(+), 44 deletions(-) diff --git a/src/Custom/Assistants/AssistantClient.Protocol.cs b/src/Custom/Assistants/AssistantClient.Protocol.cs index fffff22e1..a3964439e 100644 --- a/src/Custom/Assistants/AssistantClient.Protocol.cs +++ b/src/Custom/Assistants/AssistantClient.Protocol.cs @@ -1,4 +1,3 @@ -using OpenAI.Utility; using System; using System.ClientModel; using System.ClientModel.Primitives; @@ -241,13 +240,13 @@ public virtual ClientResult CreateMessage(string threadId, BinaryContent content public virtual IAsyncEnumerable GetMessagesAsync(string threadId, int? limit, string order, string after, string before, RequestOptions options) { - IAsyncEnumerator enumerator = new MessageCollectionClient(_messageSubClient, threadId, limit, order, after, before, options); + IAsyncEnumerator enumerator = new MessageCollectionClient(_pipeline, _endpoint, threadId, limit, order, after, before, options); return PageCollectionHelpers.CreateProtocolAsync(enumerator); } public virtual IEnumerable GetMessages(string threadId, int? limit, string order, string after, string before, RequestOptions options) { - IEnumerator enumerator = new MessageCollectionClient(_messageSubClient, threadId, limit, order, after, before, options); + IEnumerator enumerator = new MessageCollectionClient(_pipeline, _endpoint, threadId, limit, order, after, before, options); return PageCollectionHelpers.CreateProtocol(enumerator); } diff --git a/src/Custom/Assistants/AssistantClient.cs b/src/Custom/Assistants/AssistantClient.cs index 72b423322..1f58b6b34 100644 --- a/src/Custom/Assistants/AssistantClient.cs +++ b/src/Custom/Assistants/AssistantClient.cs @@ -1,4 +1,3 @@ -using OpenAI.Utility; using System; using System.ClientModel; using System.ClientModel.Primitives; @@ -435,7 +434,7 @@ public virtual PageCollection GetMessages( { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); - MessageCollectionClient enumerator = new(_messageSubClient, + MessageCollectionClient enumerator = new(_pipeline, _endpoint, threadId, options?.PageSize, options?.Order?.ToString(), @@ -455,7 +454,7 @@ public virtual PageCollection GetMessages( MessageCollectionPageToken pageToken = MessageCollectionPageToken.FromToken(firstPageToken); - MessageCollectionClient enumerator = new(_messageSubClient, + MessageCollectionClient enumerator = new(_pipeline, _endpoint, pageToken.ThreadId, pageToken.Limit, pageToken.Order, diff --git a/src/To.Be.Generated/Internal/PageCollectionHelpers.cs b/src/To.Be.Generated/Internal/PageCollectionHelpers.cs index 2abdfd72d..e81bbd4da 100644 --- a/src/To.Be.Generated/Internal/PageCollectionHelpers.cs +++ b/src/To.Be.Generated/Internal/PageCollectionHelpers.cs @@ -5,7 +5,7 @@ #nullable enable -namespace OpenAI.Utility; +namespace OpenAI; internal class PageCollectionHelpers { diff --git a/src/To.Be.Generated/Internal/PageResultEnumerator.cs b/src/To.Be.Generated/Internal/PageResultEnumerator.cs index aa8b3936d..573fb952f 100644 --- a/src/To.Be.Generated/Internal/PageResultEnumerator.cs +++ b/src/To.Be.Generated/Internal/PageResultEnumerator.cs @@ -8,16 +8,32 @@ namespace OpenAI; // Note: implements both sync and async enumerator interfaces. -internal abstract class PageResultEnumerator : IEnumerator, - IAsyncEnumerator +internal abstract class PageResultEnumerator : IAsyncEnumerator, IEnumerator { private ClientResult? _current; + protected PageResultEnumerator() { } + public ClientResult Current => _current!; - object IEnumerator.Current => Current; + // Idea is that this is generated on the client + public abstract Task GetFirstAsync(); + + // Idea is that this is generated on the client + public abstract Task GetNextAsync(ClientResult result); + + // Idea is that this is generated on the client + public abstract ClientResult GetFirst(); - #region IEnumerable implementation + // Idea is that this is generated on the client + public abstract ClientResult GetNext(ClientResult result); + + // Idea is that this is generated on the client + public abstract bool HasNext(ClientResult result); + + #region IEnumerator implementation + + object IEnumerator.Current => Current; public bool MoveNext() { @@ -35,19 +51,11 @@ public bool MoveNext() public void Reset() => _current = null; - // Idea is that this is generated on the client - public abstract ClientResult GetFirst(); - - // Idea is that this is generated on the client - public abstract ClientResult GetNext(ClientResult result); - - // Idea is that this is generated on the client - public abstract bool HasNext(ClientResult result); - public virtual void Dispose() { } + #endregion - #region IAsyncEnumerable implementation + #region IAsyncEnumerator implementation public async ValueTask MoveNextAsync() { @@ -63,12 +71,7 @@ public async ValueTask MoveNextAsync() return HasNext(_current); } - // Idea is that this is generated on the client - public abstract Task GetFirstAsync(); - - // Idea is that this is generated on the client - public abstract Task GetNextAsync(ClientResult result); - public virtual ValueTask DisposeAsync() => new(); + #endregion } \ No newline at end of file diff --git a/src/To.Be.Generated/MessageCollectionClient.cs b/src/To.Be.Generated/MessageCollectionClient.cs index 8c0b946ea..608430a7c 100644 --- a/src/To.Be.Generated/MessageCollectionClient.cs +++ b/src/To.Be.Generated/MessageCollectionClient.cs @@ -1,6 +1,9 @@ -using System.ClientModel; +using System; +using System.ClientModel; using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; +using System.Threading; using System.Threading.Tasks; #nullable enable @@ -9,7 +12,8 @@ namespace OpenAI.Assistants; internal class MessageCollectionClient : PageResultEnumerator { - private readonly InternalAssistantMessageClient _messageSubClient; + private readonly ClientPipeline _pipeline; + private readonly Uri _endpoint; private readonly string _threadId; private readonly int? _limit; @@ -21,16 +25,21 @@ internal class MessageCollectionClient : PageResultEnumerator private readonly string _before; private readonly RequestOptions _options; - public MessageCollectionClient(InternalAssistantMessageClient subclient, string threadId, int? limit, string order, string after, string before, RequestOptions options) + public MessageCollectionClient( + ClientPipeline pipeline, + Uri endpoint, + string threadId, int? limit, string order, string after, string before, + RequestOptions options) { + _pipeline = pipeline; + _endpoint = endpoint; + _threadId = threadId; _limit = limit; _order = order; _after = after; _before = before; _options = options; - - _messageSubClient = subclient; } // TODO: do we need these in so many places? @@ -80,13 +89,6 @@ public override bool HasNext(ClientResult result) return hasMore; } - // Note: these are the protocol methods - they are generated here - internal virtual async Task GetMessagesPageAsync(string threadId, int? limit, string order, string after, string before, RequestOptions options) - => await _messageSubClient.GetMessagesAsync(threadId, limit, order, after, before, options).ConfigureAwait(false); - - internal virtual ClientResult GetMessagesPage(string threadId, int? limit, string order, string after, string before, RequestOptions options) - => _messageSubClient.GetMessages(threadId, limit, order, after, before, options); - // Note: this is the static page deserialization method public static PageResult GetPageFromResult( MessageCollectionClient resultEnumerator, @@ -106,4 +108,58 @@ public static PageResult GetPageFromResult( return PageResult.Create(list.Data, pageToken, nextPageToken, response); } + + // Note: these are the protocol methods - they are generated here + public virtual async Task GetMessagesPageAsync(string threadId, int? limit, string order, string after, string before, RequestOptions options) + { + Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); + + using PipelineMessage message = CreateGetMessagesRequest(threadId, limit, order, after, before, options); + return ClientResult.FromResponse(await _pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); + } + + public virtual ClientResult GetMessagesPage(string threadId, int? limit, string order, string after, string before, RequestOptions options) + { + Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); + + using PipelineMessage message = CreateGetMessagesRequest(threadId, limit, order, after, before, options); + return ClientResult.FromResponse(_pipeline.ProcessMessage(message, options)); + } + + internal PipelineMessage CreateGetMessagesRequest(string threadId, int? limit, string order, string after, string before, RequestOptions options) + { + var message = _pipeline.CreateMessage(); + message.ResponseClassifier = PipelineMessageClassifier200; + var request = message.Request; + request.Method = "GET"; + var uri = new ClientUriBuilder(); + uri.Reset(_endpoint); + uri.AppendPath("/threads/", false); + uri.AppendPath(threadId, true); + uri.AppendPath("/messages", false); + if (limit != null) + { + uri.AppendQuery("limit", limit.Value, true); + } + if (order != null) + { + uri.AppendQuery("order", order, true); + } + if (after != null) + { + uri.AppendQuery("after", after, true); + } + if (before != null) + { + uri.AppendQuery("before", before, true); + } + request.Uri = uri.ToUri(); + request.Headers.Set("Accept", "application/json"); + message.Apply(options); + return message; + } + + private static PipelineMessageClassifier? _pipelineMessageClassifier200; + private static PipelineMessageClassifier PipelineMessageClassifier200 => _pipelineMessageClassifier200 ??= PipelineMessageClassifier.Create(stackalloc ushort[] { 200 }); + } diff --git a/src/To.Be.Generated/MessageCollectionPageToken.cs b/src/To.Be.Generated/MessageCollectionPageToken.cs index 914cff7a7..1dbc07bcc 100644 --- a/src/To.Be.Generated/MessageCollectionPageToken.cs +++ b/src/To.Be.Generated/MessageCollectionPageToken.cs @@ -69,10 +69,6 @@ public override BinaryData ToBytes() public MessageCollectionPageToken? GetNextPageToken(bool hasMore, string? lastId) => GetNextPageToken(ThreadId, Limit, Order, lastId, Before, hasMore); - // Convenience - first page request - public static MessageCollectionPageToken FromOptions(string threadId, MessageCollectionOptions options) - => new(threadId, options?.PageSize, options?.Order?.ToString(), options?.AfterId, options?.BeforeId); - // Convenience - continuation page request public static MessageCollectionPageToken FromToken(ContinuationToken pageToken) { @@ -149,7 +145,7 @@ public static MessageCollectionPageToken FromToken(ContinuationToken pageToken) return new(threadId, limit, order, after, before); } - // Protocol + // Protocol - called from subclient public static MessageCollectionPageToken FromOptions(string threadId, int? limit, string? order, string? after, string? before) => new MessageCollectionPageToken(threadId, limit, order, after, before); From f3c5e961a53f89a2a5214dd3f03ea248a28f4f3d Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Mon, 1 Jul 2024 17:22:03 -0700 Subject: [PATCH 42/72] simplify --- src/Custom/Assistants/AssistantClient.cs | 16 ++++----- .../MessageCollectionClient.cs | 35 ++++--------------- 2 files changed, 13 insertions(+), 38 deletions(-) diff --git a/src/Custom/Assistants/AssistantClient.cs b/src/Custom/Assistants/AssistantClient.cs index 1f58b6b34..d2027d923 100644 --- a/src/Custom/Assistants/AssistantClient.cs +++ b/src/Custom/Assistants/AssistantClient.cs @@ -390,7 +390,7 @@ public virtual AsyncPageCollection GetMessagesAsync( { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); - MessageCollectionClient enumerator = new(_messageSubClient, + MessageCollectionClient enumerator = new(_pipeline, _endpoint, threadId, options?.PageSize, options?.Order?.ToString(), @@ -398,8 +398,7 @@ public virtual AsyncPageCollection GetMessagesAsync( options?.BeforeId, cancellationToken.ToRequestOptions()); - return PageCollectionHelpers.CreateAsync(enumerator, - result => MessageCollectionClient.GetPageFromResult(enumerator, result)); + return PageCollectionHelpers.CreateAsync(enumerator, enumerator.GetPageFromResult); } public virtual AsyncPageCollection GetMessagesAsync( @@ -408,7 +407,7 @@ public virtual AsyncPageCollection GetMessagesAsync( { MessageCollectionPageToken pageToken = MessageCollectionPageToken.FromToken(firstPageToken); - MessageCollectionClient enumerator = new(_messageSubClient, + MessageCollectionClient enumerator = new(_pipeline, _endpoint, pageToken.ThreadId, pageToken.Limit, pageToken.Order, @@ -416,8 +415,7 @@ public virtual AsyncPageCollection GetMessagesAsync( pageToken.Before, cancellationToken.ToRequestOptions()); - return PageCollectionHelpers.CreateAsync(enumerator, - result => MessageCollectionClient.GetPageFromResult(enumerator, result)); + return PageCollectionHelpers.CreateAsync(enumerator, enumerator.GetPageFromResult); } /// @@ -442,8 +440,7 @@ public virtual PageCollection GetMessages( options?.BeforeId, cancellationToken.ToRequestOptions()); - return PageCollectionHelpers.Create(enumerator, - result => MessageCollectionClient.GetPageFromResult(enumerator, result)); + return PageCollectionHelpers.Create(enumerator, enumerator.GetPageFromResult); } public virtual PageCollection GetMessages( @@ -462,8 +459,7 @@ public virtual PageCollection GetMessages( pageToken.Before, cancellationToken.ToRequestOptions()); - return PageCollectionHelpers.Create(enumerator, - result => MessageCollectionClient.GetPageFromResult(enumerator, result)); + return PageCollectionHelpers.Create(enumerator, enumerator.GetPageFromResult); } /// diff --git a/src/To.Be.Generated/MessageCollectionClient.cs b/src/To.Be.Generated/MessageCollectionClient.cs index 608430a7c..823ab7773 100644 --- a/src/To.Be.Generated/MessageCollectionClient.cs +++ b/src/To.Be.Generated/MessageCollectionClient.cs @@ -1,9 +1,7 @@ using System; using System.ClientModel; using System.ClientModel.Primitives; -using System.Collections.Generic; using System.Text.Json; -using System.Threading; using System.Threading.Tasks; #nullable enable @@ -12,7 +10,7 @@ namespace OpenAI.Assistants; internal class MessageCollectionClient : PageResultEnumerator { - private readonly ClientPipeline _pipeline; + private readonly ClientPipeline _pipeline; private readonly Uri _endpoint; private readonly string _threadId; @@ -27,7 +25,7 @@ internal class MessageCollectionClient : PageResultEnumerator public MessageCollectionClient( ClientPipeline pipeline, - Uri endpoint, + Uri endpoint, string threadId, int? limit, string order, string after, string before, RequestOptions options) { @@ -42,17 +40,6 @@ public MessageCollectionClient( _options = options; } - // TODO: do we need these in so many places? - public string ThreadId => _threadId; - - public int? Limit => _limit; - - public string? Order => _order; - - public string? After => _after; - - public string? Before => _before; - public override async Task GetFirstAsync() => await GetMessagesPageAsync(_threadId, _limit, _order, _after, _before, _options).ConfigureAwait(false); @@ -89,21 +76,14 @@ public override bool HasNext(ClientResult result) return hasMore; } - // Note: this is the static page deserialization method - public static PageResult GetPageFromResult( - MessageCollectionClient resultEnumerator, - ClientResult result) + // Note: this is the deserialization method that converts protocol to convenience + public PageResult GetPageFromResult(ClientResult result) { PipelineResponse response = result.GetRawResponse(); - InternalListMessagesResponse list = ModelReaderWriter.Read(response.Content)!; - MessageCollectionPageToken pageToken = MessageCollectionPageToken.FromOptions( - resultEnumerator.ThreadId, - resultEnumerator.Limit, - resultEnumerator.Order, - resultEnumerator.After, - resultEnumerator.Before); + InternalListMessagesResponse list = ModelReaderWriter.Read(response.Content)!; + MessageCollectionPageToken pageToken = MessageCollectionPageToken.FromOptions(_threadId, _limit, _order, _after, _before); MessageCollectionPageToken? nextPageToken = pageToken.GetNextPageToken(list.HasMore, list.LastId); return PageResult.Create(list.Data, pageToken, nextPageToken, response); @@ -126,7 +106,7 @@ public virtual ClientResult GetMessagesPage(string threadId, int? limit, string return ClientResult.FromResponse(_pipeline.ProcessMessage(message, options)); } - internal PipelineMessage CreateGetMessagesRequest(string threadId, int? limit, string order, string after, string before, RequestOptions options) + private PipelineMessage CreateGetMessagesRequest(string threadId, int? limit, string order, string after, string before, RequestOptions options) { var message = _pipeline.CreateMessage(); message.ResponseClassifier = PipelineMessageClassifier200; @@ -161,5 +141,4 @@ internal PipelineMessage CreateGetMessagesRequest(string threadId, int? limit, s private static PipelineMessageClassifier? _pipelineMessageClassifier200; private static PipelineMessageClassifier PipelineMessageClassifier200 => _pipelineMessageClassifier200 ??= PipelineMessageClassifier.Create(stackalloc ushort[] { 200 }); - } From 8b762e27717ed01be874fa408a57ee62c4278b3e Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Mon, 1 Jul 2024 17:26:30 -0700 Subject: [PATCH 43/72] more nits and simplify --- .../MessageCollectionPageToken.cs | 27 +++++++++---------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/src/To.Be.Generated/MessageCollectionPageToken.cs b/src/To.Be.Generated/MessageCollectionPageToken.cs index 1dbc07bcc..6a7be63ad 100644 --- a/src/To.Be.Generated/MessageCollectionPageToken.cs +++ b/src/To.Be.Generated/MessageCollectionPageToken.cs @@ -67,9 +67,15 @@ public override BinaryData ToBytes() } public MessageCollectionPageToken? GetNextPageToken(bool hasMore, string? lastId) - => GetNextPageToken(ThreadId, Limit, Order, lastId, Before, hasMore); + { + if (!hasMore || lastId is null) + { + return null; + } + + return new(ThreadId, Limit, Order, lastId, Before); + } - // Convenience - continuation page request public static MessageCollectionPageToken FromToken(ContinuationToken pageToken) { if (pageToken is MessageCollectionPageToken token) @@ -81,7 +87,7 @@ public static MessageCollectionPageToken FromToken(ContinuationToken pageToken) if (data.ToMemory().Length == 0) { - return new(string.Empty, default, default, default, default); + throw new ArgumentException("Failed to create MessageCollectionPageToken from provided pageToken.", nameof(pageToken)); } Utf8JsonReader reader = new(data); @@ -93,6 +99,7 @@ public static MessageCollectionPageToken FromToken(ContinuationToken pageToken) string? before = null; reader.Read(); + Debug.Assert(reader.TokenType == JsonTokenType.StartObject); while (reader.Read()) @@ -103,6 +110,7 @@ public static MessageCollectionPageToken FromToken(ContinuationToken pageToken) } Debug.Assert(reader.TokenType == JsonTokenType.PropertyName); + string propertyName = reader.GetString()!; switch (propertyName) @@ -145,17 +153,6 @@ public static MessageCollectionPageToken FromToken(ContinuationToken pageToken) return new(threadId, limit, order, after, before); } - // Protocol - called from subclient public static MessageCollectionPageToken FromOptions(string threadId, int? limit, string? order, string? after, string? before) - => new MessageCollectionPageToken(threadId, limit, order, after, before); - - private static MessageCollectionPageToken? GetNextPageToken(string threadId, int? limit, string? order, string? after, string? before, bool hasMore) - { - if (!hasMore || after is null) - { - return null; - } - - return new MessageCollectionPageToken(threadId, limit, order, after, before); - } + => new(threadId, limit, order, after, before); } \ No newline at end of file From 7cd2e92e52a475f618a396224f2ab8077c4fd348 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Mon, 1 Jul 2024 17:33:13 -0700 Subject: [PATCH 44/72] nits --- .../Internal/PageResultEnumerator.cs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/To.Be.Generated/Internal/PageResultEnumerator.cs b/src/To.Be.Generated/Internal/PageResultEnumerator.cs index 573fb952f..7f0d19fd3 100644 --- a/src/To.Be.Generated/Internal/PageResultEnumerator.cs +++ b/src/To.Be.Generated/Internal/PageResultEnumerator.cs @@ -16,21 +16,20 @@ protected PageResultEnumerator() { } public ClientResult Current => _current!; - // Idea is that this is generated on the client - public abstract Task GetFirstAsync(); + #region Service-specific methods that need to be generated on the subclient - // Idea is that this is generated on the client - public abstract Task GetNextAsync(ClientResult result); + public abstract Task GetFirstAsync(); - // Idea is that this is generated on the client public abstract ClientResult GetFirst(); - // Idea is that this is generated on the client + public abstract Task GetNextAsync(ClientResult result); + public abstract ClientResult GetNext(ClientResult result); - // Idea is that this is generated on the client public abstract bool HasNext(ClientResult result); + #endregion + #region IEnumerator implementation object IEnumerator.Current => Current; From 67d70fab33c469dbf2f16052357b4c1f9fd98e29 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Tue, 2 Jul 2024 09:10:43 -0700 Subject: [PATCH 45/72] renames and a little rework --- .../Assistants/AssistantClient.Protocol.cs | 8 +- src/Custom/Assistants/AssistantClient.cs | 12 +-- .../Internal/PageCollectionHelpers.cs | 4 +- .../Internal/PageEnumerator.cs | 74 +++++++++++++++++++ .../MessagesPageEnumerator.Convenience.cs | 22 ++++++ ...ionClient.cs => MessagesPageEnumerator.cs} | 17 +---- ...ctionPageToken.cs => MessagesPageToken.cs} | 12 +-- 7 files changed, 116 insertions(+), 33 deletions(-) create mode 100644 src/To.Be.Generated/Internal/PageEnumerator.cs create mode 100644 src/To.Be.Generated/MessagesPageEnumerator.Convenience.cs rename src/To.Be.Generated/{MessageCollectionClient.cs => MessagesPageEnumerator.cs} (85%) rename src/To.Be.Generated/{MessageCollectionPageToken.cs => MessagesPageToken.cs} (87%) diff --git a/src/Custom/Assistants/AssistantClient.Protocol.cs b/src/Custom/Assistants/AssistantClient.Protocol.cs index a3964439e..ac4cb87c5 100644 --- a/src/Custom/Assistants/AssistantClient.Protocol.cs +++ b/src/Custom/Assistants/AssistantClient.Protocol.cs @@ -240,14 +240,14 @@ public virtual ClientResult CreateMessage(string threadId, BinaryContent content public virtual IAsyncEnumerable GetMessagesAsync(string threadId, int? limit, string order, string after, string before, RequestOptions options) { - IAsyncEnumerator enumerator = new MessageCollectionClient(_pipeline, _endpoint, threadId, limit, order, after, before, options); - return PageCollectionHelpers.CreateProtocolAsync(enumerator); + IAsyncEnumerator enumerator = new MessagesPageEnumerator(_pipeline, _endpoint, threadId, limit, order, after, before, options); + return PageCollectionHelpers.CreateAsync(enumerator); } public virtual IEnumerable GetMessages(string threadId, int? limit, string order, string after, string before, RequestOptions options) { - IEnumerator enumerator = new MessageCollectionClient(_pipeline, _endpoint, threadId, limit, order, after, before, options); - return PageCollectionHelpers.CreateProtocol(enumerator); + IEnumerator enumerator = new MessagesPageEnumerator(_pipeline, _endpoint, threadId, limit, order, after, before, options); + return PageCollectionHelpers.Create(enumerator); } /// diff --git a/src/Custom/Assistants/AssistantClient.cs b/src/Custom/Assistants/AssistantClient.cs index d2027d923..b22a9ddc5 100644 --- a/src/Custom/Assistants/AssistantClient.cs +++ b/src/Custom/Assistants/AssistantClient.cs @@ -390,7 +390,7 @@ public virtual AsyncPageCollection GetMessagesAsync( { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); - MessageCollectionClient enumerator = new(_pipeline, _endpoint, + MessagesPageEnumerator enumerator = new(_pipeline, _endpoint, threadId, options?.PageSize, options?.Order?.ToString(), @@ -405,9 +405,9 @@ public virtual AsyncPageCollection GetMessagesAsync( ContinuationToken firstPageToken, CancellationToken cancellationToken = default) { - MessageCollectionPageToken pageToken = MessageCollectionPageToken.FromToken(firstPageToken); + MessagesPageToken pageToken = MessagesPageToken.FromToken(firstPageToken); - MessageCollectionClient enumerator = new(_pipeline, _endpoint, + MessagesPageEnumerator enumerator = new(_pipeline, _endpoint, pageToken.ThreadId, pageToken.Limit, pageToken.Order, @@ -432,7 +432,7 @@ public virtual PageCollection GetMessages( { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); - MessageCollectionClient enumerator = new(_pipeline, _endpoint, + MessagesPageEnumerator enumerator = new(_pipeline, _endpoint, threadId, options?.PageSize, options?.Order?.ToString(), @@ -449,9 +449,9 @@ public virtual PageCollection GetMessages( { Argument.AssertNotNull(firstPageToken, nameof(firstPageToken)); - MessageCollectionPageToken pageToken = MessageCollectionPageToken.FromToken(firstPageToken); + MessagesPageToken pageToken = MessagesPageToken.FromToken(firstPageToken); - MessageCollectionClient enumerator = new(_pipeline, _endpoint, + MessagesPageEnumerator enumerator = new(_pipeline, _endpoint, pageToken.ThreadId, pageToken.Limit, pageToken.Order, diff --git a/src/To.Be.Generated/Internal/PageCollectionHelpers.cs b/src/To.Be.Generated/Internal/PageCollectionHelpers.cs index e81bbd4da..8c2eab6dd 100644 --- a/src/To.Be.Generated/Internal/PageCollectionHelpers.cs +++ b/src/To.Be.Generated/Internal/PageCollectionHelpers.cs @@ -19,7 +19,7 @@ public static PageCollection Create( Func> getPageFromResult) => new FuncPageCollection(enumerator, getPageFromResult); - public static IEnumerable CreateProtocol(IEnumerator enumerator) + public static IEnumerable Create(IEnumerator enumerator) { while (enumerator.MoveNext()) { @@ -27,7 +27,7 @@ public static IEnumerable CreateProtocol(IEnumerator } } - public static async IAsyncEnumerable CreateProtocolAsync(IAsyncEnumerator enumerator) + public static async IAsyncEnumerable CreateAsync(IAsyncEnumerator enumerator) { while (await enumerator.MoveNextAsync().ConfigureAwait(false)) { diff --git a/src/To.Be.Generated/Internal/PageEnumerator.cs b/src/To.Be.Generated/Internal/PageEnumerator.cs new file mode 100644 index 000000000..abfc73130 --- /dev/null +++ b/src/To.Be.Generated/Internal/PageEnumerator.cs @@ -0,0 +1,74 @@ +//using System; +//using System.ClientModel; +//using System.Collections; +//using System.Collections.Generic; +//using System.Threading.Tasks; + +//#nullable enable + +//namespace OpenAI; + +//internal abstract class PageEnumerator : IAsyncEnumerator>, IEnumerator> +//{ +// public PageEnumerator(PageResultEnumerator resultEnumerator) +// { +// ResultEnumerator = resultEnumerator; +// } + +// public PageResultEnumerator ResultEnumerator { get; } + +// public abstract PageResult GetPageFromResult(ClientResult result); + +// public PageResult Current => GetPageFromResult(ResultEnumerator.Current); + +// #region IEnumerator> implementation + +// object IEnumerator.Current => Current; + +// public bool MoveNext() => ResultEnumerator.MoveNext(); + +// public void Reset() => ResultEnumerator.Reset(); + +// public void Dispose() => ResultEnumerator.Dispose(); + +// #endregion + +// #region IAsyncEnumerator> implementation + +// public ValueTask MoveNextAsync() => ResultEnumerator.MoveNextAsync(); + +// public ValueTask DisposeAsync() => ResultEnumerator.DisposeAsync(); + +// #endregion +//} +//using System.ClientModel; +//using System.ClientModel.Primitives; + +//#nullable enable + +//namespace OpenAI.Assistants; + +//internal partial class MessagesPageEnumerator : PageEnumerator +//{ +// public MessagesPageEnumerator(MessagesPageResultEnumerator resultEnumerator) +// : base(resultEnumerator) +// { +// } + +// // Note: this is the deserialization method that converts protocol to convenience +// public override PageResult GetPageFromResult(ClientResult result) +// { +// PipelineResponse response = result.GetRawResponse(); + +// InternalListMessagesResponse list = ModelReaderWriter.Read(response.Content)!; + +// MessagesPageResultEnumerator resultEnumerator = (MessagesPageResultEnumerator)ResultEnumerator; + +// MessagesPageToken pageToken = MessagesPageToken.FromOptions( +// resultEnumerator. +// _threadId, _limit, _order, _after, _before); +// MessagesPageToken? nextPageToken = pageToken.GetNextPageToken(list.HasMore, list.LastId); + +// return PageResult.Create(list.Data, pageToken, nextPageToken, response); +// } +//} diff --git a/src/To.Be.Generated/MessagesPageEnumerator.Convenience.cs b/src/To.Be.Generated/MessagesPageEnumerator.Convenience.cs new file mode 100644 index 000000000..234fa12a8 --- /dev/null +++ b/src/To.Be.Generated/MessagesPageEnumerator.Convenience.cs @@ -0,0 +1,22 @@ +using System.ClientModel; +using System.ClientModel.Primitives; + +#nullable enable + +namespace OpenAI.Assistants; + +internal partial class MessagesPageEnumerator : PageResultEnumerator +{ + // Note: this is the deserialization method that converts protocol to convenience + public PageResult GetPageFromResult(ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + + InternalListMessagesResponse list = ModelReaderWriter.Read(response.Content)!; + + MessagesPageToken pageToken = MessagesPageToken.FromOptions(_threadId, _limit, _order, _after, _before); + MessagesPageToken? nextPageToken = pageToken.GetNextPageToken(list.HasMore, list.LastId); + + return PageResult.Create(list.Data, pageToken, nextPageToken, response); + } +} \ No newline at end of file diff --git a/src/To.Be.Generated/MessageCollectionClient.cs b/src/To.Be.Generated/MessagesPageEnumerator.cs similarity index 85% rename from src/To.Be.Generated/MessageCollectionClient.cs rename to src/To.Be.Generated/MessagesPageEnumerator.cs index 823ab7773..bf5774ab4 100644 --- a/src/To.Be.Generated/MessageCollectionClient.cs +++ b/src/To.Be.Generated/MessagesPageEnumerator.cs @@ -8,7 +8,7 @@ namespace OpenAI.Assistants; -internal class MessageCollectionClient : PageResultEnumerator +internal partial class MessagesPageEnumerator : PageResultEnumerator { private readonly ClientPipeline _pipeline; private readonly Uri _endpoint; @@ -23,7 +23,7 @@ internal class MessageCollectionClient : PageResultEnumerator private readonly string _before; private readonly RequestOptions _options; - public MessageCollectionClient( + public MessagesPageEnumerator( ClientPipeline pipeline, Uri endpoint, string threadId, int? limit, string order, string after, string before, @@ -76,19 +76,6 @@ public override bool HasNext(ClientResult result) return hasMore; } - // Note: this is the deserialization method that converts protocol to convenience - public PageResult GetPageFromResult(ClientResult result) - { - PipelineResponse response = result.GetRawResponse(); - - InternalListMessagesResponse list = ModelReaderWriter.Read(response.Content)!; - - MessageCollectionPageToken pageToken = MessageCollectionPageToken.FromOptions(_threadId, _limit, _order, _after, _before); - MessageCollectionPageToken? nextPageToken = pageToken.GetNextPageToken(list.HasMore, list.LastId); - - return PageResult.Create(list.Data, pageToken, nextPageToken, response); - } - // Note: these are the protocol methods - they are generated here public virtual async Task GetMessagesPageAsync(string threadId, int? limit, string order, string after, string before, RequestOptions options) { diff --git a/src/To.Be.Generated/MessageCollectionPageToken.cs b/src/To.Be.Generated/MessagesPageToken.cs similarity index 87% rename from src/To.Be.Generated/MessageCollectionPageToken.cs rename to src/To.Be.Generated/MessagesPageToken.cs index 6a7be63ad..359dc7854 100644 --- a/src/To.Be.Generated/MessageCollectionPageToken.cs +++ b/src/To.Be.Generated/MessagesPageToken.cs @@ -8,9 +8,9 @@ namespace OpenAI.Assistants; -internal class MessageCollectionPageToken : ContinuationToken +internal class MessagesPageToken : ContinuationToken { - public MessageCollectionPageToken(string threadId, int? limit, string? order, string? after, string? before) + public MessagesPageToken(string threadId, int? limit, string? order, string? after, string? before) { ThreadId = threadId; @@ -66,7 +66,7 @@ public override BinaryData ToBytes() return BinaryData.FromStream(stream); } - public MessageCollectionPageToken? GetNextPageToken(bool hasMore, string? lastId) + public MessagesPageToken? GetNextPageToken(bool hasMore, string? lastId) { if (!hasMore || lastId is null) { @@ -76,9 +76,9 @@ public override BinaryData ToBytes() return new(ThreadId, Limit, Order, lastId, Before); } - public static MessageCollectionPageToken FromToken(ContinuationToken pageToken) + public static MessagesPageToken FromToken(ContinuationToken pageToken) { - if (pageToken is MessageCollectionPageToken token) + if (pageToken is MessagesPageToken token) { return token; } @@ -153,6 +153,6 @@ public static MessageCollectionPageToken FromToken(ContinuationToken pageToken) return new(threadId, limit, order, after, before); } - public static MessageCollectionPageToken FromOptions(string threadId, int? limit, string? order, string? after, string? before) + public static MessagesPageToken FromOptions(string threadId, int? limit, string? order, string? after, string? before) => new(threadId, limit, order, after, before); } \ No newline at end of file From daab1083f557143dfe74acae108f445657cf5b15 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Tue, 2 Jul 2024 09:32:39 -0700 Subject: [PATCH 46/72] move page tokens --- .../Assistants/AssistantClient.Protocol.cs | 36 ++++----- src/Custom/Assistants/AssistantClient.cs | 36 ++++----- .../AssistantsPageToken.cs} | 54 +++++++------- .../Internal/PageEnumerator.cs | 74 ------------------- src/To.Be.Generated/MessagesPageToken.cs | 4 +- .../RunStepsPageToken.cs} | 57 +++++++------- .../RunsPageToken.cs} | 57 +++++++------- 7 files changed, 129 insertions(+), 189 deletions(-) rename src/{Custom/Assistants/AssistantCollectionPageToken.cs => To.Be.Generated/AssistantsPageToken.cs} (68%) delete mode 100644 src/To.Be.Generated/Internal/PageEnumerator.cs rename src/{Custom/Assistants/RunStepCollectionPageToken.cs => To.Be.Generated/RunStepsPageToken.cs} (68%) rename src/{Custom/Assistants/RunCollectionPageToken.cs => To.Be.Generated/RunsPageToken.cs} (68%) diff --git a/src/Custom/Assistants/AssistantClient.Protocol.cs b/src/Custom/Assistants/AssistantClient.Protocol.cs index ac4cb87c5..022d05465 100644 --- a/src/Custom/Assistants/AssistantClient.Protocol.cs +++ b/src/Custom/Assistants/AssistantClient.Protocol.cs @@ -66,13 +66,13 @@ public virtual ClientResult CreateAssistant(BinaryContent content, RequestOption /// The response returned from the service. public virtual IAsyncEnumerable GetAssistantsAsync(int? limit, string order, string after, string before, RequestOptions options) { - AssistantCollectionPageToken firstPageToken = AssistantCollectionPageToken.FromOptions(limit, order, after, before); - return OpenAIPageCollectionHelpers.CreateProtocolAsync(firstPageToken, GetAssistantsPageAsync, AssistantCollectionPageToken.FromToken, options); + AssistantsPageToken firstPageToken = AssistantsPageToken.FromOptions(limit, order, after, before); + return OpenAIPageCollectionHelpers.CreateProtocolAsync(firstPageToken, GetAssistantsPageAsync, AssistantsPageToken.FromToken, options); } internal virtual async Task GetAssistantsPageAsync(ContinuationToken pageToken, RequestOptions options) { - AssistantCollectionPageToken token = AssistantCollectionPageToken.FromToken(pageToken); + AssistantsPageToken token = AssistantsPageToken.FromToken(pageToken); return await GetAssistantsPageAsync(token.Limit, token.Order, token.After, token.Before, options).ConfigureAwait(false); } @@ -108,13 +108,13 @@ internal virtual async Task GetAssistantsPageAsync(int? limit, str /// The response returned from the service. public virtual IEnumerable GetAssistants(int? limit, string order, string after, string before, RequestOptions options) { - AssistantCollectionPageToken firstPageToken = AssistantCollectionPageToken.FromOptions(limit, order, after, before); - return OpenAIPageCollectionHelpers.CreateProtocol(firstPageToken, GetAssistantsPage, AssistantCollectionPageToken.FromToken, options); + AssistantsPageToken firstPageToken = AssistantsPageToken.FromOptions(limit, order, after, before); + return OpenAIPageCollectionHelpers.CreateProtocol(firstPageToken, GetAssistantsPage, AssistantsPageToken.FromToken, options); } internal virtual ClientResult GetAssistantsPage(ContinuationToken pageToken, RequestOptions options) { - AssistantCollectionPageToken token = AssistantCollectionPageToken.FromToken(pageToken); + AssistantsPageToken token = AssistantsPageToken.FromToken(pageToken); return GetAssistantsPage(token.Limit, token.Order, token.After, token.Before, options); } @@ -290,13 +290,13 @@ public virtual ClientResult CreateRun(string threadId, BinaryContent content, Re public virtual IAsyncEnumerable GetRunsAsync(string threadId, int? limit, string order, string after, string before, RequestOptions options) { - RunCollectionPageToken firstPageToken = RunCollectionPageToken.FromOptions(threadId, limit, order, after, before); - return OpenAIPageCollectionHelpers.CreateProtocolAsync(firstPageToken, GetRunsPageAsync, RunCollectionPageToken.FromToken, options); + RunsPageToken firstPageToken = RunsPageToken.FromOptions(threadId, limit, order, after, before); + return OpenAIPageCollectionHelpers.CreateProtocolAsync(firstPageToken, GetRunsPageAsync, RunsPageToken.FromToken, options); } internal async virtual Task GetRunsPageAsync(ContinuationToken pageToken, RequestOptions options) { - RunCollectionPageToken token = RunCollectionPageToken.FromToken(pageToken); + RunsPageToken token = RunsPageToken.FromToken(pageToken); return await GetRunsPageAsync(token.ThreadId, token.Limit, token.Order, token.After, token.Before, options).ConfigureAwait(false); } @@ -306,13 +306,13 @@ internal async virtual Task GetRunsPageAsync(string threadId, int? public virtual IEnumerable GetRuns(string threadId, int? limit, string order, string after, string before, RequestOptions options) { - RunCollectionPageToken firstPageToken = RunCollectionPageToken.FromOptions(threadId, limit, order, after, before); - return OpenAIPageCollectionHelpers.CreateProtocol(firstPageToken, GetRunsPage, RunCollectionPageToken.FromToken, options); + RunsPageToken firstPageToken = RunsPageToken.FromOptions(threadId, limit, order, after, before); + return OpenAIPageCollectionHelpers.CreateProtocol(firstPageToken, GetRunsPage, RunsPageToken.FromToken, options); } internal virtual ClientResult GetRunsPage(ContinuationToken pageToken, RequestOptions options) { - RunCollectionPageToken token = RunCollectionPageToken.FromToken(pageToken); + RunsPageToken token = RunsPageToken.FromToken(pageToken); return GetRunsPage(token.ThreadId, token.Limit, token.Order, token.After, token.Before, options); } @@ -354,13 +354,13 @@ public virtual ClientResult SubmitToolOutputsToRun(string threadId, string runId public virtual IAsyncEnumerable GetRunStepsAsync(string threadId, string runId, int? limit, string order, string after, string before, RequestOptions options) { - RunStepCollectionPageToken firstPageToken = RunStepCollectionPageToken.FromOptions(threadId, runId, limit, order, after, before); - return OpenAIPageCollectionHelpers.CreateProtocolAsync(firstPageToken, GetRunStepsPageAsync, RunStepCollectionPageToken.FromToken, options); + RunStepsPageToken firstPageToken = RunStepsPageToken.FromOptions(threadId, runId, limit, order, after, before); + return OpenAIPageCollectionHelpers.CreateProtocolAsync(firstPageToken, GetRunStepsPageAsync, RunStepsPageToken.FromToken, options); } internal virtual async Task GetRunStepsPageAsync(ContinuationToken pageToken, RequestOptions options) { - RunStepCollectionPageToken token = RunStepCollectionPageToken.FromToken(pageToken); + RunStepsPageToken token = RunStepsPageToken.FromToken(pageToken); return await GetRunStepsPageAsync(token.ThreadId, token.RunId, token.Limit, token.Order, token.After, token.Before, options).ConfigureAwait(false); } @@ -370,13 +370,13 @@ internal virtual async Task GetRunStepsPageAsync(string threadId, public virtual IEnumerable GetRunSteps(string threadId, string runId, int? limit, string order, string after, string before, RequestOptions options) { - RunStepCollectionPageToken firstPageToken = RunStepCollectionPageToken.FromOptions(threadId, runId, limit, order, after, before); - return OpenAIPageCollectionHelpers.CreateProtocol(firstPageToken, GetRunStepsPage, RunStepCollectionPageToken.FromToken, options); + RunStepsPageToken firstPageToken = RunStepsPageToken.FromOptions(threadId, runId, limit, order, after, before); + return OpenAIPageCollectionHelpers.CreateProtocol(firstPageToken, GetRunStepsPage, RunStepsPageToken.FromToken, options); } internal virtual ClientResult GetRunStepsPage(ContinuationToken pageToken, RequestOptions options) { - RunStepCollectionPageToken token = RunStepCollectionPageToken.FromToken(pageToken); + RunStepsPageToken token = RunStepsPageToken.FromToken(pageToken); return GetRunStepsPage(token.ThreadId, token.RunId, token.Limit, token.Order, token.After, token.Before, options); } diff --git a/src/Custom/Assistants/AssistantClient.cs b/src/Custom/Assistants/AssistantClient.cs index b22a9ddc5..f2b63f77a 100644 --- a/src/Custom/Assistants/AssistantClient.cs +++ b/src/Custom/Assistants/AssistantClient.cs @@ -111,11 +111,11 @@ public virtual AsyncPageCollection GetAssistantsAsync( AssistantCollectionOptions options = default, CancellationToken cancellationToken = default) { - AssistantCollectionPageToken firstPageToken = AssistantCollectionPageToken.FromOptions(options); + AssistantsPageToken firstPageToken = AssistantsPageToken.FromOptions(options); return OpenAIPageCollectionHelpers.CreateAsync( firstPageToken, GetAssistantsPageAsync, - AssistantCollectionPageToken.FromToken, + AssistantsPageToken.FromToken, cancellationToken.ToRequestOptions()); } @@ -129,11 +129,11 @@ public virtual AsyncPageCollection GetAssistantsAsync( ContinuationToken firstPageToken, CancellationToken cancellationToken = default) { - AssistantCollectionPageToken pageToken = AssistantCollectionPageToken.FromToken(firstPageToken); + AssistantsPageToken pageToken = AssistantsPageToken.FromToken(firstPageToken); return OpenAIPageCollectionHelpers.CreateAsync( firstPageToken, GetAssistantsPageAsync, - AssistantCollectionPageToken.FromToken, + AssistantsPageToken.FromToken, cancellationToken.ToRequestOptions()); } @@ -147,11 +147,11 @@ public virtual PageCollection GetAssistants( AssistantCollectionOptions options = default, CancellationToken cancellationToken = default) { - AssistantCollectionPageToken firstPageToken = AssistantCollectionPageToken.FromOptions(options); + AssistantsPageToken firstPageToken = AssistantsPageToken.FromOptions(options); return OpenAIPageCollectionHelpers.Create( firstPageToken, GetAssistantsPage, - AssistantCollectionPageToken.FromToken, + AssistantsPageToken.FromToken, cancellationToken.ToRequestOptions()); } @@ -165,11 +165,11 @@ public virtual PageCollection GetAssistants( ContinuationToken firstPageToken, CancellationToken cancellationToken = default) { - AssistantCollectionPageToken pageToken = AssistantCollectionPageToken.FromToken(firstPageToken); + AssistantsPageToken pageToken = AssistantsPageToken.FromToken(firstPageToken); return OpenAIPageCollectionHelpers.Create( pageToken, GetAssistantsPage, - AssistantCollectionPageToken.FromToken, + AssistantsPageToken.FromToken, cancellationToken.ToRequestOptions()); } @@ -768,11 +768,11 @@ public virtual AsyncPageCollection GetRunsAsync( { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); - RunCollectionPageToken firstPageToken = RunCollectionPageToken.FromOptions(threadId, options); + RunsPageToken firstPageToken = RunsPageToken.FromOptions(threadId, options); return OpenAIPageCollectionHelpers.CreateAsync( firstPageToken, GetRunsPageAsync, - RunCollectionPageToken.FromToken, + RunsPageToken.FromToken, cancellationToken.ToRequestOptions()); } @@ -780,11 +780,11 @@ public virtual AsyncPageCollection GetRunsAsync( ContinuationToken firstPageToken, CancellationToken cancellationToken = default) { - RunCollectionPageToken pageToken = RunCollectionPageToken.FromToken(firstPageToken); + RunsPageToken pageToken = RunsPageToken.FromToken(firstPageToken); return OpenAIPageCollectionHelpers.CreateAsync( firstPageToken, GetRunsPageAsync, - RunCollectionPageToken.FromToken, + RunsPageToken.FromToken, cancellationToken.ToRequestOptions()); } @@ -811,11 +811,11 @@ public virtual PageCollection GetRuns( ContinuationToken firstPageToken, CancellationToken cancellationToken = default) { - RunCollectionPageToken pageToken = RunCollectionPageToken.FromToken(firstPageToken); + RunsPageToken pageToken = RunsPageToken.FromToken(firstPageToken); return OpenAIPageCollectionHelpers.Create( firstPageToken, GetRunsPage, - RunCollectionPageToken.FromToken, + RunsPageToken.FromToken, cancellationToken.ToRequestOptions()); } @@ -1003,11 +1003,11 @@ public virtual AsyncPageCollection GetRunStepsAsync( Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); Argument.AssertNotNullOrEmpty(runId, nameof(runId)); - RunStepCollectionPageToken firstPageToken = RunStepCollectionPageToken.FromOptions(threadId, runId, options); + RunStepsPageToken firstPageToken = RunStepsPageToken.FromOptions(threadId, runId, options); return OpenAIPageCollectionHelpers.CreateAsync( firstPageToken, GetRunStepsPageAsync, - RunStepCollectionPageToken.FromToken, + RunStepsPageToken.FromToken, cancellationToken.ToRequestOptions()); } @@ -1028,11 +1028,11 @@ public virtual PageCollection GetRunSteps( Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); Argument.AssertNotNullOrEmpty(runId, nameof(runId)); - RunStepCollectionPageToken firstPageToken = RunStepCollectionPageToken.FromOptions(threadId, runId, options); + RunStepsPageToken firstPageToken = RunStepsPageToken.FromOptions(threadId, runId, options); return OpenAIPageCollectionHelpers.Create( firstPageToken, GetRunStepsPage, - RunStepCollectionPageToken.FromToken, + RunStepsPageToken.FromToken, cancellationToken.ToRequestOptions()); } diff --git a/src/Custom/Assistants/AssistantCollectionPageToken.cs b/src/To.Be.Generated/AssistantsPageToken.cs similarity index 68% rename from src/Custom/Assistants/AssistantCollectionPageToken.cs rename to src/To.Be.Generated/AssistantsPageToken.cs index f83b01fd1..d6002c39b 100644 --- a/src/Custom/Assistants/AssistantCollectionPageToken.cs +++ b/src/To.Be.Generated/AssistantsPageToken.cs @@ -8,15 +8,23 @@ namespace OpenAI.Assistants; -internal class AssistantCollectionPageToken : OpenAIPageToken +internal class AssistantsPageToken : ContinuationToken { - public AssistantCollectionPageToken(int? limit, string? order, string? after, string? before) - : base(limit, order, after, before) + public AssistantsPageToken(int? limit, string? order, string? after, string? before) { + Limit = limit; + Order = order; + After = after; + Before = before; } - public override OpenAIPageToken? GetNextPageToken(bool hasMore, string? lastId) - => GetNextPageToken(Limit, Order, lastId, Before, hasMore); + public int? Limit { get; } + + public string? Order { get; } + + public string? After { get; } + + public string? Before { get; } public override BinaryData ToBytes() { @@ -53,14 +61,19 @@ public override BinaryData ToBytes() return BinaryData.FromStream(stream); } - // Convenience - first page request - public static AssistantCollectionPageToken FromOptions(AssistantCollectionOptions options) - => new(options?.PageSize, options?.Order?.ToString(), options?.AfterId, options?.BeforeId); + public AssistantsPageToken? GetNextPageToken(bool hasMore, string? lastId) + { + if (!hasMore || lastId is null) + { + return null; + } + + return new AssistantsPageToken(Limit, Order, After, Before); + } - // Convenience - continuation page request - public static AssistantCollectionPageToken FromToken(ContinuationToken token) + public static AssistantsPageToken FromToken(ContinuationToken token) { - if (token is AssistantCollectionPageToken pageToken) + if (token is AssistantsPageToken pageToken) { return pageToken; } @@ -69,7 +82,7 @@ public static AssistantCollectionPageToken FromToken(ContinuationToken token) if (data.ToMemory().Length == 0) { - return new(default, default, default, default); + throw new ArgumentException("Failed to create AssistantsPageToken from provided pageToken.", nameof(pageToken)); } Utf8JsonReader reader = new(data); @@ -80,6 +93,7 @@ public static AssistantCollectionPageToken FromToken(ContinuationToken token) string? before = null; reader.Read(); + Debug.Assert(reader.TokenType == JsonTokenType.StartObject); while (reader.Read()) @@ -90,6 +104,7 @@ public static AssistantCollectionPageToken FromToken(ContinuationToken token) } Debug.Assert(reader.TokenType == JsonTokenType.PropertyName); + string propertyName = reader.GetString()!; switch (propertyName) @@ -122,17 +137,6 @@ public static AssistantCollectionPageToken FromToken(ContinuationToken token) return new(limit, order, after, before); } - // Protocol - public static AssistantCollectionPageToken FromOptions(int? limit, string? order, string? after, string? before) - => new AssistantCollectionPageToken(limit, order, after, before); - - private static AssistantCollectionPageToken? GetNextPageToken(int? limit, string? order, string? after, string? before, bool hasMore) - { - if (!hasMore || after is null) - { - return null; - } - - return new AssistantCollectionPageToken(limit, order, after, before); - } + public static AssistantsPageToken FromOptions(int? limit, string? order, string? after, string? before) + => new AssistantsPageToken(limit, order, after, before); } \ No newline at end of file diff --git a/src/To.Be.Generated/Internal/PageEnumerator.cs b/src/To.Be.Generated/Internal/PageEnumerator.cs deleted file mode 100644 index abfc73130..000000000 --- a/src/To.Be.Generated/Internal/PageEnumerator.cs +++ /dev/null @@ -1,74 +0,0 @@ -//using System; -//using System.ClientModel; -//using System.Collections; -//using System.Collections.Generic; -//using System.Threading.Tasks; - -//#nullable enable - -//namespace OpenAI; - -//internal abstract class PageEnumerator : IAsyncEnumerator>, IEnumerator> -//{ -// public PageEnumerator(PageResultEnumerator resultEnumerator) -// { -// ResultEnumerator = resultEnumerator; -// } - -// public PageResultEnumerator ResultEnumerator { get; } - -// public abstract PageResult GetPageFromResult(ClientResult result); - -// public PageResult Current => GetPageFromResult(ResultEnumerator.Current); - -// #region IEnumerator> implementation - -// object IEnumerator.Current => Current; - -// public bool MoveNext() => ResultEnumerator.MoveNext(); - -// public void Reset() => ResultEnumerator.Reset(); - -// public void Dispose() => ResultEnumerator.Dispose(); - -// #endregion - -// #region IAsyncEnumerator> implementation - -// public ValueTask MoveNextAsync() => ResultEnumerator.MoveNextAsync(); - -// public ValueTask DisposeAsync() => ResultEnumerator.DisposeAsync(); - -// #endregion -//} -//using System.ClientModel; -//using System.ClientModel.Primitives; - -//#nullable enable - -//namespace OpenAI.Assistants; - -//internal partial class MessagesPageEnumerator : PageEnumerator -//{ -// public MessagesPageEnumerator(MessagesPageResultEnumerator resultEnumerator) -// : base(resultEnumerator) -// { -// } - -// // Note: this is the deserialization method that converts protocol to convenience -// public override PageResult GetPageFromResult(ClientResult result) -// { -// PipelineResponse response = result.GetRawResponse(); - -// InternalListMessagesResponse list = ModelReaderWriter.Read(response.Content)!; - -// MessagesPageResultEnumerator resultEnumerator = (MessagesPageResultEnumerator)ResultEnumerator; - -// MessagesPageToken pageToken = MessagesPageToken.FromOptions( -// resultEnumerator. -// _threadId, _limit, _order, _after, _before); -// MessagesPageToken? nextPageToken = pageToken.GetNextPageToken(list.HasMore, list.LastId); - -// return PageResult.Create(list.Data, pageToken, nextPageToken, response); -// } -//} diff --git a/src/To.Be.Generated/MessagesPageToken.cs b/src/To.Be.Generated/MessagesPageToken.cs index 359dc7854..4700880e0 100644 --- a/src/To.Be.Generated/MessagesPageToken.cs +++ b/src/To.Be.Generated/MessagesPageToken.cs @@ -87,7 +87,7 @@ public static MessagesPageToken FromToken(ContinuationToken pageToken) if (data.ToMemory().Length == 0) { - throw new ArgumentException("Failed to create MessageCollectionPageToken from provided pageToken.", nameof(pageToken)); + throw new ArgumentException("Failed to create MessagesPageToken from provided pageToken.", nameof(pageToken)); } Utf8JsonReader reader = new(data); @@ -147,7 +147,7 @@ public static MessagesPageToken FromToken(ContinuationToken pageToken) if (threadId is null) { - throw new ArgumentException("Failed to create MessageCollectionPageToken from provided pageToken.", nameof(pageToken)); + throw new ArgumentException("Failed to create MessagesPageToken from provided pageToken.", nameof(pageToken)); } return new(threadId, limit, order, after, before); diff --git a/src/Custom/Assistants/RunStepCollectionPageToken.cs b/src/To.Be.Generated/RunStepsPageToken.cs similarity index 68% rename from src/Custom/Assistants/RunStepCollectionPageToken.cs rename to src/To.Be.Generated/RunStepsPageToken.cs index 008eb9f8e..371026996 100644 --- a/src/Custom/Assistants/RunStepCollectionPageToken.cs +++ b/src/To.Be.Generated/RunStepsPageToken.cs @@ -8,18 +8,30 @@ namespace OpenAI.Assistants; -internal class RunStepCollectionPageToken : OpenAIPageToken +internal class RunStepsPageToken : ContinuationToken { - public RunStepCollectionPageToken(string threadId, string runId, int? limit, string? order, string? after, string? before) - : base(limit, order, after, before) + public RunStepsPageToken(string threadId, string runId, int? limit, string? order, string? after, string? before) { ThreadId = threadId; RunId = runId; + + Limit = limit; + Order = order; + After = after; + Before = before; } public string ThreadId { get; } public string RunId { get; } + public int? Limit { get; } + + public string? Order { get; } + + public string? After { get; } + + public string? Before { get; } + public override BinaryData ToBytes() { using MemoryStream stream = new(); @@ -57,17 +69,19 @@ public override BinaryData ToBytes() return BinaryData.FromStream(stream); } - public override OpenAIPageToken? GetNextPageToken(bool hasMore, string? lastId) - => GetNextPageToken(ThreadId, RunId, Limit, Order, lastId, Before, hasMore); + public RunStepsPageToken? GetNextPageToken(bool hasMore, string? lastId) + { + if (!hasMore || lastId is null) + { + return null; + } - // Convenience - first page request - public static RunStepCollectionPageToken FromOptions(string threadId, string runId,RunStepCollectionOptions options) - => new(threadId, runId, options?.PageSize, options?.Order?.ToString(), options?.AfterId, options?.BeforeId); + return new RunStepsPageToken(ThreadId, RunId, Limit, Order, After, Before); + } - // Convenience - continuation page request - public static RunStepCollectionPageToken FromToken(ContinuationToken pageToken) + public static RunStepsPageToken FromToken(ContinuationToken pageToken) { - if (pageToken is RunStepCollectionPageToken token) + if (pageToken is RunStepsPageToken token) { return token; } @@ -76,7 +90,7 @@ public static RunStepCollectionPageToken FromToken(ContinuationToken pageToken) if (data.ToMemory().Length == 0) { - throw new ArgumentException("Failed to create MessageCollectionPageToken from provided pageToken.", nameof(pageToken)); + throw new ArgumentException("Failed to create RunStepsPageToken from provided pageToken.", nameof(pageToken)); } Utf8JsonReader reader = new(data); @@ -89,6 +103,7 @@ public static RunStepCollectionPageToken FromToken(ContinuationToken pageToken) string? before = null; reader.Read(); + Debug.Assert(reader.TokenType == JsonTokenType.StartObject); while (reader.Read()) @@ -99,6 +114,7 @@ public static RunStepCollectionPageToken FromToken(ContinuationToken pageToken) } Debug.Assert(reader.TokenType == JsonTokenType.PropertyName); + string propertyName = reader.GetString()!; switch (propertyName) @@ -140,23 +156,12 @@ public static RunStepCollectionPageToken FromToken(ContinuationToken pageToken) if (threadId is null || runId is null) { - throw new ArgumentException("Failed to create MessageCollectionPageToken from provided pageToken.", nameof(pageToken)); + throw new ArgumentException("Failed to create RunStepsPageToken from provided pageToken.", nameof(pageToken)); } return new(threadId, runId, limit, order, after, before); } - // Protocol - public static RunStepCollectionPageToken FromOptions(string threadId, string runId, int? limit, string? order, string? after, string? before) - => new RunStepCollectionPageToken(threadId, runId, limit, order, after, before); - - private static RunStepCollectionPageToken? GetNextPageToken(string threadId, string runId, int? limit, string? order, string? after, string? before, bool hasMore) - { - if (!hasMore || after is null) - { - return null; - } - - return new RunStepCollectionPageToken(threadId, runId, limit, order, after, before); - } + public static RunStepsPageToken FromOptions(string threadId, string runId, int? limit, string? order, string? after, string? before) + => new RunStepsPageToken(threadId, runId, limit, order, after, before); } \ No newline at end of file diff --git a/src/Custom/Assistants/RunCollectionPageToken.cs b/src/To.Be.Generated/RunsPageToken.cs similarity index 68% rename from src/Custom/Assistants/RunCollectionPageToken.cs rename to src/To.Be.Generated/RunsPageToken.cs index f31ccc544..aec984ac3 100644 --- a/src/Custom/Assistants/RunCollectionPageToken.cs +++ b/src/To.Be.Generated/RunsPageToken.cs @@ -8,16 +8,28 @@ namespace OpenAI.Assistants; -internal class RunCollectionPageToken : OpenAIPageToken +internal class RunsPageToken : ContinuationToken { - public RunCollectionPageToken(string threadId, int? limit, string? order, string? after, string? before) - : base(limit, order, after, before) + public RunsPageToken(string threadId, int? limit, string? order, string? after, string? before) { ThreadId = threadId; + + Limit = limit; + Order = order; + After = after; + Before = before; } public string ThreadId { get; } + public int? Limit { get; } + + public string? Order { get; } + + public string? After { get; } + + public string? Before { get; } + public override BinaryData ToBytes() { using MemoryStream stream = new(); @@ -54,17 +66,19 @@ public override BinaryData ToBytes() return BinaryData.FromStream(stream); } - public override OpenAIPageToken? GetNextPageToken(bool hasMore, string? lastId) - => GetNextPageToken(ThreadId, Limit, Order, lastId, Before, hasMore); + public RunsPageToken? GetNextPageToken(bool hasMore, string? lastId) + { + if (!hasMore || lastId is null) + { + return null; + } - // Convenience - first page request - public static RunCollectionPageToken FromOptions(string threadId, RunCollectionOptions options) - => new(threadId, options?.PageSize, options?.Order?.ToString(), options?.AfterId, options?.BeforeId); + return new RunsPageToken(ThreadId, Limit, Order, After, Before); + } - // Convenience - continuation page request - public static RunCollectionPageToken FromToken(ContinuationToken pageToken) + public static RunsPageToken FromToken(ContinuationToken pageToken) { - if (pageToken is RunCollectionPageToken token) + if (pageToken is RunsPageToken token) { return token; } @@ -73,7 +87,7 @@ public static RunCollectionPageToken FromToken(ContinuationToken pageToken) if (data.ToMemory().Length == 0) { - return new(string.Empty, default, default, default, default); + throw new ArgumentException("Failed to create RunsPageToken from provided pageToken.", nameof(pageToken)); } Utf8JsonReader reader = new(data); @@ -85,6 +99,7 @@ public static RunCollectionPageToken FromToken(ContinuationToken pageToken) string? before = null; reader.Read(); + Debug.Assert(reader.TokenType == JsonTokenType.StartObject); while (reader.Read()) @@ -95,6 +110,7 @@ public static RunCollectionPageToken FromToken(ContinuationToken pageToken) } Debug.Assert(reader.TokenType == JsonTokenType.PropertyName); + string propertyName = reader.GetString()!; switch (propertyName) @@ -131,23 +147,12 @@ public static RunCollectionPageToken FromToken(ContinuationToken pageToken) if (threadId is null) { - throw new ArgumentException("Failed to create MessageCollectionPageToken from provided pageToken.", nameof(pageToken)); + throw new ArgumentException("Failed to create RunsPageToken from provided pageToken.", nameof(pageToken)); } return new(threadId, limit, order, after, before); } - // Protocol - public static RunCollectionPageToken FromOptions(string threadId, int? limit, string? order, string? after, string? before) - => new RunCollectionPageToken(threadId, limit, order, after, before); - - private static RunCollectionPageToken? GetNextPageToken(string threadId, int? limit, string? order, string? after, string? before, bool hasMore) - { - if (!hasMore || after is null) - { - return null; - } - - return new RunCollectionPageToken(threadId, limit, order, after, before); - } + public static RunsPageToken FromOptions(string threadId, int? limit, string? order, string? after, string? before) + => new RunsPageToken(threadId, limit, order, after, before); } \ No newline at end of file From 818b6bd52abb6a0705f9d2ee79736bf7c6ee2b57 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Tue, 2 Jul 2024 10:00:04 -0700 Subject: [PATCH 47/72] Implement remaining Assistants endpoings --- .../Assistants/AssistantClient.Protocol.cs | 89 ++------- src/Custom/Assistants/AssistantClient.cs | 174 +++++++++++++----- .../AssistantsPageEnumerator.Convenience.cs | 21 +++ .../AssistantsPageEnumerator.cs | 123 +++++++++++++ src/To.Be.Generated/MessagesPageEnumerator.cs | 4 +- .../RunStepsPageEnumerator.Convenience.cs | 22 +++ src/To.Be.Generated/RunStepsPageEnumerator.cs | 140 ++++++++++++++ .../RunsPageEnumerator.Convenience.cs | 22 +++ src/To.Be.Generated/RunsPageEnumerator.cs | 131 +++++++++++++ 9 files changed, 602 insertions(+), 124 deletions(-) create mode 100644 src/To.Be.Generated/AssistantsPageEnumerator.Convenience.cs create mode 100644 src/To.Be.Generated/AssistantsPageEnumerator.cs create mode 100644 src/To.Be.Generated/RunStepsPageEnumerator.Convenience.cs create mode 100644 src/To.Be.Generated/RunStepsPageEnumerator.cs create mode 100644 src/To.Be.Generated/RunsPageEnumerator.Convenience.cs create mode 100644 src/To.Be.Generated/RunsPageEnumerator.cs diff --git a/src/Custom/Assistants/AssistantClient.Protocol.cs b/src/Custom/Assistants/AssistantClient.Protocol.cs index 022d05465..37bd66f93 100644 --- a/src/Custom/Assistants/AssistantClient.Protocol.cs +++ b/src/Custom/Assistants/AssistantClient.Protocol.cs @@ -2,6 +2,7 @@ using System.ClientModel; using System.ClientModel.Primitives; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; namespace OpenAI.Assistants; @@ -66,20 +67,8 @@ public virtual ClientResult CreateAssistant(BinaryContent content, RequestOption /// The response returned from the service. public virtual IAsyncEnumerable GetAssistantsAsync(int? limit, string order, string after, string before, RequestOptions options) { - AssistantsPageToken firstPageToken = AssistantsPageToken.FromOptions(limit, order, after, before); - return OpenAIPageCollectionHelpers.CreateProtocolAsync(firstPageToken, GetAssistantsPageAsync, AssistantsPageToken.FromToken, options); - } - - internal virtual async Task GetAssistantsPageAsync(ContinuationToken pageToken, RequestOptions options) - { - AssistantsPageToken token = AssistantsPageToken.FromToken(pageToken); - return await GetAssistantsPageAsync(token.Limit, token.Order, token.After, token.Before, options).ConfigureAwait(false); - } - - internal virtual async Task GetAssistantsPageAsync(int? limit, string order, string after, string before, RequestOptions options) - { - using PipelineMessage message = CreateGetAssistantsRequest(limit, order, after, before, options); - return ClientResult.FromResponse(await _pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); + IAsyncEnumerator enumerator = new AssistantsPageEnumerator(_pipeline, _endpoint, limit, order, after, before, options); + return PageCollectionHelpers.CreateAsync(enumerator); } /// @@ -108,20 +97,8 @@ internal virtual async Task GetAssistantsPageAsync(int? limit, str /// The response returned from the service. public virtual IEnumerable GetAssistants(int? limit, string order, string after, string before, RequestOptions options) { - AssistantsPageToken firstPageToken = AssistantsPageToken.FromOptions(limit, order, after, before); - return OpenAIPageCollectionHelpers.CreateProtocol(firstPageToken, GetAssistantsPage, AssistantsPageToken.FromToken, options); - } - - internal virtual ClientResult GetAssistantsPage(ContinuationToken pageToken, RequestOptions options) - { - AssistantsPageToken token = AssistantsPageToken.FromToken(pageToken); - return GetAssistantsPage(token.Limit, token.Order, token.After, token.Before, options); - } - - internal virtual ClientResult GetAssistantsPage(int? limit, string order, string after, string before, RequestOptions options) - { - using PipelineMessage message = CreateGetAssistantsRequest(limit, order, after, before, options); - return ClientResult.FromResponse(_pipeline.ProcessMessage(message, options)); + IEnumerator enumerator = new AssistantsPageEnumerator(_pipeline, _endpoint, limit, order, after, before, options); + return PageCollectionHelpers.Create(enumerator); } /// @@ -290,36 +267,16 @@ public virtual ClientResult CreateRun(string threadId, BinaryContent content, Re public virtual IAsyncEnumerable GetRunsAsync(string threadId, int? limit, string order, string after, string before, RequestOptions options) { - RunsPageToken firstPageToken = RunsPageToken.FromOptions(threadId, limit, order, after, before); - return OpenAIPageCollectionHelpers.CreateProtocolAsync(firstPageToken, GetRunsPageAsync, RunsPageToken.FromToken, options); - } - - internal async virtual Task GetRunsPageAsync(ContinuationToken pageToken, RequestOptions options) - { - RunsPageToken token = RunsPageToken.FromToken(pageToken); - return await GetRunsPageAsync(token.ThreadId, token.Limit, token.Order, token.After, token.Before, options).ConfigureAwait(false); + IAsyncEnumerator enumerator = new RunsPageEnumerator(_pipeline, _endpoint, threadId, limit, order, after, before, options); + return PageCollectionHelpers.CreateAsync(enumerator); } - /// - internal async virtual Task GetRunsPageAsync(string threadId, int? limit, string order, string after, string before, RequestOptions options) - => await _runSubClient.GetRunsAsync(threadId, limit, order, after, before, options).ConfigureAwait(false); - public virtual IEnumerable GetRuns(string threadId, int? limit, string order, string after, string before, RequestOptions options) { - RunsPageToken firstPageToken = RunsPageToken.FromOptions(threadId, limit, order, after, before); - return OpenAIPageCollectionHelpers.CreateProtocol(firstPageToken, GetRunsPage, RunsPageToken.FromToken, options); - } - - internal virtual ClientResult GetRunsPage(ContinuationToken pageToken, RequestOptions options) - { - RunsPageToken token = RunsPageToken.FromToken(pageToken); - return GetRunsPage(token.ThreadId, token.Limit, token.Order, token.After, token.Before, options); + IEnumerator enumerator = new RunsPageEnumerator(_pipeline, _endpoint, threadId, limit, order, after, before, options); + return PageCollectionHelpers.Create(enumerator); } - /// - internal virtual ClientResult GetRunsPage(string threadId, int? limit, string order, string after, string before, RequestOptions options) - => _runSubClient.GetRuns(threadId, limit, order, after, before, options); - /// public virtual Task GetRunAsync(string threadId, string runId, RequestOptions options) => _runSubClient.GetRunAsync(threadId, runId, options); @@ -354,36 +311,16 @@ public virtual ClientResult SubmitToolOutputsToRun(string threadId, string runId public virtual IAsyncEnumerable GetRunStepsAsync(string threadId, string runId, int? limit, string order, string after, string before, RequestOptions options) { - RunStepsPageToken firstPageToken = RunStepsPageToken.FromOptions(threadId, runId, limit, order, after, before); - return OpenAIPageCollectionHelpers.CreateProtocolAsync(firstPageToken, GetRunStepsPageAsync, RunStepsPageToken.FromToken, options); - } - - internal virtual async Task GetRunStepsPageAsync(ContinuationToken pageToken, RequestOptions options) - { - RunStepsPageToken token = RunStepsPageToken.FromToken(pageToken); - return await GetRunStepsPageAsync(token.ThreadId, token.RunId, token.Limit, token.Order, token.After, token.Before, options).ConfigureAwait(false); + IAsyncEnumerator enumerator = new RunStepsPageEnumerator(_pipeline, _endpoint, threadId, runId, limit, order, after, before, options); + return PageCollectionHelpers.CreateAsync(enumerator); } - /// - internal virtual async Task GetRunStepsPageAsync(string threadId, string runId, int? limit, string order, string after, string before, RequestOptions options) - => await _runSubClient.GetRunStepsAsync(threadId, runId, limit, order, after, before, options).ConfigureAwait(false); - public virtual IEnumerable GetRunSteps(string threadId, string runId, int? limit, string order, string after, string before, RequestOptions options) { - RunStepsPageToken firstPageToken = RunStepsPageToken.FromOptions(threadId, runId, limit, order, after, before); - return OpenAIPageCollectionHelpers.CreateProtocol(firstPageToken, GetRunStepsPage, RunStepsPageToken.FromToken, options); - } - - internal virtual ClientResult GetRunStepsPage(ContinuationToken pageToken, RequestOptions options) - { - RunStepsPageToken token = RunStepsPageToken.FromToken(pageToken); - return GetRunStepsPage(token.ThreadId, token.RunId, token.Limit, token.Order, token.After, token.Before, options); + IEnumerator enumerator = new RunStepsPageEnumerator(_pipeline, _endpoint, threadId, runId, limit, order, after, before, options); + return PageCollectionHelpers.Create(enumerator); } - /// - internal virtual ClientResult GetRunStepsPage(string threadId, string runId, int? limit, string order, string after, string before, RequestOptions options) - => _runSubClient.GetRunSteps(threadId, runId, limit, order, after, before, options); - /// public virtual Task GetRunStepAsync(string threadId, string runId, string stepId, RequestOptions options) => _runSubClient.GetRunStepAsync(threadId, runId, stepId, options); diff --git a/src/Custom/Assistants/AssistantClient.cs b/src/Custom/Assistants/AssistantClient.cs index f2b63f77a..bf004a48a 100644 --- a/src/Custom/Assistants/AssistantClient.cs +++ b/src/Custom/Assistants/AssistantClient.cs @@ -111,12 +111,14 @@ public virtual AsyncPageCollection GetAssistantsAsync( AssistantCollectionOptions options = default, CancellationToken cancellationToken = default) { - AssistantsPageToken firstPageToken = AssistantsPageToken.FromOptions(options); - return OpenAIPageCollectionHelpers.CreateAsync( - firstPageToken, - GetAssistantsPageAsync, - AssistantsPageToken.FromToken, + AssistantsPageEnumerator enumerator = new(_pipeline, _endpoint, + options?.PageSize, + options?.Order?.ToString(), + options?.AfterId, + options?.BeforeId, cancellationToken.ToRequestOptions()); + + return PageCollectionHelpers.CreateAsync(enumerator, enumerator.GetPageFromResult); } /// @@ -129,12 +131,17 @@ public virtual AsyncPageCollection GetAssistantsAsync( ContinuationToken firstPageToken, CancellationToken cancellationToken = default) { + Argument.AssertNotNull(firstPageToken, nameof(firstPageToken)); + AssistantsPageToken pageToken = AssistantsPageToken.FromToken(firstPageToken); - return OpenAIPageCollectionHelpers.CreateAsync( - firstPageToken, - GetAssistantsPageAsync, - AssistantsPageToken.FromToken, + AssistantsPageEnumerator enumerator = new(_pipeline, _endpoint, + pageToken.Limit, + pageToken.Order, + pageToken.After, + pageToken.Before, cancellationToken.ToRequestOptions()); + + return PageCollectionHelpers.CreateAsync(enumerator, enumerator.GetPageFromResult); } /// @@ -147,12 +154,14 @@ public virtual PageCollection GetAssistants( AssistantCollectionOptions options = default, CancellationToken cancellationToken = default) { - AssistantsPageToken firstPageToken = AssistantsPageToken.FromOptions(options); - return OpenAIPageCollectionHelpers.Create( - firstPageToken, - GetAssistantsPage, - AssistantsPageToken.FromToken, + AssistantsPageEnumerator enumerator = new(_pipeline, _endpoint, + options?.PageSize, + options?.Order?.ToString(), + options?.AfterId, + options?.BeforeId, cancellationToken.ToRequestOptions()); + + return PageCollectionHelpers.Create(enumerator, enumerator.GetPageFromResult); } /// @@ -165,12 +174,17 @@ public virtual PageCollection GetAssistants( ContinuationToken firstPageToken, CancellationToken cancellationToken = default) { + Argument.AssertNotNull(firstPageToken, nameof(firstPageToken)); + AssistantsPageToken pageToken = AssistantsPageToken.FromToken(firstPageToken); - return OpenAIPageCollectionHelpers.Create( - pageToken, - GetAssistantsPage, - AssistantsPageToken.FromToken, + AssistantsPageEnumerator enumerator = new(_pipeline, _endpoint, + pageToken.Limit, + pageToken.Order, + pageToken.After, + pageToken.Before, cancellationToken.ToRequestOptions()); + + return PageCollectionHelpers.Create(enumerator, enumerator.GetPageFromResult); } /// @@ -405,8 +419,9 @@ public virtual AsyncPageCollection GetMessagesAsync( ContinuationToken firstPageToken, CancellationToken cancellationToken = default) { - MessagesPageToken pageToken = MessagesPageToken.FromToken(firstPageToken); + Argument.AssertNotNull(firstPageToken, nameof(firstPageToken)); + MessagesPageToken pageToken = MessagesPageToken.FromToken(firstPageToken); MessagesPageEnumerator enumerator = new(_pipeline, _endpoint, pageToken.ThreadId, pageToken.Limit, @@ -450,7 +465,6 @@ public virtual PageCollection GetMessages( Argument.AssertNotNull(firstPageToken, nameof(firstPageToken)); MessagesPageToken pageToken = MessagesPageToken.FromToken(firstPageToken); - MessagesPageEnumerator enumerator = new(_pipeline, _endpoint, pageToken.ThreadId, pageToken.Limit, @@ -768,24 +782,33 @@ public virtual AsyncPageCollection GetRunsAsync( { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); - RunsPageToken firstPageToken = RunsPageToken.FromOptions(threadId, options); - return OpenAIPageCollectionHelpers.CreateAsync( - firstPageToken, - GetRunsPageAsync, - RunsPageToken.FromToken, + RunsPageEnumerator enumerator = new(_pipeline, _endpoint, + threadId, + options?.PageSize, + options?.Order?.ToString(), + options?.AfterId, + options?.BeforeId, cancellationToken.ToRequestOptions()); + + return PageCollectionHelpers.CreateAsync(enumerator, enumerator.GetPageFromResult); } public virtual AsyncPageCollection GetRunsAsync( ContinuationToken firstPageToken, CancellationToken cancellationToken = default) { + Argument.AssertNotNull(firstPageToken, nameof(firstPageToken)); + RunsPageToken pageToken = RunsPageToken.FromToken(firstPageToken); - return OpenAIPageCollectionHelpers.CreateAsync( - firstPageToken, - GetRunsPageAsync, - RunsPageToken.FromToken, + RunsPageEnumerator enumerator = new(_pipeline, _endpoint, + pageToken.ThreadId, + pageToken.Limit, + pageToken.Order, + pageToken.After, + pageToken.Before, cancellationToken.ToRequestOptions()); + + return PageCollectionHelpers.CreateAsync(enumerator, enumerator.GetPageFromResult); } /// @@ -802,21 +825,33 @@ public virtual PageCollection GetRuns( { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); - throw new NotImplementedException(); - //return CreatePageable((continuationToken, pageSize) - // => GetRuns(threadId, pageSize, resultOrder?.ToString(), continuationToken, null, cancellationToken.ToRequestOptions())); + RunsPageEnumerator enumerator = new(_pipeline, _endpoint, + threadId, + options?.PageSize, + options?.Order?.ToString(), + options?.AfterId, + options?.BeforeId, + cancellationToken.ToRequestOptions()); + + return PageCollectionHelpers.Create(enumerator, enumerator.GetPageFromResult); } public virtual PageCollection GetRuns( ContinuationToken firstPageToken, CancellationToken cancellationToken = default) { + Argument.AssertNotNull(firstPageToken, nameof(firstPageToken)); + RunsPageToken pageToken = RunsPageToken.FromToken(firstPageToken); - return OpenAIPageCollectionHelpers.Create( - firstPageToken, - GetRunsPage, - RunsPageToken.FromToken, + RunsPageEnumerator enumerator = new(_pipeline, _endpoint, + pageToken.ThreadId, + pageToken.Limit, + pageToken.Order, + pageToken.After, + pageToken.Before, cancellationToken.ToRequestOptions()); + + return PageCollectionHelpers.Create(enumerator, enumerator.GetPageFromResult); } /// @@ -1003,12 +1038,35 @@ public virtual AsyncPageCollection GetRunStepsAsync( Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); Argument.AssertNotNullOrEmpty(runId, nameof(runId)); - RunStepsPageToken firstPageToken = RunStepsPageToken.FromOptions(threadId, runId, options); - return OpenAIPageCollectionHelpers.CreateAsync( - firstPageToken, - GetRunStepsPageAsync, - RunStepsPageToken.FromToken, + RunStepsPageEnumerator enumerator = new(_pipeline, _endpoint, + threadId, + runId, + options?.PageSize, + options?.Order?.ToString(), + options?.AfterId, + options?.BeforeId, + cancellationToken.ToRequestOptions()); + + return PageCollectionHelpers.CreateAsync(enumerator, enumerator.GetPageFromResult); + } + + public virtual AsyncPageCollection GetRunStepsAsync( + ContinuationToken firstPageToken, + CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(firstPageToken, nameof(firstPageToken)); + + RunStepsPageToken pageToken = RunStepsPageToken.FromToken(firstPageToken); + RunStepsPageEnumerator enumerator = new(_pipeline, _endpoint, + pageToken.ThreadId, + pageToken.RunId, + pageToken.Limit, + pageToken.Order, + pageToken.After, + pageToken.Before, cancellationToken.ToRequestOptions()); + + return PageCollectionHelpers.CreateAsync(enumerator, enumerator.GetPageFromResult); } /// @@ -1028,14 +1086,38 @@ public virtual PageCollection GetRunSteps( Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); Argument.AssertNotNullOrEmpty(runId, nameof(runId)); - RunStepsPageToken firstPageToken = RunStepsPageToken.FromOptions(threadId, runId, options); - return OpenAIPageCollectionHelpers.Create( - firstPageToken, - GetRunStepsPage, - RunStepsPageToken.FromToken, + RunStepsPageEnumerator enumerator = new(_pipeline, _endpoint, + threadId, + runId, + options?.PageSize, + options?.Order?.ToString(), + options?.AfterId, + options?.BeforeId, + cancellationToken.ToRequestOptions()); + + return PageCollectionHelpers.Create(enumerator, enumerator.GetPageFromResult); + } + + public virtual PageCollection GetRunSteps( + ContinuationToken firstPageToken, + CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(firstPageToken, nameof(firstPageToken)); + + RunStepsPageToken pageToken = RunStepsPageToken.FromToken(firstPageToken); + RunStepsPageEnumerator enumerator = new(_pipeline, _endpoint, + pageToken.ThreadId, + pageToken.RunId, + pageToken.Limit, + pageToken.Order, + pageToken.After, + pageToken.Before, cancellationToken.ToRequestOptions()); + + return PageCollectionHelpers.Create(enumerator, enumerator.GetPageFromResult); } + /// /// Gets a single run step from a run. /// diff --git a/src/To.Be.Generated/AssistantsPageEnumerator.Convenience.cs b/src/To.Be.Generated/AssistantsPageEnumerator.Convenience.cs new file mode 100644 index 000000000..8e4189a1b --- /dev/null +++ b/src/To.Be.Generated/AssistantsPageEnumerator.Convenience.cs @@ -0,0 +1,21 @@ +using System.ClientModel; +using System.ClientModel.Primitives; + +#nullable enable + +namespace OpenAI.Assistants; + +internal partial class AssistantsPageEnumerator : PageResultEnumerator +{ + public PageResult GetPageFromResult(ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + + InternalListAssistantsResponse list = ModelReaderWriter.Read(response.Content)!; + + AssistantsPageToken pageToken = AssistantsPageToken.FromOptions(_limit, _order, _after, _before); + AssistantsPageToken? nextPageToken = pageToken.GetNextPageToken(list.HasMore, list.LastId); + + return PageResult.Create(list.Data, pageToken, nextPageToken, response); + } +} \ No newline at end of file diff --git a/src/To.Be.Generated/AssistantsPageEnumerator.cs b/src/To.Be.Generated/AssistantsPageEnumerator.cs new file mode 100644 index 000000000..6c8d40b58 --- /dev/null +++ b/src/To.Be.Generated/AssistantsPageEnumerator.cs @@ -0,0 +1,123 @@ +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Text.Json; +using System.Threading.Tasks; + +#nullable enable + +namespace OpenAI.Assistants; + +internal partial class AssistantsPageEnumerator : PageResultEnumerator +{ + private readonly ClientPipeline _pipeline; + private readonly Uri _endpoint; + + private readonly int? _limit; + private readonly string _order; + + // Note: this one is special + private string _after; + + private readonly string _before; + private readonly RequestOptions _options; + + public AssistantsPageEnumerator( + ClientPipeline pipeline, + Uri endpoint, + int? limit, string order, string after, string before, + RequestOptions options) + { + _pipeline = pipeline; + _endpoint = endpoint; + + _limit = limit; + _order = order; + _after = after; + _before = before; + _options = options; + } + + public override async Task GetFirstAsync() + => await GetAssistantsPageAsync(_limit, _order, _after, _before, _options).ConfigureAwait(false); + + public override ClientResult GetFirst() + => GetAssistantsPage(_limit, _order, _after, _before, _options); + + public override async Task GetNextAsync(ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + + using JsonDocument doc = JsonDocument.Parse(response.Content); + _after = doc.RootElement.GetProperty("last_id"u8).GetString()!; + + return await GetAssistantsPageAsync(_limit, _order, _after, _before, _options).ConfigureAwait(false); + } + + public override ClientResult GetNext(ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + + using JsonDocument doc = JsonDocument.Parse(response.Content); + _after = doc.RootElement.GetProperty("last_id"u8).GetString()!; + + return GetAssistantsPage(_limit, _order, _after, _before, _options); + } + + public override bool HasNext(ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + + using JsonDocument doc = JsonDocument.Parse(response.Content); + bool hasMore = doc.RootElement.GetProperty("has_more"u8).GetBoolean(); + + return hasMore; + } + + // Note: these are the protocol methods - they are generated here + internal virtual async Task GetAssistantsPageAsync(int? limit, string order, string after, string before, RequestOptions options) + { + using PipelineMessage message = CreateGetAssistantsRequest(limit, order, after, before, options); + return ClientResult.FromResponse(await _pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); + } + + internal virtual ClientResult GetAssistantsPage(int? limit, string order, string after, string before, RequestOptions options) + { + using PipelineMessage message = CreateGetAssistantsRequest(limit, order, after, before, options); + return ClientResult.FromResponse(_pipeline.ProcessMessage(message, options)); + } + + private PipelineMessage CreateGetAssistantsRequest(int? limit, string order, string after, string before, RequestOptions options) + { + var message = _pipeline.CreateMessage(); + message.ResponseClassifier = PipelineMessageClassifier200; + var request = message.Request; + request.Method = "GET"; + var uri = new ClientUriBuilder(); + uri.Reset(_endpoint); + uri.AppendPath("/assistants", false); + if (limit != null) + { + uri.AppendQuery("limit", limit.Value, true); + } + if (order != null) + { + uri.AppendQuery("order", order, true); + } + if (after != null) + { + uri.AppendQuery("after", after, true); + } + if (before != null) + { + uri.AppendQuery("before", before, true); + } + request.Uri = uri.ToUri(); + request.Headers.Set("Accept", "application/json"); + message.Apply(options); + return message; + } + + private static PipelineMessageClassifier? _pipelineMessageClassifier200; + private static PipelineMessageClassifier PipelineMessageClassifier200 => _pipelineMessageClassifier200 ??= PipelineMessageClassifier.Create(stackalloc ushort[] { 200 }); +} diff --git a/src/To.Be.Generated/MessagesPageEnumerator.cs b/src/To.Be.Generated/MessagesPageEnumerator.cs index bf5774ab4..b631834c5 100644 --- a/src/To.Be.Generated/MessagesPageEnumerator.cs +++ b/src/To.Be.Generated/MessagesPageEnumerator.cs @@ -77,7 +77,7 @@ public override bool HasNext(ClientResult result) } // Note: these are the protocol methods - they are generated here - public virtual async Task GetMessagesPageAsync(string threadId, int? limit, string order, string after, string before, RequestOptions options) + internal virtual async Task GetMessagesPageAsync(string threadId, int? limit, string order, string after, string before, RequestOptions options) { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); @@ -85,7 +85,7 @@ public virtual async Task GetMessagesPageAsync(string threadId, in return ClientResult.FromResponse(await _pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); } - public virtual ClientResult GetMessagesPage(string threadId, int? limit, string order, string after, string before, RequestOptions options) + internal virtual ClientResult GetMessagesPage(string threadId, int? limit, string order, string after, string before, RequestOptions options) { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); diff --git a/src/To.Be.Generated/RunStepsPageEnumerator.Convenience.cs b/src/To.Be.Generated/RunStepsPageEnumerator.Convenience.cs new file mode 100644 index 000000000..9d59ffb2a --- /dev/null +++ b/src/To.Be.Generated/RunStepsPageEnumerator.Convenience.cs @@ -0,0 +1,22 @@ +using System.ClientModel; +using System.ClientModel.Primitives; + +#nullable enable + +namespace OpenAI.Assistants; + +internal partial class RunStepsPageEnumerator : PageResultEnumerator +{ + // Note: this is the deserialization method that converts protocol to convenience + public PageResult GetPageFromResult(ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + + InternalListRunStepsResponse list = ModelReaderWriter.Read(response.Content)!; + + RunStepsPageToken pageToken = RunStepsPageToken.FromOptions(_threadId, _runId, _limit, _order, _after, _before); + RunStepsPageToken? nextPageToken = pageToken.GetNextPageToken(list.HasMore, list.LastId); + + return PageResult.Create(list.Data, pageToken, nextPageToken, response); + } +} \ No newline at end of file diff --git a/src/To.Be.Generated/RunStepsPageEnumerator.cs b/src/To.Be.Generated/RunStepsPageEnumerator.cs new file mode 100644 index 000000000..e8f3c0041 --- /dev/null +++ b/src/To.Be.Generated/RunStepsPageEnumerator.cs @@ -0,0 +1,140 @@ +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Text.Json; +using System.Threading.Tasks; + +#nullable enable + +namespace OpenAI.Assistants; + +internal partial class RunStepsPageEnumerator : PageResultEnumerator +{ + private readonly ClientPipeline _pipeline; + private readonly Uri _endpoint; + + private readonly string _threadId; + private readonly string _runId; + + private readonly int? _limit; + private readonly string _order; + + // Note: this one is special + private string _after; + + private readonly string _before; + private readonly RequestOptions _options; + + public RunStepsPageEnumerator( + ClientPipeline pipeline, + Uri endpoint, + string threadId, string runId, + int? limit, string order, string after, string before, + RequestOptions options) + { + _pipeline = pipeline; + _endpoint = endpoint; + + _threadId = threadId; + _runId = runId; + + _limit = limit; + _order = order; + _after = after; + _before = before; + _options = options; + } + + public override async Task GetFirstAsync() + => await GetRunStepsPageAsync(_threadId, _runId, _limit, _order, _after, _before, _options).ConfigureAwait(false); + + public override ClientResult GetFirst() + => GetRunStepsPage(_threadId, _runId, _limit, _order, _after, _before, _options); + + public override async Task GetNextAsync(ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + + using JsonDocument doc = JsonDocument.Parse(response.Content); + _after = doc.RootElement.GetProperty("last_id"u8).GetString()!; + + return await GetRunStepsPageAsync(_threadId, _runId, _limit, _order, _after, _before, _options).ConfigureAwait(false); + } + + public override ClientResult GetNext(ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + + using JsonDocument doc = JsonDocument.Parse(response.Content); + _after = doc.RootElement.GetProperty("last_id"u8).GetString()!; + + return GetRunStepsPage(_threadId, _runId, _limit, _order, _after, _before, _options); + } + + public override bool HasNext(ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + + using JsonDocument doc = JsonDocument.Parse(response.Content); + bool hasMore = doc.RootElement.GetProperty("has_more"u8).GetBoolean(); + + return hasMore; + } + + // Note: these are the protocol methods - they are generated here + internal async virtual Task GetRunStepsPageAsync(string threadId, string runId, int? limit, string order, string after, string before, RequestOptions options) + { + Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); + Argument.AssertNotNullOrEmpty(runId, nameof(runId)); + + using PipelineMessage message = CreateGetRunStepsRequest(threadId, runId, limit, order, after, before, options); + return ClientResult.FromResponse(await _pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); + } + + internal virtual ClientResult GetRunStepsPage(string threadId, string runId, int? limit, string order, string after, string before, RequestOptions options) + { + Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); + Argument.AssertNotNullOrEmpty(runId, nameof(runId)); + + using PipelineMessage message = CreateGetRunStepsRequest(threadId, runId, limit, order, after, before, options); + return ClientResult.FromResponse(_pipeline.ProcessMessage(message, options)); + } + + private PipelineMessage CreateGetRunStepsRequest(string threadId, string runId, int? limit, string order, string after, string before, RequestOptions options) + { + var message = _pipeline.CreateMessage(); + message.ResponseClassifier = PipelineMessageClassifier200; + var request = message.Request; + request.Method = "GET"; + var uri = new ClientUriBuilder(); + uri.Reset(_endpoint); + uri.AppendPath("/threads/", false); + uri.AppendPath(threadId, true); + uri.AppendPath("/runs/", false); + uri.AppendPath(runId, true); + uri.AppendPath("/steps", false); + if (limit != null) + { + uri.AppendQuery("limit", limit.Value, true); + } + if (order != null) + { + uri.AppendQuery("order", order, true); + } + if (after != null) + { + uri.AppendQuery("after", after, true); + } + if (before != null) + { + uri.AppendQuery("before", before, true); + } + request.Uri = uri.ToUri(); + request.Headers.Set("Accept", "application/json"); + message.Apply(options); + return message; + } + + private static PipelineMessageClassifier? _pipelineMessageClassifier200; + private static PipelineMessageClassifier PipelineMessageClassifier200 => _pipelineMessageClassifier200 ??= PipelineMessageClassifier.Create(stackalloc ushort[] { 200 }); +} diff --git a/src/To.Be.Generated/RunsPageEnumerator.Convenience.cs b/src/To.Be.Generated/RunsPageEnumerator.Convenience.cs new file mode 100644 index 000000000..993b85a49 --- /dev/null +++ b/src/To.Be.Generated/RunsPageEnumerator.Convenience.cs @@ -0,0 +1,22 @@ +using System.ClientModel; +using System.ClientModel.Primitives; + +#nullable enable + +namespace OpenAI.Assistants; + +internal partial class RunsPageEnumerator : PageResultEnumerator +{ + // Note: this is the deserialization method that converts protocol to convenience + public PageResult GetPageFromResult(ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + + InternalListRunsResponse list = ModelReaderWriter.Read(response.Content)!; + + RunsPageToken pageToken = RunsPageToken.FromOptions(_threadId, _limit, _order, _after, _before); + RunsPageToken? nextPageToken = pageToken.GetNextPageToken(list.HasMore, list.LastId); + + return PageResult.Create(list.Data, pageToken, nextPageToken, response); + } +} \ No newline at end of file diff --git a/src/To.Be.Generated/RunsPageEnumerator.cs b/src/To.Be.Generated/RunsPageEnumerator.cs new file mode 100644 index 000000000..b9c618963 --- /dev/null +++ b/src/To.Be.Generated/RunsPageEnumerator.cs @@ -0,0 +1,131 @@ +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Text.Json; +using System.Threading.Tasks; + +#nullable enable + +namespace OpenAI.Assistants; + +internal partial class RunsPageEnumerator : PageResultEnumerator +{ + private readonly ClientPipeline _pipeline; + private readonly Uri _endpoint; + + private readonly string _threadId; + private readonly int? _limit; + private readonly string _order; + + // Note: this one is special + private string _after; + + private readonly string _before; + private readonly RequestOptions _options; + + public RunsPageEnumerator( + ClientPipeline pipeline, + Uri endpoint, + string threadId, int? limit, string order, string after, string before, + RequestOptions options) + { + _pipeline = pipeline; + _endpoint = endpoint; + + _threadId = threadId; + _limit = limit; + _order = order; + _after = after; + _before = before; + _options = options; + } + + public override async Task GetFirstAsync() + => await GetRunsPageAsync(_threadId, _limit, _order, _after, _before, _options).ConfigureAwait(false); + + public override ClientResult GetFirst() + => GetRunsPage(_threadId, _limit, _order, _after, _before, _options); + + public override async Task GetNextAsync(ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + + using JsonDocument doc = JsonDocument.Parse(response.Content); + _after = doc.RootElement.GetProperty("last_id"u8).GetString()!; + + return await GetRunsPageAsync(_threadId, _limit, _order, _after, _before, _options).ConfigureAwait(false); + } + + public override ClientResult GetNext(ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + + using JsonDocument doc = JsonDocument.Parse(response.Content); + _after = doc.RootElement.GetProperty("last_id"u8).GetString()!; + + return GetRunsPage(_threadId, _limit, _order, _after, _before, _options); + } + + public override bool HasNext(ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + + using JsonDocument doc = JsonDocument.Parse(response.Content); + bool hasMore = doc.RootElement.GetProperty("has_more"u8).GetBoolean(); + + return hasMore; + } + + // Note: these are the protocol methods - they are generated here + internal async virtual Task GetRunsPageAsync(string threadId, int? limit, string order, string after, string before, RequestOptions options) + { + Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); + + using PipelineMessage message = CreateGetRunsRequest(threadId, limit, order, after, before, options); + return ClientResult.FromResponse(await _pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); + } + + internal virtual ClientResult GetRunsPage(string threadId, int? limit, string order, string after, string before, RequestOptions options) + { + Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); + + using PipelineMessage message = CreateGetRunsRequest(threadId, limit, order, after, before, options); + return ClientResult.FromResponse(_pipeline.ProcessMessage(message, options)); + } + + private PipelineMessage CreateGetRunsRequest(string threadId, int? limit, string order, string after, string before, RequestOptions options) + { + var message = _pipeline.CreateMessage(); + message.ResponseClassifier = PipelineMessageClassifier200; + var request = message.Request; + request.Method = "GET"; + var uri = new ClientUriBuilder(); + uri.Reset(_endpoint); + uri.AppendPath("/threads/", false); + uri.AppendPath(threadId, true); + uri.AppendPath("/runs", false); + if (limit != null) + { + uri.AppendQuery("limit", limit.Value, true); + } + if (order != null) + { + uri.AppendQuery("order", order, true); + } + if (after != null) + { + uri.AppendQuery("after", after, true); + } + if (before != null) + { + uri.AppendQuery("before", before, true); + } + request.Uri = uri.ToUri(); + request.Headers.Set("Accept", "application/json"); + message.Apply(options); + return message; + } + + private static PipelineMessageClassifier? _pipelineMessageClassifier200; + private static PipelineMessageClassifier PipelineMessageClassifier200 => _pipelineMessageClassifier200 ??= PipelineMessageClassifier.Create(stackalloc ushort[] { 200 }); +} From 34264b5fc4b0c8ae7b7d9d0e26a68b33ec5192f7 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Tue, 2 Jul 2024 10:59:24 -0700 Subject: [PATCH 48/72] Implement vector store paginated endpoints --- .../Assistants/AssistantClient.Protocol.cs | 14 + .../VectorStoreClient.Protocol.cs | 41 +-- src/Custom/VectorStores/VectorStoreClient.cs | 301 +++++++++++++----- .../VectorStoreCollectionOptions.cs | 31 ++ ...orStoreFileAssociationCollectionOptions.cs | 37 +++ ...reFileBatchesPageEnumerator.Convenience.cs | 22 ++ .../VectorStoreFileBatchesPageEnumerator.cs | 142 +++++++++ .../VectorStoreFileBatchesPageToken.cs | 183 +++++++++++ ...torStoreFilesPageEnumerator.Convenience.cs | 22 ++ .../VectorStoreFilesPageEnumerator.cs | 138 ++++++++ .../VectorStoreFilesPageToken.cs | 171 ++++++++++ .../VectorStoresPageEnumerator.Convenience.cs | 22 ++ .../VectorStoresPageEnumerator.cs | 123 +++++++ src/To.Be.Generated/VectorStoresPageToken.cs | 142 +++++++++ 14 files changed, 1296 insertions(+), 93 deletions(-) create mode 100644 src/Custom/VectorStores/VectorStoreCollectionOptions.cs create mode 100644 src/Custom/VectorStores/VectorStoreFileAssociationCollectionOptions.cs create mode 100644 src/To.Be.Generated/VectorStoreFileBatchesPageEnumerator.Convenience.cs create mode 100644 src/To.Be.Generated/VectorStoreFileBatchesPageEnumerator.cs create mode 100644 src/To.Be.Generated/VectorStoreFileBatchesPageToken.cs create mode 100644 src/To.Be.Generated/VectorStoreFilesPageEnumerator.Convenience.cs create mode 100644 src/To.Be.Generated/VectorStoreFilesPageEnumerator.cs create mode 100644 src/To.Be.Generated/VectorStoreFilesPageToken.cs create mode 100644 src/To.Be.Generated/VectorStoresPageEnumerator.Convenience.cs create mode 100644 src/To.Be.Generated/VectorStoresPageEnumerator.cs create mode 100644 src/To.Be.Generated/VectorStoresPageToken.cs diff --git a/src/Custom/Assistants/AssistantClient.Protocol.cs b/src/Custom/Assistants/AssistantClient.Protocol.cs index 37bd66f93..aba6fd330 100644 --- a/src/Custom/Assistants/AssistantClient.Protocol.cs +++ b/src/Custom/Assistants/AssistantClient.Protocol.cs @@ -217,12 +217,16 @@ public virtual ClientResult CreateMessage(string threadId, BinaryContent content public virtual IAsyncEnumerable GetMessagesAsync(string threadId, int? limit, string order, string after, string before, RequestOptions options) { + Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); + IAsyncEnumerator enumerator = new MessagesPageEnumerator(_pipeline, _endpoint, threadId, limit, order, after, before, options); return PageCollectionHelpers.CreateAsync(enumerator); } public virtual IEnumerable GetMessages(string threadId, int? limit, string order, string after, string before, RequestOptions options) { + Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); + IEnumerator enumerator = new MessagesPageEnumerator(_pipeline, _endpoint, threadId, limit, order, after, before, options); return PageCollectionHelpers.Create(enumerator); } @@ -267,12 +271,16 @@ public virtual ClientResult CreateRun(string threadId, BinaryContent content, Re public virtual IAsyncEnumerable GetRunsAsync(string threadId, int? limit, string order, string after, string before, RequestOptions options) { + Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); + IAsyncEnumerator enumerator = new RunsPageEnumerator(_pipeline, _endpoint, threadId, limit, order, after, before, options); return PageCollectionHelpers.CreateAsync(enumerator); } public virtual IEnumerable GetRuns(string threadId, int? limit, string order, string after, string before, RequestOptions options) { + Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); + IEnumerator enumerator = new RunsPageEnumerator(_pipeline, _endpoint, threadId, limit, order, after, before, options); return PageCollectionHelpers.Create(enumerator); } @@ -311,12 +319,18 @@ public virtual ClientResult SubmitToolOutputsToRun(string threadId, string runId public virtual IAsyncEnumerable GetRunStepsAsync(string threadId, string runId, int? limit, string order, string after, string before, RequestOptions options) { + Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); + Argument.AssertNotNullOrEmpty(runId, nameof(runId)); + IAsyncEnumerator enumerator = new RunStepsPageEnumerator(_pipeline, _endpoint, threadId, runId, limit, order, after, before, options); return PageCollectionHelpers.CreateAsync(enumerator); } public virtual IEnumerable GetRunSteps(string threadId, string runId, int? limit, string order, string after, string before, RequestOptions options) { + Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); + Argument.AssertNotNullOrEmpty(runId, nameof(runId)); + IEnumerator enumerator = new RunStepsPageEnumerator(_pipeline, _endpoint, threadId, runId, limit, order, after, before, options); return PageCollectionHelpers.Create(enumerator); } diff --git a/src/Custom/VectorStores/VectorStoreClient.Protocol.cs b/src/Custom/VectorStores/VectorStoreClient.Protocol.cs index 311be206b..4b6f2866f 100644 --- a/src/Custom/VectorStores/VectorStoreClient.Protocol.cs +++ b/src/Custom/VectorStores/VectorStoreClient.Protocol.cs @@ -1,7 +1,10 @@ -using System; +using OpenAI.Assistants; +using System; using System.ClientModel; using System.ClientModel.Primitives; +using System.Collections.Generic; using System.ComponentModel; +using System.Threading; using System.Threading.Tasks; namespace OpenAI.VectorStores; @@ -49,10 +52,10 @@ public partial class VectorStoreClient /// Service returned a non-success status code. /// The response returned from the service. [EditorBrowsable(EditorBrowsableState.Never)] - public virtual async Task GetVectorStoresAsync(int? limit, string order, string after, string before, RequestOptions options) + public virtual IAsyncEnumerable GetVectorStoresAsync(int? limit, string order, string after, string before, RequestOptions options) { - using PipelineMessage message = CreateGetVectorStoresRequest(limit, order, after, before, options); - return ClientResult.FromResponse(await _pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); + IAsyncEnumerator enumerator = new VectorStoresPageEnumerator(_pipeline, _endpoint, limit, order, after, before, options); + return PageCollectionHelpers.CreateAsync(enumerator); } /// @@ -80,10 +83,10 @@ public virtual async Task GetVectorStoresAsync(int? limit, string /// Service returned a non-success status code. /// The response returned from the service. [EditorBrowsable(EditorBrowsableState.Never)] - public virtual ClientResult GetVectorStores(int? limit, string order, string after, string before, RequestOptions options) + public virtual IEnumerable GetVectorStores(int? limit, string order, string after, string before, RequestOptions options) { - using PipelineMessage message = CreateGetVectorStoresRequest(limit, order, after, before, options); - return ClientResult.FromResponse(_pipeline.ProcessMessage(message, options)); + IEnumerator enumerator = new VectorStoresPageEnumerator(_pipeline, _endpoint, limit, order, after, before, options); + return PageCollectionHelpers.Create(enumerator); } /// @@ -256,12 +259,12 @@ public virtual ClientResult DeleteVectorStore(string vectorStoreId, RequestOptio /// Service returned a non-success status code. /// The response returned from the service. [EditorBrowsable(EditorBrowsableState.Never)] - public virtual async Task GetFileAssociationsAsync(string vectorStoreId, int? limit, string order, string after, string before, string filter, RequestOptions options) + public virtual IAsyncEnumerable GetFileAssociationsAsync(string vectorStoreId, int? limit, string order, string after, string before, string filter, RequestOptions options) { Argument.AssertNotNullOrEmpty(vectorStoreId, nameof(vectorStoreId)); - using PipelineMessage message = CreateGetVectorStoreFilesRequest(vectorStoreId, limit, order, after, before, filter, options); - return ClientResult.FromResponse(await _pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); + IAsyncEnumerator enumerator = new VectorStoreFilesPageEnumerator(_pipeline, _endpoint, vectorStoreId, limit, order, after, before, filter, options); + return PageCollectionHelpers.CreateAsync(enumerator); } /// @@ -293,12 +296,12 @@ public virtual async Task GetFileAssociationsAsync(string vectorSt /// Service returned a non-success status code. /// The response returned from the service. [EditorBrowsable(EditorBrowsableState.Never)] - public virtual ClientResult GetFileAssociations(string vectorStoreId, int? limit, string order, string after, string before, string filter, RequestOptions options) + public virtual IEnumerable GetFileAssociations(string vectorStoreId, int? limit, string order, string after, string before, string filter, RequestOptions options) { Argument.AssertNotNullOrEmpty(vectorStoreId, nameof(vectorStoreId)); - using PipelineMessage message = CreateGetVectorStoreFilesRequest(vectorStoreId, limit, order, after, before, filter, options); - return ClientResult.FromResponse(_pipeline.ProcessMessage(message, options)); + IEnumerator enumerator = new MessagesPageEnumerator(_pipeline, _endpoint, vectorStoreId, limit, order, after, before, options); + return PageCollectionHelpers.Create(enumerator); } /// @@ -571,13 +574,13 @@ public virtual ClientResult CancelBatchFileJob(string vectorStoreId, string batc /// Service returned a non-success status code. /// The response returned from the service. [EditorBrowsable(EditorBrowsableState.Never)] - public virtual async Task GetFileAssociationsAsync(string vectorStoreId, string batchId, int? limit, string order, string after, string before, string filter, RequestOptions options) + public virtual IAsyncEnumerable GetFileAssociationsAsync(string vectorStoreId, string batchId, int? limit, string order, string after, string before, string filter, RequestOptions options) { Argument.AssertNotNullOrEmpty(vectorStoreId, nameof(vectorStoreId)); Argument.AssertNotNullOrEmpty(batchId, nameof(batchId)); - using PipelineMessage message = CreateGetFilesInVectorStoreBatchesRequest(vectorStoreId, batchId, limit, order, after, before, filter, options); - return ClientResult.FromResponse(await _pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); + IAsyncEnumerator enumerator = new VectorStoreFileBatchesPageEnumerator(_pipeline, _endpoint, vectorStoreId, batchId, limit, order, after, before, filter, options); + return PageCollectionHelpers.CreateAsync(enumerator); } /// @@ -610,12 +613,12 @@ public virtual async Task GetFileAssociationsAsync(string vectorSt /// Service returned a non-success status code. /// The response returned from the service. [EditorBrowsable(EditorBrowsableState.Never)] - public virtual ClientResult GetFileAssociations(string vectorStoreId, string batchId, int? limit, string order, string after, string before, string filter, RequestOptions options) + public virtual IEnumerable GetFileAssociations(string vectorStoreId, string batchId, int? limit, string order, string after, string before, string filter, RequestOptions options) { Argument.AssertNotNullOrEmpty(vectorStoreId, nameof(vectorStoreId)); Argument.AssertNotNullOrEmpty(batchId, nameof(batchId)); - using PipelineMessage message = CreateGetFilesInVectorStoreBatchesRequest(vectorStoreId, batchId, limit, order, after, before, filter, options); - return ClientResult.FromResponse(_pipeline.ProcessMessage(message, options)); + IEnumerator enumerator = new VectorStoreFileBatchesPageEnumerator(_pipeline, _endpoint, vectorStoreId, batchId, limit, order, after, before, filter, options); + return PageCollectionHelpers.Create(enumerator); } } diff --git a/src/Custom/VectorStores/VectorStoreClient.cs b/src/Custom/VectorStores/VectorStoreClient.cs index 60ec1c83e..18e318ad1 100644 --- a/src/Custom/VectorStores/VectorStoreClient.cs +++ b/src/Custom/VectorStores/VectorStoreClient.cs @@ -1,9 +1,7 @@ -using OpenAI.Assistants; -using OpenAI.Files; +using OpenAI.Files; using System; using System.ClientModel; using System.ClientModel.Primitives; -using System.Collections; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Threading; @@ -51,7 +49,7 @@ public VectorStoreClient(ApiKeyCredential credential, OpenAIClientOptions option OpenAIClient.CreatePipeline(OpenAIClient.GetApiKey(credential, requireExplicitCredential: true), options), OpenAIClient.GetEndpoint(options), options) - {} + { } /// /// Initializes a new instance of that will use an API key from the OPENAI_API_KEY @@ -68,7 +66,7 @@ public VectorStoreClient(OpenAIClientOptions options = null) OpenAIClient.CreatePipeline(OpenAIClient.GetApiKey(), options), OpenAIClient.GetEndpoint(options), options) - {} + { } /// Initializes a new instance of VectorStoreClient. /// The HTTP pipeline for sending and receiving REST requests and responses. @@ -138,39 +136,80 @@ public virtual ClientResult DeleteVectorStore(string vectorStoreId, Cancel /// /// Gets the collection of instances for the configured organization. /// - /// - /// The order that results should appear in the list according to their created_at - /// timestamp. - /// + /// Options describing the collection to return. /// A token that can be used to cancel this method call. /// /// A collection of instances that can be asynchronously enumerated via /// await foreach. /// - public virtual AsyncPageCollection GetVectorStoresAsync(ListOrder? resultOrder = null, CancellationToken cancellationToken = default) + public virtual AsyncPageCollection GetVectorStoresAsync( + VectorStoreCollectionOptions options = default, + CancellationToken cancellationToken = default) { - throw new NotImplementedException(); - //return CreateAsyncPageable((continuationToken, pageSize) - // => GetVectorStoresAsync(pageSize, resultOrder?.ToString(), continuationToken, null, cancellationToken.ToRequestOptions())); + VectorStoresPageEnumerator enumerator = new(_pipeline, _endpoint, + options?.PageSize, + options?.Order?.ToString(), + options?.AfterId, + options?.BeforeId, + cancellationToken.ToRequestOptions()); + + return PageCollectionHelpers.CreateAsync(enumerator, enumerator.GetPageFromResult); + } + + public virtual AsyncPageCollection GetVectorStoresAsync( + ContinuationToken firstPageToken, + CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(firstPageToken, nameof(firstPageToken)); + + VectorStoresPageToken pageToken = VectorStoresPageToken.FromToken(firstPageToken); + VectorStoresPageEnumerator enumerator = new(_pipeline, _endpoint, + pageToken.Limit, + pageToken.Order, + pageToken.After, + pageToken.Before, + cancellationToken.ToRequestOptions()); + + return PageCollectionHelpers.CreateAsync(enumerator, enumerator.GetPageFromResult); } /// /// Gets the collection of instances for the configured organization. /// - /// - /// The order that results should appear in the list according to their created_at - /// timestamp. - /// + /// Options describing the collection to return. /// A token that can be used to cancel this method call. /// /// A collection of instances that can be synchronously enumerated via foreach. /// - public virtual PageCollection GetVectorStores(ListOrder? resultOrder = null, CancellationToken cancellationToken = default) + public virtual PageCollection GetVectorStores( + VectorStoreCollectionOptions options = default, + CancellationToken cancellationToken = default) + { + VectorStoresPageEnumerator enumerator = new(_pipeline, _endpoint, + options?.PageSize, + options?.Order?.ToString(), + options?.AfterId, + options?.BeforeId, + cancellationToken.ToRequestOptions()); + + return PageCollectionHelpers.Create(enumerator, enumerator.GetPageFromResult); + } + + public virtual PageCollection GetVectorStores( + ContinuationToken firstPageToken, + CancellationToken cancellationToken = default) { - throw new NotImplementedException(); + Argument.AssertNotNull(firstPageToken, nameof(firstPageToken)); + + VectorStoresPageToken pageToken = VectorStoresPageToken.FromToken(firstPageToken); + VectorStoresPageEnumerator enumerator = new(_pipeline, _endpoint, + pageToken.Limit, + pageToken.Order, + pageToken.After, + pageToken.Before, + cancellationToken.ToRequestOptions()); - //return CreatePageable((continuationToken, pageSize) - // => GetVectorStores(pageSize, resultOrder?.ToString(), continuationToken, null, cancellationToken.ToRequestOptions())); + return PageCollectionHelpers.Create(enumerator, enumerator.GetPageFromResult); } /// @@ -216,13 +255,7 @@ public virtual ClientResult AddFileToVectorStore(str /// /// The ID of the vector store to enumerate the file associations of. /// - /// - /// The order that results should appear in the list according to their created_at - /// timestamp. - /// - /// - /// A status filter that file associations must match to be included in the collection. - /// + /// Options describing the collection to return. /// A token that can be used to cancel this method call. /// /// A collection of instances that can be asynchronously enumerated via @@ -230,16 +263,40 @@ public virtual ClientResult AddFileToVectorStore(str /// public virtual AsyncPageCollection GetFileAssociationsAsync( string vectorStoreId, - ListOrder? resultOrder = null, - VectorStoreFileStatusFilter? filter = null, + VectorStoreFileAssociationCollectionOptions options = default, CancellationToken cancellationToken = default) { Argument.AssertNotNullOrEmpty(vectorStoreId, nameof(vectorStoreId)); - throw new NotImplementedException(); - //return CreateAsyncPageable( - // (continuationToken, pageSize) => GetFileAssociationsAsync( - // vectorStoreId, pageSize, resultOrder?.ToString(), continuationToken, null, filter?.ToString(), cancellationToken.ToRequestOptions())); + VectorStoreFilesPageEnumerator enumerator = new(_pipeline, _endpoint, + vectorStoreId, + options?.PageSize, + options?.Order?.ToString(), + options?.AfterId, + options?.BeforeId, + options?.Filter?.ToString(), + cancellationToken.ToRequestOptions()); + + return PageCollectionHelpers.CreateAsync(enumerator, enumerator.GetPageFromResult); + } + + public virtual AsyncPageCollection GetFileAssociationsAsync( + ContinuationToken firstPageToken, + CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(firstPageToken, nameof(firstPageToken)); + + VectorStoreFilesPageToken pageToken = VectorStoreFilesPageToken.FromToken(firstPageToken); + VectorStoreFilesPageEnumerator enumerator = new(_pipeline, _endpoint, + pageToken.VectorStoreId, + pageToken.Limit, + pageToken.Order, + pageToken.After, + pageToken.Before, + pageToken.Filter, + cancellationToken.ToRequestOptions()); + + return PageCollectionHelpers.CreateAsync(enumerator, enumerator.GetPageFromResult); } /// @@ -249,26 +306,48 @@ public virtual AsyncPageCollection GetFileAssociatio /// /// The ID of the vector store to enumerate the file associations of. /// - /// - /// The order that results should appear in the list according to their created_at - /// timestamp. - /// - /// - /// A status filter that file associations must match to be included in the collection. - /// + /// Options describing the collection to return. /// A token that can be used to cancel this method call. /// /// A collection of instances that can be synchronously enumerated via /// foreach. /// - public virtual PageCollection GetFileAssociations(string vectorStoreId, ListOrder? resultOrder = null, VectorStoreFileStatusFilter? filter = null, CancellationToken cancellationToken = default) + public virtual PageCollection GetFileAssociations( + string vectorStoreId, + VectorStoreFileAssociationCollectionOptions options = default, + CancellationToken cancellationToken = default) { Argument.AssertNotNullOrEmpty(vectorStoreId, nameof(vectorStoreId)); - throw new NotImplementedException(); - //return CreatePageable( - // (continuationToken, pageSize) => GetFileAssociations( - // vectorStoreId, pageSize, resultOrder?.ToString(), continuationToken, null, filter?.ToString(), cancellationToken.ToRequestOptions())); + VectorStoreFilesPageEnumerator enumerator = new(_pipeline, _endpoint, + vectorStoreId, + options?.PageSize, + options?.Order?.ToString(), + options?.AfterId, + options?.BeforeId, + options?.Filter?.ToString(), + cancellationToken.ToRequestOptions()); + + return PageCollectionHelpers.Create(enumerator, enumerator.GetPageFromResult); + } + + public virtual PageCollection GetFileAssociations( + ContinuationToken firstPageToken, + CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(firstPageToken, nameof(firstPageToken)); + + VectorStoreFilesPageToken pageToken = VectorStoreFilesPageToken.FromToken(firstPageToken); + VectorStoreFilesPageEnumerator enumerator = new(_pipeline, _endpoint, + pageToken.VectorStoreId, + pageToken.Limit, + pageToken.Order, + pageToken.After, + pageToken.Before, + pageToken.Filter, + cancellationToken.ToRequestOptions()); + + return PageCollectionHelpers.Create(enumerator, enumerator.GetPageFromResult); } /// @@ -281,7 +360,7 @@ public virtual PageCollection GetFileAssociations(st /// A instance. public virtual async Task> GetFileAssociationAsync( string vectorStoreId, - string fileId, + string fileId, CancellationToken cancellationToken = default) { Argument.AssertNotNullOrEmpty(vectorStoreId, nameof(vectorStoreId)); @@ -303,7 +382,7 @@ public virtual async Task> GetFileAssoc /// A instance. public virtual ClientResult GetFileAssociation( string vectorStoreId, - string fileId, + string fileId, CancellationToken cancellationToken = default) { Argument.AssertNotNullOrEmpty(vectorStoreId, nameof(vectorStoreId)); @@ -481,13 +560,7 @@ public virtual ClientResult CancelBatchFileJob(string v /// /// The ID of the batch file job that was previously scheduled. /// - /// - /// The order that results should appear in the list according to their created_at - /// timestamp. - /// - /// - /// A status filter that file associations must match to be included in the collection. - /// + /// Options describing the collection to return. /// A token that can be used to cancel this method call. /// /// A collection of instances that can be asynchronously enumerated via @@ -496,17 +569,60 @@ public virtual ClientResult CancelBatchFileJob(string v public virtual AsyncPageCollection GetFileAssociationsAsync( string vectorStoreId, string batchJobId, - ListOrder? resultOrder = null, - VectorStoreFileStatusFilter? filter = null, + VectorStoreFileAssociationCollectionOptions options = default, CancellationToken cancellationToken = default) { Argument.AssertNotNullOrEmpty(vectorStoreId, nameof(vectorStoreId)); Argument.AssertNotNullOrEmpty(batchJobId, nameof(batchJobId)); - throw new NotImplementedException(); - //return CreateAsyncPageable( - // (continuationToken, pageSize) => GetFileAssociationsAsync - // (vectorStoreId, batchJobId, pageSize, resultOrder?.ToString(), continuationToken, null, filter?.ToString(), cancellationToken.ToRequestOptions())); + VectorStoreFileBatchesPageEnumerator enumerator = new(_pipeline, _endpoint, + vectorStoreId, + batchJobId, + options?.PageSize, + options?.Order?.ToString(), + options?.AfterId, + options?.BeforeId, + options?.Filter?.ToString(), + cancellationToken.ToRequestOptions()); + + return PageCollectionHelpers.CreateAsync(enumerator, enumerator.GetPageFromResult); + } + + public virtual AsyncPageCollection GetFileAssociationsAsync( + string vectorStoreId, + string batchJobId, + ContinuationToken firstPageToken, + CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(firstPageToken, nameof(firstPageToken)); + + VectorStoreFileBatchesPageToken pageToken = VectorStoreFileBatchesPageToken.FromToken(firstPageToken); + + if (vectorStoreId != pageToken.VectorStoreId) + { + throw new ArgumentException( + "Invalid page token. 'vectorStoreId' value does not match page token value.", + nameof(vectorStoreId)); + } + + if (batchJobId != pageToken.BatchId) + { + throw new ArgumentException( + "Invalid page token. 'batchJobId' value does not match page token value.", + nameof(vectorStoreId)); + } + + VectorStoreFileBatchesPageEnumerator enumerator = new(_pipeline, _endpoint, + pageToken.VectorStoreId, + pageToken.BatchId, + pageToken.Limit, + pageToken.Order, + pageToken.After, + pageToken.Before, + pageToken.Filter, + cancellationToken.ToRequestOptions()); + + return PageCollectionHelpers.CreateAsync(enumerator, enumerator.GetPageFromResult); } /// @@ -519,13 +635,7 @@ public virtual AsyncPageCollection GetFileAssociatio /// /// The ID of the batch file job that was previously scheduled. /// - /// - /// The order that results should appear in the list according to their created_at - /// timestamp. - /// - /// - /// A status filter that file associations must match to be included in the collection. - /// + /// Options describing the collection to return. /// A token that can be used to cancel this method call. /// /// A collection of instances that can be synchronously enumerated via @@ -534,16 +644,59 @@ public virtual AsyncPageCollection GetFileAssociatio public virtual PageCollection GetFileAssociations( string vectorStoreId, string batchJobId, - ListOrder? resultOrder = null, - VectorStoreFileStatusFilter? filter = null, + VectorStoreFileAssociationCollectionOptions options = default, CancellationToken cancellationToken = default) { Argument.AssertNotNullOrEmpty(vectorStoreId, nameof(vectorStoreId)); Argument.AssertNotNullOrEmpty(batchJobId, nameof(batchJobId)); - throw new NotImplementedException(); - //return CreatePageable( - // (continuationToken, pageSize) => GetFileAssociations - // (vectorStoreId, batchJobId, pageSize, resultOrder?.ToString(), continuationToken, null, filter?.ToString(), cancellationToken.ToRequestOptions())); + VectorStoreFileBatchesPageEnumerator enumerator = new(_pipeline, _endpoint, + vectorStoreId, + batchJobId, + options?.PageSize, + options?.Order?.ToString(), + options?.AfterId, + options?.BeforeId, + options?.Filter?.ToString(), + cancellationToken.ToRequestOptions()); + + return PageCollectionHelpers.Create(enumerator, enumerator.GetPageFromResult); + } + + public virtual PageCollection GetFileAssociations( + string vectorStoreId, + string batchJobId, + ContinuationToken firstPageToken, + CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(firstPageToken, nameof(firstPageToken)); + + VectorStoreFileBatchesPageToken pageToken = VectorStoreFileBatchesPageToken.FromToken(firstPageToken); + + if (vectorStoreId != pageToken.VectorStoreId) + { + throw new ArgumentException( + "Invalid page token. 'vectorStoreId' value does not match page token value.", + nameof(vectorStoreId)); + } + + if (batchJobId != pageToken.BatchId) + { + throw new ArgumentException( + "Invalid page token. 'batchJobId' value does not match page token value.", + nameof(vectorStoreId)); + } + + VectorStoreFileBatchesPageEnumerator enumerator = new(_pipeline, _endpoint, + pageToken.VectorStoreId, + pageToken.BatchId, + pageToken.Limit, + pageToken.Order, + pageToken.After, + pageToken.Before, + pageToken.Filter, + cancellationToken.ToRequestOptions()); + + return PageCollectionHelpers.Create(enumerator, enumerator.GetPageFromResult); } } diff --git a/src/Custom/VectorStores/VectorStoreCollectionOptions.cs b/src/Custom/VectorStores/VectorStoreCollectionOptions.cs new file mode 100644 index 000000000..2361aebde --- /dev/null +++ b/src/Custom/VectorStores/VectorStoreCollectionOptions.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace OpenAI.VectorStores; + +public class VectorStoreCollectionOptions +{ + public VectorStoreCollectionOptions() { } + + /// + /// The order that results should appear in the list according to + /// their created_at timestamp. + /// + public ListOrder? Order { get; init; } + + /// + /// The number of values to return in a page result. + /// + public int? PageSize { get; init; } + + /// + /// The id of the item preceeding the first item in the collection. + /// + public string AfterId { get; init; } + + /// + /// The id of the item following the last item in the collection. + /// + public string BeforeId { get; init; } +} diff --git a/src/Custom/VectorStores/VectorStoreFileAssociationCollectionOptions.cs b/src/Custom/VectorStores/VectorStoreFileAssociationCollectionOptions.cs new file mode 100644 index 000000000..0b8bb697d --- /dev/null +++ b/src/Custom/VectorStores/VectorStoreFileAssociationCollectionOptions.cs @@ -0,0 +1,37 @@ +using OpenAI.Files; +using System; +using System.Collections.Generic; +using System.Text; + +namespace OpenAI.VectorStores; + +public class VectorStoreFileAssociationCollectionOptions +{ + public VectorStoreFileAssociationCollectionOptions() { } + + /// + /// The order that results should appear in the list according to + /// their created_at timestamp. + /// + public ListOrder? Order { get; init; } + + /// + /// The number of values to return in a page result. + /// + public int? PageSize { get; init; } + + /// + /// The id of the item preceeding the first item in the collection. + /// + public string AfterId { get; init; } + + /// + /// The id of the item following the last item in the collection. + /// + public string BeforeId { get; init; } + + /// + /// A status filter that file associations must match to be included in the collection. + /// + public VectorStoreFileStatusFilter? Filter { get; init; } +} diff --git a/src/To.Be.Generated/VectorStoreFileBatchesPageEnumerator.Convenience.cs b/src/To.Be.Generated/VectorStoreFileBatchesPageEnumerator.Convenience.cs new file mode 100644 index 000000000..94a14c497 --- /dev/null +++ b/src/To.Be.Generated/VectorStoreFileBatchesPageEnumerator.Convenience.cs @@ -0,0 +1,22 @@ +using System.ClientModel; +using System.ClientModel.Primitives; + +#nullable enable + +namespace OpenAI.VectorStores; + +internal partial class VectorStoreFileBatchesPageEnumerator : PageResultEnumerator +{ + // Note: this is the deserialization method that converts protocol to convenience + public PageResult GetPageFromResult(ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + + InternalListVectorStoreFilesResponse list = ModelReaderWriter.Read(response.Content)!; + + VectorStoreFilesPageToken pageToken = VectorStoreFilesPageToken.FromOptions(_vectorStoreId, _limit, _order, _after, _before, _filter); + VectorStoreFilesPageToken? nextPageToken = pageToken.GetNextPageToken(list.HasMore, list.LastId); + + return PageResult.Create(list.Data, pageToken, nextPageToken, response); + } +} \ No newline at end of file diff --git a/src/To.Be.Generated/VectorStoreFileBatchesPageEnumerator.cs b/src/To.Be.Generated/VectorStoreFileBatchesPageEnumerator.cs new file mode 100644 index 000000000..e6829ad82 --- /dev/null +++ b/src/To.Be.Generated/VectorStoreFileBatchesPageEnumerator.cs @@ -0,0 +1,142 @@ +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Text.Json; +using System.Threading.Tasks; + +#nullable enable + +namespace OpenAI.VectorStores; + +internal partial class VectorStoreFileBatchesPageEnumerator : PageResultEnumerator +{ + private readonly ClientPipeline _pipeline; + private readonly Uri _endpoint; + + private readonly string _vectorStoreId; + private readonly string _batchId; + private readonly int? _limit; + private readonly string? _order; + + // Note: this one is special + private string? _after; + + private readonly string? _before; + private readonly string? _filter; + private readonly RequestOptions _options; + + public VectorStoreFileBatchesPageEnumerator( + ClientPipeline pipeline, + Uri endpoint, + string vectorStoreId, string batchId, int? limit, string? order, string? after, string? before, string? filter, + RequestOptions options) + { + _pipeline = pipeline; + _endpoint = endpoint; + + _vectorStoreId = vectorStoreId; + _batchId = batchId; + _limit = limit; + _order = order; + _after = after; + _before = before; + _options = options; + } + + public override async Task GetFirstAsync() + => await GetFileAssociationsAsync(_vectorStoreId, _batchId, _limit, _order, _after, _before, _filter, _options).ConfigureAwait(false); + + public override ClientResult GetFirst() + => GetFileAssociations(_vectorStoreId, _batchId, _limit, _order, _after, _before, _filter, _options); + + public override async Task GetNextAsync(ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + + using JsonDocument doc = JsonDocument.Parse(response.Content); + _after = doc.RootElement.GetProperty("last_id"u8).GetString()!; + + return await GetFileAssociationsAsync(_vectorStoreId, _batchId, _limit, _order, _after, _before, _filter, _options).ConfigureAwait(false); + } + + public override ClientResult GetNext(ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + + using JsonDocument doc = JsonDocument.Parse(response.Content); + _after = doc.RootElement.GetProperty("last_id"u8).GetString()!; + + return GetFileAssociations(_vectorStoreId, _batchId, _limit, _order, _after, _before, _filter, _options); + } + + public override bool HasNext(ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + + using JsonDocument doc = JsonDocument.Parse(response.Content); + bool hasMore = doc.RootElement.GetProperty("has_more"u8).GetBoolean(); + + return hasMore; + } + + // Note: these are the protocol methods - they are generated here + internal virtual async Task GetFileAssociationsAsync(string vectorStoreId, string batchId, int? limit, string? order, string? after, string? before, string? filter, RequestOptions options) + { + Argument.AssertNotNullOrEmpty(vectorStoreId, nameof(vectorStoreId)); + Argument.AssertNotNullOrEmpty(batchId, nameof(batchId)); + + using PipelineMessage message = CreateGetFilesInVectorStoreBatchesRequest(vectorStoreId, batchId, limit, order, after, before, filter, options); + return ClientResult.FromResponse(await _pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); + } + + internal virtual ClientResult GetFileAssociations(string vectorStoreId, string batchId, int? limit, string? order, string? after, string? before, string? filter, RequestOptions options) + { + Argument.AssertNotNullOrEmpty(vectorStoreId, nameof(vectorStoreId)); + Argument.AssertNotNullOrEmpty(batchId, nameof(batchId)); + + using PipelineMessage message = CreateGetFilesInVectorStoreBatchesRequest(vectorStoreId, batchId, limit, order, after, before, filter, options); + return ClientResult.FromResponse(_pipeline.ProcessMessage(message, options)); + } + + internal PipelineMessage CreateGetFilesInVectorStoreBatchesRequest(string vectorStoreId, string batchId, int? limit, string? order, string? after, string? before, string? filter, RequestOptions options) + { + var message = _pipeline.CreateMessage(); + message.ResponseClassifier = PipelineMessageClassifier200; + var request = message.Request; + request.Method = "GET"; + var uri = new ClientUriBuilder(); + uri.Reset(_endpoint); + uri.AppendPath("/vector_stores/", false); + uri.AppendPath(vectorStoreId, true); + uri.AppendPath("/file_batches/", false); + uri.AppendPath(batchId, true); + uri.AppendPath("/files", false); + if (limit != null) + { + uri.AppendQuery("limit", limit.Value, true); + } + if (order != null) + { + uri.AppendQuery("order", order, true); + } + if (after != null) + { + uri.AppendQuery("after", after, true); + } + if (before != null) + { + uri.AppendQuery("before", before, true); + } + if (filter != null) + { + uri.AppendQuery("filter", filter, true); + } + request.Uri = uri.ToUri(); + request.Headers.Set("Accept", "application/json"); + message.Apply(options); + return message; + } + + private static PipelineMessageClassifier? _pipelineMessageClassifier200; + private static PipelineMessageClassifier PipelineMessageClassifier200 => _pipelineMessageClassifier200 ??= PipelineMessageClassifier.Create(stackalloc ushort[] { 200 }); +} diff --git a/src/To.Be.Generated/VectorStoreFileBatchesPageToken.cs b/src/To.Be.Generated/VectorStoreFileBatchesPageToken.cs new file mode 100644 index 000000000..96e732737 --- /dev/null +++ b/src/To.Be.Generated/VectorStoreFileBatchesPageToken.cs @@ -0,0 +1,183 @@ +using System; +using System.ClientModel; +using System.Diagnostics; +using System.IO; +using System.Text.Json; + +#nullable enable + +namespace OpenAI.VectorStores; + +internal class VectorStoreFileBatchesPageToken : ContinuationToken +{ + public VectorStoreFileBatchesPageToken(string vectorStoreId,string batchId, int? limit, string? order, string? after, string? before, string? filter) + { + VectorStoreId = vectorStoreId; + BatchId = batchId; + + Limit = limit; + Order = order; + After = after; + Before = before; + Filter = filter; + } + + public string VectorStoreId { get; } + + public string BatchId { get; } + + public int? Limit { get; } + + public string? Order { get; } + + public string? After { get; } + + public string? Before { get; } + + public string? Filter { get; } + + public override BinaryData ToBytes() + { + using MemoryStream stream = new(); + using Utf8JsonWriter writer = new(stream); + + writer.WriteStartObject(); + writer.WriteString("vectorStoreId", VectorStoreId); + writer.WriteString("batchId", BatchId); + + if (Limit.HasValue) + { + writer.WriteNumber("limit", Limit.Value); + } + + if (Order is not null) + { + writer.WriteString("order", Order); + } + + if (After is not null) + { + writer.WriteString("after", After); + } + + if (Before is not null) + { + writer.WriteString("before", Before); + } + + if (Filter is not null) + { + writer.WriteString("filter", Filter); + } + + writer.WriteEndObject(); + + writer.Flush(); + stream.Position = 0; + + return BinaryData.FromStream(stream); + } + + public VectorStoreFileBatchesPageToken? GetNextPageToken(bool hasMore, string? lastId) + { + if (!hasMore || lastId is null) + { + return null; + } + + return new(VectorStoreId, BatchId, Limit, Order, lastId, Before, Filter); + } + + public static VectorStoreFileBatchesPageToken FromToken(ContinuationToken pageToken) + { + if (pageToken is VectorStoreFileBatchesPageToken token) + { + return token; + } + + BinaryData data = pageToken.ToBytes(); + + if (data.ToMemory().Length == 0) + { + throw new ArgumentException("Failed to create VectorStoreFileBatchesPageToken from provided pageToken.", nameof(pageToken)); + } + + Utf8JsonReader reader = new(data); + + string vectorStoreId = null!; + string batchId = null!; + int? limit = null; + string? order = null; + string? after = null; + string? before = null; + string? filter = null; + + reader.Read(); + + Debug.Assert(reader.TokenType == JsonTokenType.StartObject); + + while (reader.Read()) + { + if (reader.TokenType == JsonTokenType.EndObject) + { + break; + } + + Debug.Assert(reader.TokenType == JsonTokenType.PropertyName); + + string propertyName = reader.GetString()!; + + switch (propertyName) + { + case "vectorStoreId": + reader.Read(); + Debug.Assert(reader.TokenType == JsonTokenType.String); + vectorStoreId = reader.GetString()!; + break; + case "batchId": + reader.Read(); + Debug.Assert(reader.TokenType == JsonTokenType.String); + vectorStoreId = reader.GetString()!; + break; + case "limit": + reader.Read(); + Debug.Assert(reader.TokenType == JsonTokenType.Number); + limit = reader.GetInt32(); + break; + case "order": + reader.Read(); + Debug.Assert(reader.TokenType == JsonTokenType.String); + order = reader.GetString(); + break; + case "after": + reader.Read(); + Debug.Assert(reader.TokenType == JsonTokenType.String); + after = reader.GetString(); + break; + case "before": + reader.Read(); + Debug.Assert(reader.TokenType == JsonTokenType.String); + before = reader.GetString(); + break; + case "filter": + reader.Read(); + Debug.Assert(reader.TokenType == JsonTokenType.String); + filter = reader.GetString(); + break; + default: + throw new JsonException($"Unrecognized property '{propertyName}'."); + } + } + + if (vectorStoreId is null || + batchId is null) + { + throw new ArgumentException("Failed to create VectorStoreFileBatchesPageToken from provided pageToken.", nameof(pageToken)); + } + + return new(vectorStoreId, batchId, limit, order, after, before, filter); + } + + public static VectorStoreFileBatchesPageToken FromOptions(string vectorStoreId, string batchId, int? limit, string? order, string? after, string? before, string? filter) + => new(vectorStoreId, batchId, limit, order, after, before, filter); +} \ No newline at end of file diff --git a/src/To.Be.Generated/VectorStoreFilesPageEnumerator.Convenience.cs b/src/To.Be.Generated/VectorStoreFilesPageEnumerator.Convenience.cs new file mode 100644 index 000000000..bc6109564 --- /dev/null +++ b/src/To.Be.Generated/VectorStoreFilesPageEnumerator.Convenience.cs @@ -0,0 +1,22 @@ +using System.ClientModel; +using System.ClientModel.Primitives; + +#nullable enable + +namespace OpenAI.VectorStores; + +internal partial class VectorStoreFilesPageEnumerator : PageResultEnumerator +{ + // Note: this is the deserialization method that converts protocol to convenience + public PageResult GetPageFromResult(ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + + InternalListVectorStoreFilesResponse list = ModelReaderWriter.Read(response.Content)!; + + VectorStoreFilesPageToken pageToken = VectorStoreFilesPageToken.FromOptions(_vectorStoreId, _limit, _order, _after, _before, _filter); + VectorStoreFilesPageToken? nextPageToken = pageToken.GetNextPageToken(list.HasMore, list.LastId); + + return PageResult.Create(list.Data, pageToken, nextPageToken, response); + } +} \ No newline at end of file diff --git a/src/To.Be.Generated/VectorStoreFilesPageEnumerator.cs b/src/To.Be.Generated/VectorStoreFilesPageEnumerator.cs new file mode 100644 index 000000000..a2bc090f1 --- /dev/null +++ b/src/To.Be.Generated/VectorStoreFilesPageEnumerator.cs @@ -0,0 +1,138 @@ +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Text.Json; +using System.Threading.Tasks; + +#nullable enable + +namespace OpenAI.VectorStores; + +internal partial class VectorStoreFilesPageEnumerator : PageResultEnumerator +{ + private readonly ClientPipeline _pipeline; + private readonly Uri _endpoint; + + private readonly string _vectorStoreId; + private readonly int? _limit; + private readonly string? _order; + + // Note: this one is special + private string? _after; + + private readonly string? _before; + private readonly string? _filter; + private readonly RequestOptions _options; + + public VectorStoreFilesPageEnumerator( + ClientPipeline pipeline, + Uri endpoint, + string vectorStoreId, + int? limit, string? order, string? after, string? before, string? filter, + RequestOptions options) + { + _pipeline = pipeline; + _endpoint = endpoint; + + _vectorStoreId = vectorStoreId; + _limit = limit; + _order = order; + _after = after; + _before = before; + _filter = filter; + _options = options; + } + + public override async Task GetFirstAsync() + => await GetFileAssociationsAsync(_vectorStoreId, _limit, _order, _after, _before, _filter, _options).ConfigureAwait(false); + + public override ClientResult GetFirst() + => GetFileAssociations(_vectorStoreId, _limit, _order, _after, _before, _filter, _options); + + public override async Task GetNextAsync(ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + + using JsonDocument doc = JsonDocument.Parse(response.Content); + _after = doc.RootElement.GetProperty("last_id"u8).GetString()!; + + return await GetFileAssociationsAsync(_vectorStoreId, _limit, _order, _after, _before, _filter, _options).ConfigureAwait(false); + } + + public override ClientResult GetNext(ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + + using JsonDocument doc = JsonDocument.Parse(response.Content); + _after = doc.RootElement.GetProperty("last_id"u8).GetString()!; + + return GetFileAssociations(_vectorStoreId, _limit, _order, _after, _before, _filter, _options); + } + + public override bool HasNext(ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + + using JsonDocument doc = JsonDocument.Parse(response.Content); + bool hasMore = doc.RootElement.GetProperty("has_more"u8).GetBoolean(); + + return hasMore; + } + + // Note: these are the protocol methods - they are generated here + internal virtual async Task GetFileAssociationsAsync(string vectorStoreId, int? limit, string? order, string? after, string? before, string? filter, RequestOptions options) + { + Argument.AssertNotNullOrEmpty(vectorStoreId, nameof(vectorStoreId)); + + using PipelineMessage message = CreateGetVectorStoreFilesRequest(vectorStoreId, limit, order, after, before, filter, options); + return ClientResult.FromResponse(await _pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); + } + + internal virtual ClientResult GetFileAssociations(string vectorStoreId, int? limit, string? order, string? after, string? before, string? filter, RequestOptions options) + { + Argument.AssertNotNullOrEmpty(vectorStoreId, nameof(vectorStoreId)); + + using PipelineMessage message = CreateGetVectorStoreFilesRequest(vectorStoreId, limit, order, after, before, filter, options); + return ClientResult.FromResponse(_pipeline.ProcessMessage(message, options)); + } + + internal PipelineMessage CreateGetVectorStoreFilesRequest(string vectorStoreId, int? limit, string? order, string? after, string? before, string? filter, RequestOptions options) + { + var message = _pipeline.CreateMessage(); + message.ResponseClassifier = PipelineMessageClassifier200; + var request = message.Request; + request.Method = "GET"; + var uri = new ClientUriBuilder(); + uri.Reset(_endpoint); + uri.AppendPath("/vector_stores/", false); + uri.AppendPath(vectorStoreId, true); + uri.AppendPath("/files", false); + if (limit != null) + { + uri.AppendQuery("limit", limit.Value, true); + } + if (order != null) + { + uri.AppendQuery("order", order, true); + } + if (after != null) + { + uri.AppendQuery("after", after, true); + } + if (before != null) + { + uri.AppendQuery("before", before, true); + } + if (filter != null) + { + uri.AppendQuery("filter", filter, true); + } + request.Uri = uri.ToUri(); + request.Headers.Set("Accept", "application/json"); + message.Apply(options); + return message; + } + + private static PipelineMessageClassifier? _pipelineMessageClassifier200; + private static PipelineMessageClassifier PipelineMessageClassifier200 => _pipelineMessageClassifier200 ??= PipelineMessageClassifier.Create(stackalloc ushort[] { 200 }); +} diff --git a/src/To.Be.Generated/VectorStoreFilesPageToken.cs b/src/To.Be.Generated/VectorStoreFilesPageToken.cs new file mode 100644 index 000000000..fa86af2e4 --- /dev/null +++ b/src/To.Be.Generated/VectorStoreFilesPageToken.cs @@ -0,0 +1,171 @@ +using System; +using System.ClientModel; +using System.Diagnostics; +using System.IO; +using System.Text.Json; + +#nullable enable + +namespace OpenAI.VectorStores; + +internal class VectorStoreFilesPageToken : ContinuationToken +{ + public VectorStoreFilesPageToken(string vectorStoreId, int? limit, string? order, string? after, string? before, string? filter) + { + VectorStoreId = vectorStoreId; + + Limit = limit; + Order = order; + After = after; + Before = before; + Filter = filter; + } + public string VectorStoreId { get; } + + public int? Limit { get; } + + public string? Order { get; } + + public string? After { get; } + + public string? Before { get; } + + public string? Filter { get; } + + public override BinaryData ToBytes() + { + using MemoryStream stream = new(); + using Utf8JsonWriter writer = new(stream); + + writer.WriteStartObject(); + writer.WriteString("vectorStoreId", VectorStoreId); + + if (Limit.HasValue) + { + writer.WriteNumber("limit", Limit.Value); + } + + if (Order is not null) + { + writer.WriteString("order", Order); + } + + if (After is not null) + { + writer.WriteString("after", After); + } + + if (Before is not null) + { + writer.WriteString("before", Before); + } + + if (Filter is not null) + { + writer.WriteString("filter", Filter); + } + + writer.WriteEndObject(); + + writer.Flush(); + stream.Position = 0; + + return BinaryData.FromStream(stream); + } + + public VectorStoreFilesPageToken? GetNextPageToken(bool hasMore, string? lastId) + { + if (!hasMore || lastId is null) + { + return null; + } + + return new(VectorStoreId, Limit, Order, lastId, Before, Filter); + } + + public static VectorStoreFilesPageToken FromToken(ContinuationToken pageToken) + { + if (pageToken is VectorStoreFilesPageToken token) + { + return token; + } + + BinaryData data = pageToken.ToBytes(); + + if (data.ToMemory().Length == 0) + { + throw new ArgumentException("Failed to create VectorStoreFilesPageToken from provided pageToken.", nameof(pageToken)); + } + + Utf8JsonReader reader = new(data); + + string vectorStoreId = null!; + int? limit = null; + string? order = null; + string? after = null; + string? before = null; + string? filter = null; + + reader.Read(); + + Debug.Assert(reader.TokenType == JsonTokenType.StartObject); + + while (reader.Read()) + { + if (reader.TokenType == JsonTokenType.EndObject) + { + break; + } + + Debug.Assert(reader.TokenType == JsonTokenType.PropertyName); + + string propertyName = reader.GetString()!; + + switch (propertyName) + { + case "vectorStoreId": + reader.Read(); + Debug.Assert(reader.TokenType == JsonTokenType.String); + vectorStoreId = reader.GetString()!; + break; + case "limit": + reader.Read(); + Debug.Assert(reader.TokenType == JsonTokenType.Number); + limit = reader.GetInt32(); + break; + case "order": + reader.Read(); + Debug.Assert(reader.TokenType == JsonTokenType.String); + order = reader.GetString(); + break; + case "after": + reader.Read(); + Debug.Assert(reader.TokenType == JsonTokenType.String); + after = reader.GetString(); + break; + case "before": + reader.Read(); + Debug.Assert(reader.TokenType == JsonTokenType.String); + before = reader.GetString(); + break; + case "filter": + reader.Read(); + Debug.Assert(reader.TokenType == JsonTokenType.String); + filter = reader.GetString(); + break; + default: + throw new JsonException($"Unrecognized property '{propertyName}'."); + } + } + + if (vectorStoreId is null) + { + throw new ArgumentException("Failed to create VectorStoreFilesPageToken from provided pageToken.", nameof(pageToken)); + } + + return new(vectorStoreId, limit, order, after, before, filter); + } + + public static VectorStoreFilesPageToken FromOptions(string vectorStoreId, int? limit, string? order, string? after, string? before, string? filter) + => new(vectorStoreId, limit, order, after, before, filter); +} \ No newline at end of file diff --git a/src/To.Be.Generated/VectorStoresPageEnumerator.Convenience.cs b/src/To.Be.Generated/VectorStoresPageEnumerator.Convenience.cs new file mode 100644 index 000000000..ca097e8a7 --- /dev/null +++ b/src/To.Be.Generated/VectorStoresPageEnumerator.Convenience.cs @@ -0,0 +1,22 @@ +using System.ClientModel; +using System.ClientModel.Primitives; + +#nullable enable + +namespace OpenAI.VectorStores; + +internal partial class VectorStoresPageEnumerator : PageResultEnumerator +{ + // Note: this is the deserialization method that converts protocol to convenience + public PageResult GetPageFromResult(ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + + InternalListVectorStoresResponse list = ModelReaderWriter.Read(response.Content)!; + + VectorStoresPageToken pageToken = VectorStoresPageToken.FromOptions(_limit, _order, _after, _before); + VectorStoresPageToken? nextPageToken = pageToken.GetNextPageToken(list.HasMore, list.LastId); + + return PageResult.Create(list.Data, pageToken, nextPageToken, response); + } +} \ No newline at end of file diff --git a/src/To.Be.Generated/VectorStoresPageEnumerator.cs b/src/To.Be.Generated/VectorStoresPageEnumerator.cs new file mode 100644 index 000000000..25800b1df --- /dev/null +++ b/src/To.Be.Generated/VectorStoresPageEnumerator.cs @@ -0,0 +1,123 @@ +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Text.Json; +using System.Threading.Tasks; + +#nullable enable + +namespace OpenAI.VectorStores; + +internal partial class VectorStoresPageEnumerator : PageResultEnumerator +{ + private readonly ClientPipeline _pipeline; + private readonly Uri _endpoint; + + private readonly int? _limit; + private readonly string _order; + + // Note: this one is special + private string _after; + + private readonly string _before; + private readonly RequestOptions _options; + + public VectorStoresPageEnumerator( + ClientPipeline pipeline, + Uri endpoint, + int? limit, string order, string after, string before, + RequestOptions options) + { + _pipeline = pipeline; + _endpoint = endpoint; + + _limit = limit; + _order = order; + _after = after; + _before = before; + _options = options; + } + + public override async Task GetFirstAsync() + => await GetVectorStoresAsync(_limit, _order, _after, _before, _options).ConfigureAwait(false); + + public override ClientResult GetFirst() + => GetVectorStores(_limit, _order, _after, _before, _options); + + public override async Task GetNextAsync(ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + + using JsonDocument doc = JsonDocument.Parse(response.Content); + _after = doc.RootElement.GetProperty("last_id"u8).GetString()!; + + return await GetVectorStoresAsync(_limit, _order, _after, _before, _options).ConfigureAwait(false); + } + + public override ClientResult GetNext(ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + + using JsonDocument doc = JsonDocument.Parse(response.Content); + _after = doc.RootElement.GetProperty("last_id"u8).GetString()!; + + return GetVectorStores(_limit, _order, _after, _before, _options); + } + + public override bool HasNext(ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + + using JsonDocument doc = JsonDocument.Parse(response.Content); + bool hasMore = doc.RootElement.GetProperty("has_more"u8).GetBoolean(); + + return hasMore; + } + + // Note: these are the protocol methods - they are generated here + internal virtual async Task GetVectorStoresAsync(int? limit, string order, string after, string before, RequestOptions options) + { + using PipelineMessage message = CreateGetVectorStoresRequest(limit, order, after, before, options); + return ClientResult.FromResponse(await _pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); + } + + internal virtual ClientResult GetVectorStores(int? limit, string order, string after, string before, RequestOptions options) + { + using PipelineMessage message = CreateGetVectorStoresRequest(limit, order, after, before, options); + return ClientResult.FromResponse(_pipeline.ProcessMessage(message, options)); + } + + private PipelineMessage CreateGetVectorStoresRequest(int? limit, string order, string after, string before, RequestOptions options) + { + var message = _pipeline.CreateMessage(); + message.ResponseClassifier = PipelineMessageClassifier200; + var request = message.Request; + request.Method = "GET"; + var uri = new ClientUriBuilder(); + uri.Reset(_endpoint); + uri.AppendPath("/vector_stores", false); + if (limit != null) + { + uri.AppendQuery("limit", limit.Value, true); + } + if (order != null) + { + uri.AppendQuery("order", order, true); + } + if (after != null) + { + uri.AppendQuery("after", after, true); + } + if (before != null) + { + uri.AppendQuery("before", before, true); + } + request.Uri = uri.ToUri(); + request.Headers.Set("Accept", "application/json"); + message.Apply(options); + return message; + } + + private static PipelineMessageClassifier? _pipelineMessageClassifier200; + private static PipelineMessageClassifier PipelineMessageClassifier200 => _pipelineMessageClassifier200 ??= PipelineMessageClassifier.Create(stackalloc ushort[] { 200 }); +} diff --git a/src/To.Be.Generated/VectorStoresPageToken.cs b/src/To.Be.Generated/VectorStoresPageToken.cs new file mode 100644 index 000000000..66ba8bf74 --- /dev/null +++ b/src/To.Be.Generated/VectorStoresPageToken.cs @@ -0,0 +1,142 @@ +using System; +using System.ClientModel; +using System.Diagnostics; +using System.IO; +using System.Text.Json; + +#nullable enable + +namespace OpenAI.VectorStores; + +internal class VectorStoresPageToken : ContinuationToken +{ + public VectorStoresPageToken(int? limit, string? order, string? after, string? before) + { + Limit = limit; + Order = order; + After = after; + Before = before; + } + + public int? Limit { get; } + + public string? Order { get; } + + public string? After { get; } + + public string? Before { get; } + + public override BinaryData ToBytes() + { + using MemoryStream stream = new(); + using Utf8JsonWriter writer = new(stream); + + writer.WriteStartObject(); + + if (Limit.HasValue) + { + writer.WriteNumber("limit", Limit.Value); + } + + if (Order is not null) + { + writer.WriteString("order", Order); + } + + if (After is not null) + { + writer.WriteString("after", After); + } + + if (Before is not null) + { + writer.WriteString("before", Before); + } + + writer.WriteEndObject(); + + writer.Flush(); + stream.Position = 0; + + return BinaryData.FromStream(stream); + } + + public VectorStoresPageToken? GetNextPageToken(bool hasMore, string? lastId) + { + if (!hasMore || lastId is null) + { + return null; + } + + return new(Limit, Order, lastId, Before); + } + + public static VectorStoresPageToken FromToken(ContinuationToken pageToken) + { + if (pageToken is VectorStoresPageToken token) + { + return token; + } + + BinaryData data = pageToken.ToBytes(); + + if (data.ToMemory().Length == 0) + { + throw new ArgumentException("Failed to create VectorStoresPageToken from provided pageToken.", nameof(pageToken)); + } + + Utf8JsonReader reader = new(data); + + int? limit = null; + string? order = null; + string? after = null; + string? before = null; + + reader.Read(); + + Debug.Assert(reader.TokenType == JsonTokenType.StartObject); + + while (reader.Read()) + { + if (reader.TokenType == JsonTokenType.EndObject) + { + break; + } + + Debug.Assert(reader.TokenType == JsonTokenType.PropertyName); + + string propertyName = reader.GetString()!; + + switch (propertyName) + { + case "limit": + reader.Read(); + Debug.Assert(reader.TokenType == JsonTokenType.Number); + limit = reader.GetInt32(); + break; + case "order": + reader.Read(); + Debug.Assert(reader.TokenType == JsonTokenType.String); + order = reader.GetString(); + break; + case "after": + reader.Read(); + Debug.Assert(reader.TokenType == JsonTokenType.String); + after = reader.GetString(); + break; + case "before": + reader.Read(); + Debug.Assert(reader.TokenType == JsonTokenType.String); + before = reader.GetString(); + break; + default: + throw new JsonException($"Unrecognized property '{propertyName}'."); + } + } + + return new(limit, order, after, before); + } + + public static VectorStoresPageToken FromOptions(int? limit, string? order, string? after, string? before) + => new(limit, order, after, before); +} \ No newline at end of file From 74e8b347aad6fc03bd048aba857998952d62b239 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Tue, 2 Jul 2024 11:04:10 -0700 Subject: [PATCH 49/72] follow-ups to convenience and tests for vector stores --- .../VectorStoreClient.Convenience.cs | 54 +++++-------------- .../VectorStoreFileBatchesPageEnumerator.cs | 3 ++ tests/Assistants/VectorStoreTests.cs | 6 +-- 3 files changed, 20 insertions(+), 43 deletions(-) diff --git a/src/Custom/VectorStores/VectorStoreClient.Convenience.cs b/src/Custom/VectorStores/VectorStoreClient.Convenience.cs index bb328b09b..886da3e5d 100644 --- a/src/Custom/VectorStores/VectorStoreClient.Convenience.cs +++ b/src/Custom/VectorStores/VectorStoreClient.Convenience.cs @@ -2,6 +2,7 @@ using System.ClientModel; using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Threading.Tasks; namespace OpenAI.VectorStores; @@ -87,22 +88,15 @@ public virtual ClientResult AddFileToVectorStore(Vec /// /// The vector store to enumerate the file associations of. /// - /// - /// The order that results should appear in the list according to their created_at - /// timestamp. - /// - /// - /// A status filter that file associations must match to be included in the collection. - /// + /// Options describing the collection to return. /// /// A collection of instances that can be asynchronously enumerated via /// await foreach. /// public virtual AsyncPageCollection GetFileAssociationsAsync( VectorStore vectorStore, - ListOrder? resultOrder = null, - VectorStoreFileStatusFilter? filter = null) - => GetFileAssociationsAsync(vectorStore?.Id, resultOrder, filter); + VectorStoreFileAssociationCollectionOptions options = default) + => GetFileAssociationsAsync(vectorStore?.Id, options); /// /// Gets the collection of instances representing file inclusions in the @@ -111,22 +105,15 @@ public virtual AsyncPageCollection GetFileAssociatio /// /// The ID vector store to enumerate the file associations of. /// - /// - /// The order that results should appear in the list according to their created_at - /// timestamp. - /// - /// - /// A status filter that file associations must match to be included in the collection. - /// + /// Options describing the collection to return. /// /// A collection of instances that can be synchronously enumerated via /// foreach. /// public virtual PageCollection GetFileAssociations( VectorStore vectorStore, - ListOrder? resultOrder = null, - VectorStoreFileStatusFilter? filter = null) - => GetFileAssociations(vectorStore?.Id, resultOrder); + VectorStoreFileAssociationCollectionOptions options = default) + => GetFileAssociations(vectorStore?.Id, options); /// /// Gets a instance representing an existing association between a known @@ -232,43 +219,30 @@ public virtual ClientResult CancelBatchFileJob(VectorSt /// Gets the collection of file associations associated with a vector store batch file job, representing the files /// that were scheduled for ingestion into the vector store. /// - /// - /// The order that results should appear in the list according to their created_at - /// timestamp. - /// - /// - /// A status filter that file associations must match to be included in the collection. - /// + /// The vector store batch file job to retrieve file associations from. + /// Options describing the collection to return. /// /// A collection of instances that can be asynchronously enumerated via /// await foreach. /// public virtual AsyncPageCollection GetFileAssociationsAsync( VectorStoreBatchFileJob batchJob, - ListOrder? resultOrder = null, - VectorStoreFileStatusFilter? filter = null) - => GetFileAssociationsAsync(batchJob?.VectorStoreId, batchJob?.BatchId, resultOrder, filter); + VectorStoreFileAssociationCollectionOptions options = default) + => GetFileAssociationsAsync(batchJob?.VectorStoreId, batchJob?.BatchId, options); /// /// Gets the collection of file associations associated with a vector store batch file job, representing the files /// that were scheduled for ingestion into the vector store. /// /// The vector store batch file job to retrieve file associations from. - /// - /// The order that results should appear in the list according to their created_at - /// timestamp. - /// - /// - /// A status filter that file associations must match to be included in the collection. - /// + /// Options describing the collection to return. /// /// A collection of instances that can be synchronously enumerated via /// foreach. /// public virtual PageCollection GetFileAssociations( VectorStoreBatchFileJob batchJob, - ListOrder? resultOrder = null, - VectorStoreFileStatusFilter? filter = null) - => GetFileAssociations(batchJob?.VectorStoreId, batchJob?.BatchId, resultOrder, filter); + VectorStoreFileAssociationCollectionOptions options = default) + => GetFileAssociations(batchJob?.VectorStoreId, batchJob?.BatchId, options); } diff --git a/src/To.Be.Generated/VectorStoreFileBatchesPageEnumerator.cs b/src/To.Be.Generated/VectorStoreFileBatchesPageEnumerator.cs index e6829ad82..1b2ef1b60 100644 --- a/src/To.Be.Generated/VectorStoreFileBatchesPageEnumerator.cs +++ b/src/To.Be.Generated/VectorStoreFileBatchesPageEnumerator.cs @@ -36,10 +36,13 @@ public VectorStoreFileBatchesPageEnumerator( _vectorStoreId = vectorStoreId; _batchId = batchId; + _limit = limit; _order = order; _after = after; _before = before; + _filter = filter; + _options = options; } diff --git a/tests/Assistants/VectorStoreTests.cs b/tests/Assistants/VectorStoreTests.cs index 7834b7592..dd470f245 100644 --- a/tests/Assistants/VectorStoreTests.cs +++ b/tests/Assistants/VectorStoreTests.cs @@ -73,7 +73,7 @@ public void CanCreateGetAndDeleteVectorStores() Assert.That(deleted, Is.True); _vectorStoresToDelete.RemoveAt(_vectorStoresToDelete.Count - 1); - vectorStore = client.CreateVectorStore(new VectorStoreCreationOptions () + vectorStore = client.CreateVectorStore(new VectorStoreCreationOptions() { FileIds = testFiles.Select(file => file.Id).ToList() }); @@ -102,7 +102,7 @@ public void CanEnumerateVectorStores() int lastIdSeen = int.MaxValue; int count = 0; - foreach (VectorStore vectorStore in client.GetVectorStores(ListOrder.NewestFirst).GetAllValues()) + foreach (VectorStore vectorStore in client.GetVectorStores(new VectorStoreCollectionOptions() { Order = ListOrder.NewestFirst }).GetAllValues()) { Assert.That(vectorStore.Id, Is.Not.Null); if (vectorStore.Name?.StartsWith("Test Vector Store ") == true) @@ -139,7 +139,7 @@ public async Task CanEnumerateVectorStoresAsync() int lastIdSeen = int.MaxValue; int count = 0; - await foreach (VectorStore vectorStore in client.GetVectorStoresAsync(ListOrder.NewestFirst).GetAllValuesAsync()) + await foreach (VectorStore vectorStore in client.GetVectorStoresAsync(new VectorStoreCollectionOptions() { Order = ListOrder.NewestFirst }).GetAllValuesAsync()) { Assert.That(vectorStore.Id, Is.Not.Null); if (vectorStore.Name?.StartsWith("Test Vector Store ") == true) From 827cf2bfe039075b9a547c83eb73612640295a1c Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Tue, 2 Jul 2024 11:28:58 -0700 Subject: [PATCH 50/72] bug fix --- .../Internal/PageResultEnumerator.cs | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/To.Be.Generated/Internal/PageResultEnumerator.cs b/src/To.Be.Generated/Internal/PageResultEnumerator.cs index 7f0d19fd3..8ac48517c 100644 --- a/src/To.Be.Generated/Internal/PageResultEnumerator.cs +++ b/src/To.Be.Generated/Internal/PageResultEnumerator.cs @@ -11,8 +11,12 @@ namespace OpenAI; internal abstract class PageResultEnumerator : IAsyncEnumerator, IEnumerator { private ClientResult? _current; + private bool _hasNext; - protected PageResultEnumerator() { } + protected PageResultEnumerator() + { + _hasNext = true; + } public ClientResult Current => _current!; @@ -36,6 +40,11 @@ protected PageResultEnumerator() { } public bool MoveNext() { + if (!_hasNext) + { + return false; + } + if (_current == null) { _current = GetFirst(); @@ -45,7 +54,8 @@ public bool MoveNext() _current = GetNext(_current); } - return HasNext(_current); + _hasNext = HasNext(_current); + return true; } public void Reset() => _current = null; @@ -58,6 +68,11 @@ public virtual void Dispose() { } public async ValueTask MoveNextAsync() { + if (!_hasNext) + { + return false; + } + if (_current == null) { _current = await GetFirstAsync().ConfigureAwait(false); @@ -67,7 +82,8 @@ public async ValueTask MoveNextAsync() _current = await GetNextAsync(_current).ConfigureAwait(false); } - return HasNext(_current); + _hasNext = HasNext(_current); + return true; } public virtual ValueTask DisposeAsync() => new(); From 891ccf53fe6da62df13ce532f92c1dd142e8506b Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Tue, 2 Jul 2024 14:28:27 -0700 Subject: [PATCH 51/72] temp bug fix --- .../Internal/PageCollectionHelpers.cs | 28 ++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/src/To.Be.Generated/Internal/PageCollectionHelpers.cs b/src/To.Be.Generated/Internal/PageCollectionHelpers.cs index 8c2eab6dd..f76dafe73 100644 --- a/src/To.Be.Generated/Internal/PageCollectionHelpers.cs +++ b/src/To.Be.Generated/Internal/PageCollectionHelpers.cs @@ -21,18 +21,28 @@ public static PageCollection Create( public static IEnumerable Create(IEnumerator enumerator) { - while (enumerator.MoveNext()) + if (enumerator.Current is not null) { yield return enumerator.Current; } + + while (enumerator.MoveNext()) + { + yield return enumerator.Current!; + } } public static async IAsyncEnumerable CreateAsync(IAsyncEnumerator enumerator) { - while (await enumerator.MoveNextAsync().ConfigureAwait(false)) + if (enumerator.Current is not null) { yield return enumerator.Current; } + + while (await enumerator.MoveNextAsync().ConfigureAwait(false)) + { + yield return enumerator.Current!; + } } private class AsyncFuncPageCollection : AsyncPageCollection @@ -50,10 +60,15 @@ public AsyncFuncPageCollection( protected override async IAsyncEnumerator> GetAsyncEnumeratorCore(CancellationToken cancellationToken = default) { - while (await _enumerator.MoveNextAsync().ConfigureAwait(false)) + if (_enumerator.Current is not null) { yield return _getPageFromResult(_enumerator.Current); } + + while (await _enumerator.MoveNextAsync().ConfigureAwait(false)) + { + yield return _getPageFromResult(_enumerator.Current!); + } } } @@ -72,10 +87,15 @@ public FuncPageCollection( protected override IEnumerator> GetEnumeratorCore() { - while (_enumerator.MoveNext()) + if (_enumerator.Current is not null) { yield return _getPageFromResult(_enumerator.Current); } + + while (_enumerator.MoveNext()) + { + yield return _getPageFromResult(_enumerator.Current!); + } } } } From b15bd18e4d13e02475ab4a852f7d49a537cae069 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Tue, 2 Jul 2024 14:54:50 -0700 Subject: [PATCH 52/72] Proof of concept of PageEnumerator pattern for MessageCollection --- .../Assistants/AssistantClient.Protocol.cs | 4 +- src/Custom/Assistants/AssistantClient.cs | 4 +- .../Internal/PageCollectionHelpers.cs | 90 ++++++------------- .../Internal/PageEnumerator.cs | 19 ++++ .../Internal/PageResultEnumerator.cs | 20 ++--- .../MessagesPageEnumerator.Convenience.cs | 22 ----- src/To.Be.Generated/MessagesPageEnumerator.cs | 15 +++- 7 files changed, 73 insertions(+), 101 deletions(-) create mode 100644 src/To.Be.Generated/Internal/PageEnumerator.cs delete mode 100644 src/To.Be.Generated/MessagesPageEnumerator.Convenience.cs diff --git a/src/Custom/Assistants/AssistantClient.Protocol.cs b/src/Custom/Assistants/AssistantClient.Protocol.cs index aba6fd330..1a3e8a718 100644 --- a/src/Custom/Assistants/AssistantClient.Protocol.cs +++ b/src/Custom/Assistants/AssistantClient.Protocol.cs @@ -219,7 +219,7 @@ public virtual IAsyncEnumerable GetMessagesAsync(string threadId, { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); - IAsyncEnumerator enumerator = new MessagesPageEnumerator(_pipeline, _endpoint, threadId, limit, order, after, before, options); + PageResultEnumerator enumerator = new MessagesPageEnumerator(_pipeline, _endpoint, threadId, limit, order, after, before, options); return PageCollectionHelpers.CreateAsync(enumerator); } @@ -227,7 +227,7 @@ public virtual IEnumerable GetMessages(string threadId, int? limit { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); - IEnumerator enumerator = new MessagesPageEnumerator(_pipeline, _endpoint, threadId, limit, order, after, before, options); + PageResultEnumerator enumerator = new MessagesPageEnumerator(_pipeline, _endpoint, threadId, limit, order, after, before, options); return PageCollectionHelpers.Create(enumerator); } diff --git a/src/Custom/Assistants/AssistantClient.cs b/src/Custom/Assistants/AssistantClient.cs index bf004a48a..f476aa531 100644 --- a/src/Custom/Assistants/AssistantClient.cs +++ b/src/Custom/Assistants/AssistantClient.cs @@ -412,7 +412,7 @@ public virtual AsyncPageCollection GetMessagesAsync( options?.BeforeId, cancellationToken.ToRequestOptions()); - return PageCollectionHelpers.CreateAsync(enumerator, enumerator.GetPageFromResult); + return PageCollectionHelpers.CreateAsync(enumerator); } public virtual AsyncPageCollection GetMessagesAsync( @@ -430,7 +430,7 @@ public virtual AsyncPageCollection GetMessagesAsync( pageToken.Before, cancellationToken.ToRequestOptions()); - return PageCollectionHelpers.CreateAsync(enumerator, enumerator.GetPageFromResult); + return PageCollectionHelpers.CreateAsync(enumerator); } /// diff --git a/src/To.Be.Generated/Internal/PageCollectionHelpers.cs b/src/To.Be.Generated/Internal/PageCollectionHelpers.cs index f76dafe73..a890e23f3 100644 --- a/src/To.Be.Generated/Internal/PageCollectionHelpers.cs +++ b/src/To.Be.Generated/Internal/PageCollectionHelpers.cs @@ -9,93 +9,59 @@ namespace OpenAI; internal class PageCollectionHelpers { - public static AsyncPageCollection CreateAsync( - IAsyncEnumerator enumerator, - Func> getPageFromResult) - => new AsyncFuncPageCollection(enumerator, getPageFromResult); + public static PageCollection Create(PageEnumerator enumerator) + => new EnumeratorPageCollection(enumerator); - public static PageCollection Create( - IEnumerator enumerator, - Func> getPageFromResult) - => new FuncPageCollection(enumerator, getPageFromResult); + public static AsyncPageCollection CreateAsync(PageEnumerator enumerator) + => new EnumeratorAsyncPageCollection(enumerator); - public static IEnumerable Create(IEnumerator enumerator) + private class EnumeratorPageCollection : PageCollection { - if (enumerator.Current is not null) - { - yield return enumerator.Current; - } + private readonly PageEnumerator _enumerator; - while (enumerator.MoveNext()) - { - yield return enumerator.Current!; - } - } - - public static async IAsyncEnumerable CreateAsync(IAsyncEnumerator enumerator) - { - if (enumerator.Current is not null) + public EnumeratorPageCollection(PageEnumerator enumerator) { - yield return enumerator.Current; + _enumerator = enumerator; } - while (await enumerator.MoveNextAsync().ConfigureAwait(false)) - { - yield return enumerator.Current!; - } + protected override IEnumerator> GetEnumeratorCore() + => _enumerator; } - private class AsyncFuncPageCollection : AsyncPageCollection + private class EnumeratorAsyncPageCollection : AsyncPageCollection { - private readonly IAsyncEnumerator _enumerator; - private readonly Func> _getPageFromResult; + private readonly PageEnumerator _enumerator; - public AsyncFuncPageCollection( - IAsyncEnumerator enumerator, - Func> getPageFromResult) + public EnumeratorAsyncPageCollection(PageEnumerator enumerator) { _enumerator = enumerator; - _getPageFromResult = getPageFromResult; } - protected override async IAsyncEnumerator> GetAsyncEnumeratorCore(CancellationToken cancellationToken = default) - { - if (_enumerator.Current is not null) - { - yield return _getPageFromResult(_enumerator.Current); - } + protected override IAsyncEnumerator> GetAsyncEnumeratorCore(CancellationToken cancellationToken = default) + => _enumerator; + } - while (await _enumerator.MoveNextAsync().ConfigureAwait(false)) + public static IEnumerable Create(PageResultEnumerator enumerator) + { + do + { + if (enumerator.Current is not null) { - yield return _getPageFromResult(_enumerator.Current!); + yield return enumerator.Current; } } + while (enumerator.MoveNext()); } - private class FuncPageCollection : PageCollection + public static async IAsyncEnumerable CreateAsync(PageResultEnumerator enumerator) { - private readonly IEnumerator _enumerator; - private readonly Func> _getPageFromResult; - - public FuncPageCollection( - IEnumerator enumerator, - Func> getPageFromResult) + do { - _enumerator = enumerator; - _getPageFromResult = getPageFromResult; - } - - protected override IEnumerator> GetEnumeratorCore() - { - if (_enumerator.Current is not null) - { - yield return _getPageFromResult(_enumerator.Current); - } - - while (_enumerator.MoveNext()) + if (enumerator.Current is not null) { - yield return _getPageFromResult(_enumerator.Current!); + yield return enumerator.Current; } } + while (await enumerator.MoveNextAsync().ConfigureAwait(false)); } } diff --git a/src/To.Be.Generated/Internal/PageEnumerator.cs b/src/To.Be.Generated/Internal/PageEnumerator.cs new file mode 100644 index 000000000..c1aef9ea4 --- /dev/null +++ b/src/To.Be.Generated/Internal/PageEnumerator.cs @@ -0,0 +1,19 @@ +using System.ClientModel; +using System.Collections.Generic; + +#nullable enable + +namespace OpenAI; + +internal abstract class PageEnumerator : PageResultEnumerator, + IAsyncEnumerator>, + IEnumerator> +{ + public abstract PageResult GetPageFromResult(ClientResult result); + + PageResult IEnumerator>.Current + => GetPageFromResult(Current); + + PageResult IAsyncEnumerator>.Current + => GetPageFromResult(Current); +} diff --git a/src/To.Be.Generated/Internal/PageResultEnumerator.cs b/src/To.Be.Generated/Internal/PageResultEnumerator.cs index 8ac48517c..4cbf22582 100644 --- a/src/To.Be.Generated/Internal/PageResultEnumerator.cs +++ b/src/To.Be.Generated/Internal/PageResultEnumerator.cs @@ -1,4 +1,5 @@ -using System.ClientModel; +using System; +using System.ClientModel; using System.Collections; using System.Collections.Generic; using System.Threading.Tasks; @@ -11,12 +12,7 @@ namespace OpenAI; internal abstract class PageResultEnumerator : IAsyncEnumerator, IEnumerator { private ClientResult? _current; - private bool _hasNext; - - protected PageResultEnumerator() - { - _hasNext = true; - } + private bool _hasNext = true; public ClientResult Current => _current!; @@ -36,9 +32,9 @@ protected PageResultEnumerator() #region IEnumerator implementation - object IEnumerator.Current => Current; + object IEnumerator.Current => ((IEnumerator)this).Current; - public bool MoveNext() + bool IEnumerator.MoveNext() { if (!_hasNext) { @@ -58,9 +54,9 @@ public bool MoveNext() return true; } - public void Reset() => _current = null; + void IEnumerator.Reset() => _current = null; - public virtual void Dispose() { } + void IDisposable.Dispose() { } #endregion @@ -86,7 +82,7 @@ public async ValueTask MoveNextAsync() return true; } - public virtual ValueTask DisposeAsync() => new(); + ValueTask IAsyncDisposable.DisposeAsync() => new(); #endregion } \ No newline at end of file diff --git a/src/To.Be.Generated/MessagesPageEnumerator.Convenience.cs b/src/To.Be.Generated/MessagesPageEnumerator.Convenience.cs deleted file mode 100644 index 234fa12a8..000000000 --- a/src/To.Be.Generated/MessagesPageEnumerator.Convenience.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.ClientModel; -using System.ClientModel.Primitives; - -#nullable enable - -namespace OpenAI.Assistants; - -internal partial class MessagesPageEnumerator : PageResultEnumerator -{ - // Note: this is the deserialization method that converts protocol to convenience - public PageResult GetPageFromResult(ClientResult result) - { - PipelineResponse response = result.GetRawResponse(); - - InternalListMessagesResponse list = ModelReaderWriter.Read(response.Content)!; - - MessagesPageToken pageToken = MessagesPageToken.FromOptions(_threadId, _limit, _order, _after, _before); - MessagesPageToken? nextPageToken = pageToken.GetNextPageToken(list.HasMore, list.LastId); - - return PageResult.Create(list.Data, pageToken, nextPageToken, response); - } -} \ No newline at end of file diff --git a/src/To.Be.Generated/MessagesPageEnumerator.cs b/src/To.Be.Generated/MessagesPageEnumerator.cs index b631834c5..1df785aea 100644 --- a/src/To.Be.Generated/MessagesPageEnumerator.cs +++ b/src/To.Be.Generated/MessagesPageEnumerator.cs @@ -8,7 +8,7 @@ namespace OpenAI.Assistants; -internal partial class MessagesPageEnumerator : PageResultEnumerator +internal partial class MessagesPageEnumerator : PageEnumerator { private readonly ClientPipeline _pipeline; private readonly Uri _endpoint; @@ -76,6 +76,19 @@ public override bool HasNext(ClientResult result) return hasMore; } + // Note: this is the deserialization method that converts protocol to convenience + public override PageResult GetPageFromResult(ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + + InternalListMessagesResponse list = ModelReaderWriter.Read(response.Content)!; + + MessagesPageToken pageToken = MessagesPageToken.FromOptions(_threadId, _limit, _order, _after, _before); + MessagesPageToken? nextPageToken = pageToken.GetNextPageToken(list.HasMore, list.LastId); + + return PageResult.Create(list.Data, pageToken, nextPageToken, response); + } + // Note: these are the protocol methods - they are generated here internal virtual async Task GetMessagesPageAsync(string threadId, int? limit, string order, string after, string before, RequestOptions options) { From 34175dc73d15684d2a411420fe7d1e3c70f07b47 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Tue, 2 Jul 2024 15:07:14 -0700 Subject: [PATCH 53/72] Refactor to PageEnumerator pattern --- .../Assistants/AssistantClient.Protocol.cs | 12 ++++---- src/Custom/Assistants/AssistantClient.cs | 28 +++++++++---------- .../VectorStoreClient.Protocol.cs | 12 ++++---- src/Custom/VectorStores/VectorStoreClient.cs | 24 ++++++++-------- .../AssistantsPageEnumerator.Convenience.cs | 21 -------------- .../AssistantsPageEnumerator.cs | 15 +++++++++- .../Internal/PageResultEnumerator.cs | 2 +- .../RunStepsPageEnumerator.Convenience.cs | 22 --------------- src/To.Be.Generated/RunStepsPageEnumerator.cs | 15 +++++++++- .../RunsPageEnumerator.Convenience.cs | 22 --------------- src/To.Be.Generated/RunsPageEnumerator.cs | 15 +++++++++- ...reFileBatchesPageEnumerator.Convenience.cs | 22 --------------- .../VectorStoreFileBatchesPageEnumerator.cs | 15 +++++++++- ...torStoreFilesPageEnumerator.Convenience.cs | 22 --------------- .../VectorStoreFilesPageEnumerator.cs | 15 +++++++++- .../VectorStoresPageEnumerator.Convenience.cs | 22 --------------- .../VectorStoresPageEnumerator.cs | 15 +++++++++- 17 files changed, 123 insertions(+), 176 deletions(-) delete mode 100644 src/To.Be.Generated/AssistantsPageEnumerator.Convenience.cs delete mode 100644 src/To.Be.Generated/RunStepsPageEnumerator.Convenience.cs delete mode 100644 src/To.Be.Generated/RunsPageEnumerator.Convenience.cs delete mode 100644 src/To.Be.Generated/VectorStoreFileBatchesPageEnumerator.Convenience.cs delete mode 100644 src/To.Be.Generated/VectorStoreFilesPageEnumerator.Convenience.cs delete mode 100644 src/To.Be.Generated/VectorStoresPageEnumerator.Convenience.cs diff --git a/src/Custom/Assistants/AssistantClient.Protocol.cs b/src/Custom/Assistants/AssistantClient.Protocol.cs index 1a3e8a718..b6cd32248 100644 --- a/src/Custom/Assistants/AssistantClient.Protocol.cs +++ b/src/Custom/Assistants/AssistantClient.Protocol.cs @@ -67,7 +67,7 @@ public virtual ClientResult CreateAssistant(BinaryContent content, RequestOption /// The response returned from the service. public virtual IAsyncEnumerable GetAssistantsAsync(int? limit, string order, string after, string before, RequestOptions options) { - IAsyncEnumerator enumerator = new AssistantsPageEnumerator(_pipeline, _endpoint, limit, order, after, before, options); + PageResultEnumerator enumerator = new AssistantsPageEnumerator(_pipeline, _endpoint, limit, order, after, before, options); return PageCollectionHelpers.CreateAsync(enumerator); } @@ -97,7 +97,7 @@ public virtual IAsyncEnumerable GetAssistantsAsync(int? limit, str /// The response returned from the service. public virtual IEnumerable GetAssistants(int? limit, string order, string after, string before, RequestOptions options) { - IEnumerator enumerator = new AssistantsPageEnumerator(_pipeline, _endpoint, limit, order, after, before, options); + PageResultEnumerator enumerator = new AssistantsPageEnumerator(_pipeline, _endpoint, limit, order, after, before, options); return PageCollectionHelpers.Create(enumerator); } @@ -273,7 +273,7 @@ public virtual IAsyncEnumerable GetRunsAsync(string threadId, int? { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); - IAsyncEnumerator enumerator = new RunsPageEnumerator(_pipeline, _endpoint, threadId, limit, order, after, before, options); + PageResultEnumerator enumerator = new RunsPageEnumerator(_pipeline, _endpoint, threadId, limit, order, after, before, options); return PageCollectionHelpers.CreateAsync(enumerator); } @@ -281,7 +281,7 @@ public virtual IEnumerable GetRuns(string threadId, int? limit, st { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); - IEnumerator enumerator = new RunsPageEnumerator(_pipeline, _endpoint, threadId, limit, order, after, before, options); + PageResultEnumerator enumerator = new RunsPageEnumerator(_pipeline, _endpoint, threadId, limit, order, after, before, options); return PageCollectionHelpers.Create(enumerator); } @@ -322,7 +322,7 @@ public virtual IAsyncEnumerable GetRunStepsAsync(string threadId, Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); Argument.AssertNotNullOrEmpty(runId, nameof(runId)); - IAsyncEnumerator enumerator = new RunStepsPageEnumerator(_pipeline, _endpoint, threadId, runId, limit, order, after, before, options); + PageResultEnumerator enumerator = new RunStepsPageEnumerator(_pipeline, _endpoint, threadId, runId, limit, order, after, before, options); return PageCollectionHelpers.CreateAsync(enumerator); } @@ -331,7 +331,7 @@ public virtual IEnumerable GetRunSteps(string threadId, string run Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); Argument.AssertNotNullOrEmpty(runId, nameof(runId)); - IEnumerator enumerator = new RunStepsPageEnumerator(_pipeline, _endpoint, threadId, runId, limit, order, after, before, options); + PageResultEnumerator enumerator = new RunStepsPageEnumerator(_pipeline, _endpoint, threadId, runId, limit, order, after, before, options); return PageCollectionHelpers.Create(enumerator); } diff --git a/src/Custom/Assistants/AssistantClient.cs b/src/Custom/Assistants/AssistantClient.cs index f476aa531..b39888e0f 100644 --- a/src/Custom/Assistants/AssistantClient.cs +++ b/src/Custom/Assistants/AssistantClient.cs @@ -118,7 +118,7 @@ public virtual AsyncPageCollection GetAssistantsAsync( options?.BeforeId, cancellationToken.ToRequestOptions()); - return PageCollectionHelpers.CreateAsync(enumerator, enumerator.GetPageFromResult); + return PageCollectionHelpers.CreateAsync(enumerator); } /// @@ -141,7 +141,7 @@ public virtual AsyncPageCollection GetAssistantsAsync( pageToken.Before, cancellationToken.ToRequestOptions()); - return PageCollectionHelpers.CreateAsync(enumerator, enumerator.GetPageFromResult); + return PageCollectionHelpers.CreateAsync(enumerator); } /// @@ -161,7 +161,7 @@ public virtual PageCollection GetAssistants( options?.BeforeId, cancellationToken.ToRequestOptions()); - return PageCollectionHelpers.Create(enumerator, enumerator.GetPageFromResult); + return PageCollectionHelpers.Create(enumerator); } /// @@ -184,7 +184,7 @@ public virtual PageCollection GetAssistants( pageToken.Before, cancellationToken.ToRequestOptions()); - return PageCollectionHelpers.Create(enumerator, enumerator.GetPageFromResult); + return PageCollectionHelpers.Create(enumerator); } /// @@ -455,7 +455,7 @@ public virtual PageCollection GetMessages( options?.BeforeId, cancellationToken.ToRequestOptions()); - return PageCollectionHelpers.Create(enumerator, enumerator.GetPageFromResult); + return PageCollectionHelpers.Create(enumerator); } public virtual PageCollection GetMessages( @@ -473,7 +473,7 @@ public virtual PageCollection GetMessages( pageToken.Before, cancellationToken.ToRequestOptions()); - return PageCollectionHelpers.Create(enumerator, enumerator.GetPageFromResult); + return PageCollectionHelpers.Create(enumerator); } /// @@ -790,7 +790,7 @@ public virtual AsyncPageCollection GetRunsAsync( options?.BeforeId, cancellationToken.ToRequestOptions()); - return PageCollectionHelpers.CreateAsync(enumerator, enumerator.GetPageFromResult); + return PageCollectionHelpers.CreateAsync(enumerator); } public virtual AsyncPageCollection GetRunsAsync( @@ -808,7 +808,7 @@ public virtual AsyncPageCollection GetRunsAsync( pageToken.Before, cancellationToken.ToRequestOptions()); - return PageCollectionHelpers.CreateAsync(enumerator, enumerator.GetPageFromResult); + return PageCollectionHelpers.CreateAsync(enumerator); } /// @@ -833,7 +833,7 @@ public virtual PageCollection GetRuns( options?.BeforeId, cancellationToken.ToRequestOptions()); - return PageCollectionHelpers.Create(enumerator, enumerator.GetPageFromResult); + return PageCollectionHelpers.Create(enumerator); } public virtual PageCollection GetRuns( @@ -851,7 +851,7 @@ public virtual PageCollection GetRuns( pageToken.Before, cancellationToken.ToRequestOptions()); - return PageCollectionHelpers.Create(enumerator, enumerator.GetPageFromResult); + return PageCollectionHelpers.Create(enumerator); } /// @@ -1047,7 +1047,7 @@ public virtual AsyncPageCollection GetRunStepsAsync( options?.BeforeId, cancellationToken.ToRequestOptions()); - return PageCollectionHelpers.CreateAsync(enumerator, enumerator.GetPageFromResult); + return PageCollectionHelpers.CreateAsync(enumerator); } public virtual AsyncPageCollection GetRunStepsAsync( @@ -1066,7 +1066,7 @@ public virtual AsyncPageCollection GetRunStepsAsync( pageToken.Before, cancellationToken.ToRequestOptions()); - return PageCollectionHelpers.CreateAsync(enumerator, enumerator.GetPageFromResult); + return PageCollectionHelpers.CreateAsync(enumerator); } /// @@ -1095,7 +1095,7 @@ public virtual PageCollection GetRunSteps( options?.BeforeId, cancellationToken.ToRequestOptions()); - return PageCollectionHelpers.Create(enumerator, enumerator.GetPageFromResult); + return PageCollectionHelpers.Create(enumerator); } public virtual PageCollection GetRunSteps( @@ -1114,7 +1114,7 @@ public virtual PageCollection GetRunSteps( pageToken.Before, cancellationToken.ToRequestOptions()); - return PageCollectionHelpers.Create(enumerator, enumerator.GetPageFromResult); + return PageCollectionHelpers.Create(enumerator); } diff --git a/src/Custom/VectorStores/VectorStoreClient.Protocol.cs b/src/Custom/VectorStores/VectorStoreClient.Protocol.cs index 4b6f2866f..bd42ae360 100644 --- a/src/Custom/VectorStores/VectorStoreClient.Protocol.cs +++ b/src/Custom/VectorStores/VectorStoreClient.Protocol.cs @@ -54,7 +54,7 @@ public partial class VectorStoreClient [EditorBrowsable(EditorBrowsableState.Never)] public virtual IAsyncEnumerable GetVectorStoresAsync(int? limit, string order, string after, string before, RequestOptions options) { - IAsyncEnumerator enumerator = new VectorStoresPageEnumerator(_pipeline, _endpoint, limit, order, after, before, options); + PageResultEnumerator enumerator = new VectorStoresPageEnumerator(_pipeline, _endpoint, limit, order, after, before, options); return PageCollectionHelpers.CreateAsync(enumerator); } @@ -85,7 +85,7 @@ public virtual IAsyncEnumerable GetVectorStoresAsync(int? limit, s [EditorBrowsable(EditorBrowsableState.Never)] public virtual IEnumerable GetVectorStores(int? limit, string order, string after, string before, RequestOptions options) { - IEnumerator enumerator = new VectorStoresPageEnumerator(_pipeline, _endpoint, limit, order, after, before, options); + PageResultEnumerator enumerator = new VectorStoresPageEnumerator(_pipeline, _endpoint, limit, order, after, before, options); return PageCollectionHelpers.Create(enumerator); } @@ -263,7 +263,7 @@ public virtual IAsyncEnumerable GetFileAssociationsAsync(string ve { Argument.AssertNotNullOrEmpty(vectorStoreId, nameof(vectorStoreId)); - IAsyncEnumerator enumerator = new VectorStoreFilesPageEnumerator(_pipeline, _endpoint, vectorStoreId, limit, order, after, before, filter, options); + PageResultEnumerator enumerator = new VectorStoreFilesPageEnumerator(_pipeline, _endpoint, vectorStoreId, limit, order, after, before, filter, options); return PageCollectionHelpers.CreateAsync(enumerator); } @@ -300,7 +300,7 @@ public virtual IEnumerable GetFileAssociations(string vectorStoreI { Argument.AssertNotNullOrEmpty(vectorStoreId, nameof(vectorStoreId)); - IEnumerator enumerator = new MessagesPageEnumerator(_pipeline, _endpoint, vectorStoreId, limit, order, after, before, options); + PageResultEnumerator enumerator = new MessagesPageEnumerator(_pipeline, _endpoint, vectorStoreId, limit, order, after, before, options); return PageCollectionHelpers.Create(enumerator); } @@ -579,7 +579,7 @@ public virtual IAsyncEnumerable GetFileAssociationsAsync(string ve Argument.AssertNotNullOrEmpty(vectorStoreId, nameof(vectorStoreId)); Argument.AssertNotNullOrEmpty(batchId, nameof(batchId)); - IAsyncEnumerator enumerator = new VectorStoreFileBatchesPageEnumerator(_pipeline, _endpoint, vectorStoreId, batchId, limit, order, after, before, filter, options); + PageResultEnumerator enumerator = new VectorStoreFileBatchesPageEnumerator(_pipeline, _endpoint, vectorStoreId, batchId, limit, order, after, before, filter, options); return PageCollectionHelpers.CreateAsync(enumerator); } @@ -618,7 +618,7 @@ public virtual IEnumerable GetFileAssociations(string vectorStoreI Argument.AssertNotNullOrEmpty(vectorStoreId, nameof(vectorStoreId)); Argument.AssertNotNullOrEmpty(batchId, nameof(batchId)); - IEnumerator enumerator = new VectorStoreFileBatchesPageEnumerator(_pipeline, _endpoint, vectorStoreId, batchId, limit, order, after, before, filter, options); + PageResultEnumerator enumerator = new VectorStoreFileBatchesPageEnumerator(_pipeline, _endpoint, vectorStoreId, batchId, limit, order, after, before, filter, options); return PageCollectionHelpers.Create(enumerator); } } diff --git a/src/Custom/VectorStores/VectorStoreClient.cs b/src/Custom/VectorStores/VectorStoreClient.cs index 18e318ad1..c8c3c4308 100644 --- a/src/Custom/VectorStores/VectorStoreClient.cs +++ b/src/Custom/VectorStores/VectorStoreClient.cs @@ -153,7 +153,7 @@ public virtual AsyncPageCollection GetVectorStoresAsync( options?.BeforeId, cancellationToken.ToRequestOptions()); - return PageCollectionHelpers.CreateAsync(enumerator, enumerator.GetPageFromResult); + return PageCollectionHelpers.CreateAsync(enumerator); } public virtual AsyncPageCollection GetVectorStoresAsync( @@ -170,7 +170,7 @@ public virtual AsyncPageCollection GetVectorStoresAsync( pageToken.Before, cancellationToken.ToRequestOptions()); - return PageCollectionHelpers.CreateAsync(enumerator, enumerator.GetPageFromResult); + return PageCollectionHelpers.CreateAsync(enumerator); } /// @@ -192,7 +192,7 @@ public virtual PageCollection GetVectorStores( options?.BeforeId, cancellationToken.ToRequestOptions()); - return PageCollectionHelpers.Create(enumerator, enumerator.GetPageFromResult); + return PageCollectionHelpers.Create(enumerator); } public virtual PageCollection GetVectorStores( @@ -209,7 +209,7 @@ public virtual PageCollection GetVectorStores( pageToken.Before, cancellationToken.ToRequestOptions()); - return PageCollectionHelpers.Create(enumerator, enumerator.GetPageFromResult); + return PageCollectionHelpers.Create(enumerator); } /// @@ -277,7 +277,7 @@ public virtual AsyncPageCollection GetFileAssociatio options?.Filter?.ToString(), cancellationToken.ToRequestOptions()); - return PageCollectionHelpers.CreateAsync(enumerator, enumerator.GetPageFromResult); + return PageCollectionHelpers.CreateAsync(enumerator); } public virtual AsyncPageCollection GetFileAssociationsAsync( @@ -296,7 +296,7 @@ public virtual AsyncPageCollection GetFileAssociatio pageToken.Filter, cancellationToken.ToRequestOptions()); - return PageCollectionHelpers.CreateAsync(enumerator, enumerator.GetPageFromResult); + return PageCollectionHelpers.CreateAsync(enumerator); } /// @@ -328,7 +328,7 @@ public virtual PageCollection GetFileAssociations( options?.Filter?.ToString(), cancellationToken.ToRequestOptions()); - return PageCollectionHelpers.Create(enumerator, enumerator.GetPageFromResult); + return PageCollectionHelpers.Create(enumerator); } public virtual PageCollection GetFileAssociations( @@ -347,7 +347,7 @@ public virtual PageCollection GetFileAssociations( pageToken.Filter, cancellationToken.ToRequestOptions()); - return PageCollectionHelpers.Create(enumerator, enumerator.GetPageFromResult); + return PageCollectionHelpers.Create(enumerator); } /// @@ -585,7 +585,7 @@ public virtual AsyncPageCollection GetFileAssociatio options?.Filter?.ToString(), cancellationToken.ToRequestOptions()); - return PageCollectionHelpers.CreateAsync(enumerator, enumerator.GetPageFromResult); + return PageCollectionHelpers.CreateAsync(enumerator); } public virtual AsyncPageCollection GetFileAssociationsAsync( @@ -622,7 +622,7 @@ public virtual AsyncPageCollection GetFileAssociatio pageToken.Filter, cancellationToken.ToRequestOptions()); - return PageCollectionHelpers.CreateAsync(enumerator, enumerator.GetPageFromResult); + return PageCollectionHelpers.CreateAsync(enumerator); } /// @@ -660,7 +660,7 @@ public virtual PageCollection GetFileAssociations( options?.Filter?.ToString(), cancellationToken.ToRequestOptions()); - return PageCollectionHelpers.Create(enumerator, enumerator.GetPageFromResult); + return PageCollectionHelpers.Create(enumerator); } public virtual PageCollection GetFileAssociations( @@ -697,6 +697,6 @@ public virtual PageCollection GetFileAssociations( pageToken.Filter, cancellationToken.ToRequestOptions()); - return PageCollectionHelpers.Create(enumerator, enumerator.GetPageFromResult); + return PageCollectionHelpers.Create(enumerator); } } diff --git a/src/To.Be.Generated/AssistantsPageEnumerator.Convenience.cs b/src/To.Be.Generated/AssistantsPageEnumerator.Convenience.cs deleted file mode 100644 index 8e4189a1b..000000000 --- a/src/To.Be.Generated/AssistantsPageEnumerator.Convenience.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System.ClientModel; -using System.ClientModel.Primitives; - -#nullable enable - -namespace OpenAI.Assistants; - -internal partial class AssistantsPageEnumerator : PageResultEnumerator -{ - public PageResult GetPageFromResult(ClientResult result) - { - PipelineResponse response = result.GetRawResponse(); - - InternalListAssistantsResponse list = ModelReaderWriter.Read(response.Content)!; - - AssistantsPageToken pageToken = AssistantsPageToken.FromOptions(_limit, _order, _after, _before); - AssistantsPageToken? nextPageToken = pageToken.GetNextPageToken(list.HasMore, list.LastId); - - return PageResult.Create(list.Data, pageToken, nextPageToken, response); - } -} \ No newline at end of file diff --git a/src/To.Be.Generated/AssistantsPageEnumerator.cs b/src/To.Be.Generated/AssistantsPageEnumerator.cs index 6c8d40b58..f18521c1e 100644 --- a/src/To.Be.Generated/AssistantsPageEnumerator.cs +++ b/src/To.Be.Generated/AssistantsPageEnumerator.cs @@ -8,7 +8,7 @@ namespace OpenAI.Assistants; -internal partial class AssistantsPageEnumerator : PageResultEnumerator +internal partial class AssistantsPageEnumerator : PageEnumerator { private readonly ClientPipeline _pipeline; private readonly Uri _endpoint; @@ -74,6 +74,19 @@ public override bool HasNext(ClientResult result) return hasMore; } + public override PageResult GetPageFromResult(ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + + InternalListAssistantsResponse list = ModelReaderWriter.Read(response.Content)!; + + AssistantsPageToken pageToken = AssistantsPageToken.FromOptions(_limit, _order, _after, _before); + AssistantsPageToken? nextPageToken = pageToken.GetNextPageToken(list.HasMore, list.LastId); + + return PageResult.Create(list.Data, pageToken, nextPageToken, response); + } + + // Note: these are the protocol methods - they are generated here internal virtual async Task GetAssistantsPageAsync(int? limit, string order, string after, string before, RequestOptions options) { diff --git a/src/To.Be.Generated/Internal/PageResultEnumerator.cs b/src/To.Be.Generated/Internal/PageResultEnumerator.cs index 4cbf22582..64853d8f6 100644 --- a/src/To.Be.Generated/Internal/PageResultEnumerator.cs +++ b/src/To.Be.Generated/Internal/PageResultEnumerator.cs @@ -34,7 +34,7 @@ internal abstract class PageResultEnumerator : IAsyncEnumerator, I object IEnumerator.Current => ((IEnumerator)this).Current; - bool IEnumerator.MoveNext() + public bool MoveNext() { if (!_hasNext) { diff --git a/src/To.Be.Generated/RunStepsPageEnumerator.Convenience.cs b/src/To.Be.Generated/RunStepsPageEnumerator.Convenience.cs deleted file mode 100644 index 9d59ffb2a..000000000 --- a/src/To.Be.Generated/RunStepsPageEnumerator.Convenience.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.ClientModel; -using System.ClientModel.Primitives; - -#nullable enable - -namespace OpenAI.Assistants; - -internal partial class RunStepsPageEnumerator : PageResultEnumerator -{ - // Note: this is the deserialization method that converts protocol to convenience - public PageResult GetPageFromResult(ClientResult result) - { - PipelineResponse response = result.GetRawResponse(); - - InternalListRunStepsResponse list = ModelReaderWriter.Read(response.Content)!; - - RunStepsPageToken pageToken = RunStepsPageToken.FromOptions(_threadId, _runId, _limit, _order, _after, _before); - RunStepsPageToken? nextPageToken = pageToken.GetNextPageToken(list.HasMore, list.LastId); - - return PageResult.Create(list.Data, pageToken, nextPageToken, response); - } -} \ No newline at end of file diff --git a/src/To.Be.Generated/RunStepsPageEnumerator.cs b/src/To.Be.Generated/RunStepsPageEnumerator.cs index e8f3c0041..09c7ab423 100644 --- a/src/To.Be.Generated/RunStepsPageEnumerator.cs +++ b/src/To.Be.Generated/RunStepsPageEnumerator.cs @@ -8,7 +8,7 @@ namespace OpenAI.Assistants; -internal partial class RunStepsPageEnumerator : PageResultEnumerator +internal partial class RunStepsPageEnumerator : PageEnumerator { private readonly ClientPipeline _pipeline; private readonly Uri _endpoint; @@ -81,6 +81,19 @@ public override bool HasNext(ClientResult result) return hasMore; } + // Note: this is the deserialization method that converts protocol to convenience + public override PageResult GetPageFromResult(ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + + InternalListRunStepsResponse list = ModelReaderWriter.Read(response.Content)!; + + RunStepsPageToken pageToken = RunStepsPageToken.FromOptions(_threadId, _runId, _limit, _order, _after, _before); + RunStepsPageToken? nextPageToken = pageToken.GetNextPageToken(list.HasMore, list.LastId); + + return PageResult.Create(list.Data, pageToken, nextPageToken, response); + } + // Note: these are the protocol methods - they are generated here internal async virtual Task GetRunStepsPageAsync(string threadId, string runId, int? limit, string order, string after, string before, RequestOptions options) { diff --git a/src/To.Be.Generated/RunsPageEnumerator.Convenience.cs b/src/To.Be.Generated/RunsPageEnumerator.Convenience.cs deleted file mode 100644 index 993b85a49..000000000 --- a/src/To.Be.Generated/RunsPageEnumerator.Convenience.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.ClientModel; -using System.ClientModel.Primitives; - -#nullable enable - -namespace OpenAI.Assistants; - -internal partial class RunsPageEnumerator : PageResultEnumerator -{ - // Note: this is the deserialization method that converts protocol to convenience - public PageResult GetPageFromResult(ClientResult result) - { - PipelineResponse response = result.GetRawResponse(); - - InternalListRunsResponse list = ModelReaderWriter.Read(response.Content)!; - - RunsPageToken pageToken = RunsPageToken.FromOptions(_threadId, _limit, _order, _after, _before); - RunsPageToken? nextPageToken = pageToken.GetNextPageToken(list.HasMore, list.LastId); - - return PageResult.Create(list.Data, pageToken, nextPageToken, response); - } -} \ No newline at end of file diff --git a/src/To.Be.Generated/RunsPageEnumerator.cs b/src/To.Be.Generated/RunsPageEnumerator.cs index b9c618963..0f1e6dc89 100644 --- a/src/To.Be.Generated/RunsPageEnumerator.cs +++ b/src/To.Be.Generated/RunsPageEnumerator.cs @@ -8,7 +8,7 @@ namespace OpenAI.Assistants; -internal partial class RunsPageEnumerator : PageResultEnumerator +internal partial class RunsPageEnumerator : PageEnumerator { private readonly ClientPipeline _pipeline; private readonly Uri _endpoint; @@ -76,6 +76,19 @@ public override bool HasNext(ClientResult result) return hasMore; } + // Note: this is the deserialization method that converts protocol to convenience + public override PageResult GetPageFromResult(ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + + InternalListRunsResponse list = ModelReaderWriter.Read(response.Content)!; + + RunsPageToken pageToken = RunsPageToken.FromOptions(_threadId, _limit, _order, _after, _before); + RunsPageToken? nextPageToken = pageToken.GetNextPageToken(list.HasMore, list.LastId); + + return PageResult.Create(list.Data, pageToken, nextPageToken, response); + } + // Note: these are the protocol methods - they are generated here internal async virtual Task GetRunsPageAsync(string threadId, int? limit, string order, string after, string before, RequestOptions options) { diff --git a/src/To.Be.Generated/VectorStoreFileBatchesPageEnumerator.Convenience.cs b/src/To.Be.Generated/VectorStoreFileBatchesPageEnumerator.Convenience.cs deleted file mode 100644 index 94a14c497..000000000 --- a/src/To.Be.Generated/VectorStoreFileBatchesPageEnumerator.Convenience.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.ClientModel; -using System.ClientModel.Primitives; - -#nullable enable - -namespace OpenAI.VectorStores; - -internal partial class VectorStoreFileBatchesPageEnumerator : PageResultEnumerator -{ - // Note: this is the deserialization method that converts protocol to convenience - public PageResult GetPageFromResult(ClientResult result) - { - PipelineResponse response = result.GetRawResponse(); - - InternalListVectorStoreFilesResponse list = ModelReaderWriter.Read(response.Content)!; - - VectorStoreFilesPageToken pageToken = VectorStoreFilesPageToken.FromOptions(_vectorStoreId, _limit, _order, _after, _before, _filter); - VectorStoreFilesPageToken? nextPageToken = pageToken.GetNextPageToken(list.HasMore, list.LastId); - - return PageResult.Create(list.Data, pageToken, nextPageToken, response); - } -} \ No newline at end of file diff --git a/src/To.Be.Generated/VectorStoreFileBatchesPageEnumerator.cs b/src/To.Be.Generated/VectorStoreFileBatchesPageEnumerator.cs index 1b2ef1b60..a0b20f710 100644 --- a/src/To.Be.Generated/VectorStoreFileBatchesPageEnumerator.cs +++ b/src/To.Be.Generated/VectorStoreFileBatchesPageEnumerator.cs @@ -8,7 +8,7 @@ namespace OpenAI.VectorStores; -internal partial class VectorStoreFileBatchesPageEnumerator : PageResultEnumerator +internal partial class VectorStoreFileBatchesPageEnumerator : PageEnumerator { private readonly ClientPipeline _pipeline; private readonly Uri _endpoint; @@ -82,6 +82,19 @@ public override bool HasNext(ClientResult result) return hasMore; } + // Note: this is the deserialization method that converts protocol to convenience + public override PageResult GetPageFromResult(ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + + InternalListVectorStoreFilesResponse list = ModelReaderWriter.Read(response.Content)!; + + VectorStoreFilesPageToken pageToken = VectorStoreFilesPageToken.FromOptions(_vectorStoreId, _limit, _order, _after, _before, _filter); + VectorStoreFilesPageToken? nextPageToken = pageToken.GetNextPageToken(list.HasMore, list.LastId); + + return PageResult.Create(list.Data, pageToken, nextPageToken, response); + } + // Note: these are the protocol methods - they are generated here internal virtual async Task GetFileAssociationsAsync(string vectorStoreId, string batchId, int? limit, string? order, string? after, string? before, string? filter, RequestOptions options) { diff --git a/src/To.Be.Generated/VectorStoreFilesPageEnumerator.Convenience.cs b/src/To.Be.Generated/VectorStoreFilesPageEnumerator.Convenience.cs deleted file mode 100644 index bc6109564..000000000 --- a/src/To.Be.Generated/VectorStoreFilesPageEnumerator.Convenience.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.ClientModel; -using System.ClientModel.Primitives; - -#nullable enable - -namespace OpenAI.VectorStores; - -internal partial class VectorStoreFilesPageEnumerator : PageResultEnumerator -{ - // Note: this is the deserialization method that converts protocol to convenience - public PageResult GetPageFromResult(ClientResult result) - { - PipelineResponse response = result.GetRawResponse(); - - InternalListVectorStoreFilesResponse list = ModelReaderWriter.Read(response.Content)!; - - VectorStoreFilesPageToken pageToken = VectorStoreFilesPageToken.FromOptions(_vectorStoreId, _limit, _order, _after, _before, _filter); - VectorStoreFilesPageToken? nextPageToken = pageToken.GetNextPageToken(list.HasMore, list.LastId); - - return PageResult.Create(list.Data, pageToken, nextPageToken, response); - } -} \ No newline at end of file diff --git a/src/To.Be.Generated/VectorStoreFilesPageEnumerator.cs b/src/To.Be.Generated/VectorStoreFilesPageEnumerator.cs index a2bc090f1..d4825a0e9 100644 --- a/src/To.Be.Generated/VectorStoreFilesPageEnumerator.cs +++ b/src/To.Be.Generated/VectorStoreFilesPageEnumerator.cs @@ -8,7 +8,7 @@ namespace OpenAI.VectorStores; -internal partial class VectorStoreFilesPageEnumerator : PageResultEnumerator +internal partial class VectorStoreFilesPageEnumerator : PageEnumerator { private readonly ClientPipeline _pipeline; private readonly Uri _endpoint; @@ -79,6 +79,19 @@ public override bool HasNext(ClientResult result) return hasMore; } + // Note: this is the deserialization method that converts protocol to convenience + public override PageResult GetPageFromResult(ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + + InternalListVectorStoreFilesResponse list = ModelReaderWriter.Read(response.Content)!; + + VectorStoreFilesPageToken pageToken = VectorStoreFilesPageToken.FromOptions(_vectorStoreId, _limit, _order, _after, _before, _filter); + VectorStoreFilesPageToken? nextPageToken = pageToken.GetNextPageToken(list.HasMore, list.LastId); + + return PageResult.Create(list.Data, pageToken, nextPageToken, response); + } + // Note: these are the protocol methods - they are generated here internal virtual async Task GetFileAssociationsAsync(string vectorStoreId, int? limit, string? order, string? after, string? before, string? filter, RequestOptions options) { diff --git a/src/To.Be.Generated/VectorStoresPageEnumerator.Convenience.cs b/src/To.Be.Generated/VectorStoresPageEnumerator.Convenience.cs deleted file mode 100644 index ca097e8a7..000000000 --- a/src/To.Be.Generated/VectorStoresPageEnumerator.Convenience.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.ClientModel; -using System.ClientModel.Primitives; - -#nullable enable - -namespace OpenAI.VectorStores; - -internal partial class VectorStoresPageEnumerator : PageResultEnumerator -{ - // Note: this is the deserialization method that converts protocol to convenience - public PageResult GetPageFromResult(ClientResult result) - { - PipelineResponse response = result.GetRawResponse(); - - InternalListVectorStoresResponse list = ModelReaderWriter.Read(response.Content)!; - - VectorStoresPageToken pageToken = VectorStoresPageToken.FromOptions(_limit, _order, _after, _before); - VectorStoresPageToken? nextPageToken = pageToken.GetNextPageToken(list.HasMore, list.LastId); - - return PageResult.Create(list.Data, pageToken, nextPageToken, response); - } -} \ No newline at end of file diff --git a/src/To.Be.Generated/VectorStoresPageEnumerator.cs b/src/To.Be.Generated/VectorStoresPageEnumerator.cs index 25800b1df..94ac83e5d 100644 --- a/src/To.Be.Generated/VectorStoresPageEnumerator.cs +++ b/src/To.Be.Generated/VectorStoresPageEnumerator.cs @@ -8,7 +8,7 @@ namespace OpenAI.VectorStores; -internal partial class VectorStoresPageEnumerator : PageResultEnumerator +internal partial class VectorStoresPageEnumerator : PageEnumerator { private readonly ClientPipeline _pipeline; private readonly Uri _endpoint; @@ -74,6 +74,19 @@ public override bool HasNext(ClientResult result) return hasMore; } + // Note: this is the deserialization method that converts protocol to convenience + public override PageResult GetPageFromResult(ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + + InternalListVectorStoresResponse list = ModelReaderWriter.Read(response.Content)!; + + VectorStoresPageToken pageToken = VectorStoresPageToken.FromOptions(_limit, _order, _after, _before); + VectorStoresPageToken? nextPageToken = pageToken.GetNextPageToken(list.HasMore, list.LastId); + + return PageResult.Create(list.Data, pageToken, nextPageToken, response); + } + // Note: these are the protocol methods - they are generated here internal virtual async Task GetVectorStoresAsync(int? limit, string order, string after, string before, RequestOptions options) { From 4a175d82b531cc050f897a88ead44a5c260b8afa Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Tue, 2 Jul 2024 15:25:58 -0700 Subject: [PATCH 54/72] bug fix --- .../Internal/PageEnumerator.cs | 26 ++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/To.Be.Generated/Internal/PageEnumerator.cs b/src/To.Be.Generated/Internal/PageEnumerator.cs index c1aef9ea4..7896c90cd 100644 --- a/src/To.Be.Generated/Internal/PageEnumerator.cs +++ b/src/To.Be.Generated/Internal/PageEnumerator.cs @@ -11,9 +11,29 @@ internal abstract class PageEnumerator : PageResultEnumerator, { public abstract PageResult GetPageFromResult(ClientResult result); - PageResult IEnumerator>.Current - => GetPageFromResult(Current); + PageResult IEnumerator>.Current + { + get + { + if (Current is null) + { + return default!; + } + + return GetPageFromResult(Current); + } + } PageResult IAsyncEnumerator>.Current - => GetPageFromResult(Current); + { + get + { + if (Current is null) + { + return default!; + } + + return GetPageFromResult(Current); + } + } } From 8656f1216862fc12ab1ce65be178339a015ebdab Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Tue, 2 Jul 2024 15:31:34 -0700 Subject: [PATCH 55/72] nit --- src/To.Be.Generated/Internal/PageResultEnumerator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/To.Be.Generated/Internal/PageResultEnumerator.cs b/src/To.Be.Generated/Internal/PageResultEnumerator.cs index 64853d8f6..89932e02a 100644 --- a/src/To.Be.Generated/Internal/PageResultEnumerator.cs +++ b/src/To.Be.Generated/Internal/PageResultEnumerator.cs @@ -82,7 +82,7 @@ public async ValueTask MoveNextAsync() return true; } - ValueTask IAsyncDisposable.DisposeAsync() => new(); + ValueTask IAsyncDisposable.DisposeAsync() => default; #endregion } \ No newline at end of file From 4d2bf33dc08d20c416edd1decf9319fb9729a7f5 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Wed, 3 Jul 2024 16:09:40 -0700 Subject: [PATCH 56/72] updates from SCM polish work --- src/To.Be.Generated/AssistantsPageToken.cs | 2 +- .../Internal/PageCollectionHelpers.cs | 53 +++++++++---------- .../Internal/PageEnumerator.cs | 21 ++++++++ src/To.Be.Generated/MessagesPageToken.cs | 2 +- src/To.Be.Generated/RunStepsPageToken.cs | 2 +- src/To.Be.Generated/RunsPageToken.cs | 2 +- .../VectorStoreFileBatchesPageToken.cs | 2 +- .../VectorStoreFilesPageToken.cs | 2 +- src/To.Be.Generated/VectorStoresPageToken.cs | 2 +- 9 files changed, 54 insertions(+), 34 deletions(-) diff --git a/src/To.Be.Generated/AssistantsPageToken.cs b/src/To.Be.Generated/AssistantsPageToken.cs index d6002c39b..251e8a421 100644 --- a/src/To.Be.Generated/AssistantsPageToken.cs +++ b/src/To.Be.Generated/AssistantsPageToken.cs @@ -10,7 +10,7 @@ namespace OpenAI.Assistants; internal class AssistantsPageToken : ContinuationToken { - public AssistantsPageToken(int? limit, string? order, string? after, string? before) + protected AssistantsPageToken(int? limit, string? order, string? after, string? before) { Limit = limit; Order = order; diff --git a/src/To.Be.Generated/Internal/PageCollectionHelpers.cs b/src/To.Be.Generated/Internal/PageCollectionHelpers.cs index a890e23f3..5cac0d7d6 100644 --- a/src/To.Be.Generated/Internal/PageCollectionHelpers.cs +++ b/src/To.Be.Generated/Internal/PageCollectionHelpers.cs @@ -2,6 +2,7 @@ using System.ClientModel; using System.Collections.Generic; using System.Threading; +using System.Threading.Tasks; #nullable enable @@ -13,7 +14,23 @@ public static PageCollection Create(PageEnumerator enumerator) => new EnumeratorPageCollection(enumerator); public static AsyncPageCollection CreateAsync(PageEnumerator enumerator) - => new EnumeratorAsyncPageCollection(enumerator); + => new AsyncEnumeratorPageCollection(enumerator); + + public static IEnumerable Create(PageResultEnumerator enumerator) + { + while (enumerator.MoveNext()) + { + yield return enumerator.Current; + } + } + + public static async IAsyncEnumerable CreateAsync(PageResultEnumerator enumerator) + { + while (await enumerator.MoveNextAsync().ConfigureAwait(false)) + { + yield return enumerator.Current; + } + } private class EnumeratorPageCollection : PageCollection { @@ -24,44 +41,26 @@ public EnumeratorPageCollection(PageEnumerator enumerator) _enumerator = enumerator; } + protected override PageResult GetCurrentPageCore() + => _enumerator.GetCurrentPage(); + protected override IEnumerator> GetEnumeratorCore() => _enumerator; } - private class EnumeratorAsyncPageCollection : AsyncPageCollection + private class AsyncEnumeratorPageCollection : AsyncPageCollection { private readonly PageEnumerator _enumerator; - public EnumeratorAsyncPageCollection(PageEnumerator enumerator) + public AsyncEnumeratorPageCollection(PageEnumerator enumerator) { _enumerator = enumerator; } + protected override async Task> GetCurrentPageAsyncCore() + => await _enumerator.GetCurrentPageAsync().ConfigureAwait(false); + protected override IAsyncEnumerator> GetAsyncEnumeratorCore(CancellationToken cancellationToken = default) => _enumerator; } - - public static IEnumerable Create(PageResultEnumerator enumerator) - { - do - { - if (enumerator.Current is not null) - { - yield return enumerator.Current; - } - } - while (enumerator.MoveNext()); - } - - public static async IAsyncEnumerable CreateAsync(PageResultEnumerator enumerator) - { - do - { - if (enumerator.Current is not null) - { - yield return enumerator.Current; - } - } - while (await enumerator.MoveNextAsync().ConfigureAwait(false)); - } } diff --git a/src/To.Be.Generated/Internal/PageEnumerator.cs b/src/To.Be.Generated/Internal/PageEnumerator.cs index 7896c90cd..6bf35810e 100644 --- a/src/To.Be.Generated/Internal/PageEnumerator.cs +++ b/src/To.Be.Generated/Internal/PageEnumerator.cs @@ -1,5 +1,6 @@ using System.ClientModel; using System.Collections.Generic; +using System.Threading.Tasks; #nullable enable @@ -11,6 +12,26 @@ internal abstract class PageEnumerator : PageResultEnumerator, { public abstract PageResult GetPageFromResult(ClientResult result); + public PageResult GetCurrentPage() + { + if (Current is null) + { + return GetPageFromResult(GetFirst()); + } + + return ((IEnumerator>)this).Current; + } + + public async Task> GetCurrentPageAsync() + { + if (Current is null) + { + return GetPageFromResult(await GetFirstAsync().ConfigureAwait(false)); + } + + return ((IEnumerator>)this).Current; + } + PageResult IEnumerator>.Current { get diff --git a/src/To.Be.Generated/MessagesPageToken.cs b/src/To.Be.Generated/MessagesPageToken.cs index 4700880e0..b11bca627 100644 --- a/src/To.Be.Generated/MessagesPageToken.cs +++ b/src/To.Be.Generated/MessagesPageToken.cs @@ -10,7 +10,7 @@ namespace OpenAI.Assistants; internal class MessagesPageToken : ContinuationToken { - public MessagesPageToken(string threadId, int? limit, string? order, string? after, string? before) + protected MessagesPageToken(string threadId, int? limit, string? order, string? after, string? before) { ThreadId = threadId; diff --git a/src/To.Be.Generated/RunStepsPageToken.cs b/src/To.Be.Generated/RunStepsPageToken.cs index 371026996..309643c95 100644 --- a/src/To.Be.Generated/RunStepsPageToken.cs +++ b/src/To.Be.Generated/RunStepsPageToken.cs @@ -10,7 +10,7 @@ namespace OpenAI.Assistants; internal class RunStepsPageToken : ContinuationToken { - public RunStepsPageToken(string threadId, string runId, int? limit, string? order, string? after, string? before) + protected RunStepsPageToken(string threadId, string runId, int? limit, string? order, string? after, string? before) { ThreadId = threadId; RunId = runId; diff --git a/src/To.Be.Generated/RunsPageToken.cs b/src/To.Be.Generated/RunsPageToken.cs index aec984ac3..e019fe5d4 100644 --- a/src/To.Be.Generated/RunsPageToken.cs +++ b/src/To.Be.Generated/RunsPageToken.cs @@ -10,7 +10,7 @@ namespace OpenAI.Assistants; internal class RunsPageToken : ContinuationToken { - public RunsPageToken(string threadId, int? limit, string? order, string? after, string? before) + protected RunsPageToken(string threadId, int? limit, string? order, string? after, string? before) { ThreadId = threadId; diff --git a/src/To.Be.Generated/VectorStoreFileBatchesPageToken.cs b/src/To.Be.Generated/VectorStoreFileBatchesPageToken.cs index 96e732737..798f0c760 100644 --- a/src/To.Be.Generated/VectorStoreFileBatchesPageToken.cs +++ b/src/To.Be.Generated/VectorStoreFileBatchesPageToken.cs @@ -10,7 +10,7 @@ namespace OpenAI.VectorStores; internal class VectorStoreFileBatchesPageToken : ContinuationToken { - public VectorStoreFileBatchesPageToken(string vectorStoreId,string batchId, int? limit, string? order, string? after, string? before, string? filter) + protected VectorStoreFileBatchesPageToken(string vectorStoreId,string batchId, int? limit, string? order, string? after, string? before, string? filter) { VectorStoreId = vectorStoreId; BatchId = batchId; diff --git a/src/To.Be.Generated/VectorStoreFilesPageToken.cs b/src/To.Be.Generated/VectorStoreFilesPageToken.cs index fa86af2e4..ba7b1f9eb 100644 --- a/src/To.Be.Generated/VectorStoreFilesPageToken.cs +++ b/src/To.Be.Generated/VectorStoreFilesPageToken.cs @@ -10,7 +10,7 @@ namespace OpenAI.VectorStores; internal class VectorStoreFilesPageToken : ContinuationToken { - public VectorStoreFilesPageToken(string vectorStoreId, int? limit, string? order, string? after, string? before, string? filter) + protected VectorStoreFilesPageToken(string vectorStoreId, int? limit, string? order, string? after, string? before, string? filter) { VectorStoreId = vectorStoreId; diff --git a/src/To.Be.Generated/VectorStoresPageToken.cs b/src/To.Be.Generated/VectorStoresPageToken.cs index 66ba8bf74..bd4c29a2d 100644 --- a/src/To.Be.Generated/VectorStoresPageToken.cs +++ b/src/To.Be.Generated/VectorStoresPageToken.cs @@ -10,7 +10,7 @@ namespace OpenAI.VectorStores; internal class VectorStoresPageToken : ContinuationToken { - public VectorStoresPageToken(int? limit, string? order, string? after, string? before) + protected VectorStoresPageToken(int? limit, string? order, string? after, string? before) { Limit = limit; Order = order; From 4008584122518ade016925aa3c5cd91804d5c589 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Mon, 15 Jul 2024 09:36:02 -0700 Subject: [PATCH 57/72] move to SCM beta.5 package --- OpenAI.sln | 6 ------ src/OpenAI.csproj | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/OpenAI.sln b/OpenAI.sln index 3d2ce81e7..79cc37611 100644 --- a/OpenAI.sln +++ b/OpenAI.sln @@ -8,8 +8,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenAI.Examples", "examples EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenAI.Tests", "tests\OpenAI.Tests.csproj", "{6F156401-2544-41D7-B204-3148C51C1D09}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.ClientModel", "..\azure-sdk-for-net\sdk\core\System.ClientModel\src\System.ClientModel.csproj", "{8269B350-8875-49F9-A9EA-DEF8718FEBE4}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -28,10 +26,6 @@ Global {6F156401-2544-41D7-B204-3148C51C1D09}.Debug|Any CPU.Build.0 = Debug|Any CPU {6F156401-2544-41D7-B204-3148C51C1D09}.Release|Any CPU.ActiveCfg = Release|Any CPU {6F156401-2544-41D7-B204-3148C51C1D09}.Release|Any CPU.Build.0 = Release|Any CPU - {8269B350-8875-49F9-A9EA-DEF8718FEBE4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8269B350-8875-49F9-A9EA-DEF8718FEBE4}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8269B350-8875-49F9-A9EA-DEF8718FEBE4}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8269B350-8875-49F9-A9EA-DEF8718FEBE4}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/OpenAI.csproj b/src/OpenAI.csproj index 54e759520..9cbba7f62 100644 --- a/src/OpenAI.csproj +++ b/src/OpenAI.csproj @@ -71,6 +71,6 @@ - + From 2e97ef736cecf6c7791b055a87ad79b0fc25a350 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Mon, 15 Jul 2024 10:09:28 -0700 Subject: [PATCH 58/72] move over update for protocol-convenience cast --- .../Assistants/AssistantClient.Protocol.cs | 17 ++++++++--------- src/Custom/Assistants/AssistantClient.cs | 1 - src/To.Be.Generated/MessagesPageEnumerator.cs | 4 +++- src/To.Be.Generated/RunStepsPageEnumerator.cs | 14 +++++++------- src/To.Be.Generated/RunStepsPageToken.cs | 1 + 5 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/Custom/Assistants/AssistantClient.Protocol.cs b/src/Custom/Assistants/AssistantClient.Protocol.cs index b6cd32248..0f383cb56 100644 --- a/src/Custom/Assistants/AssistantClient.Protocol.cs +++ b/src/Custom/Assistants/AssistantClient.Protocol.cs @@ -2,7 +2,6 @@ using System.ClientModel; using System.ClientModel.Primitives; using System.Collections.Generic; -using System.Threading; using System.Threading.Tasks; namespace OpenAI.Assistants; @@ -67,7 +66,7 @@ public virtual ClientResult CreateAssistant(BinaryContent content, RequestOption /// The response returned from the service. public virtual IAsyncEnumerable GetAssistantsAsync(int? limit, string order, string after, string before, RequestOptions options) { - PageResultEnumerator enumerator = new AssistantsPageEnumerator(_pipeline, _endpoint, limit, order, after, before, options); + AssistantsPageEnumerator enumerator = new AssistantsPageEnumerator(_pipeline, _endpoint, limit, order, after, before, options); return PageCollectionHelpers.CreateAsync(enumerator); } @@ -97,7 +96,7 @@ public virtual IAsyncEnumerable GetAssistantsAsync(int? limit, str /// The response returned from the service. public virtual IEnumerable GetAssistants(int? limit, string order, string after, string before, RequestOptions options) { - PageResultEnumerator enumerator = new AssistantsPageEnumerator(_pipeline, _endpoint, limit, order, after, before, options); + AssistantsPageEnumerator enumerator = new AssistantsPageEnumerator(_pipeline, _endpoint, limit, order, after, before, options); return PageCollectionHelpers.Create(enumerator); } @@ -219,7 +218,7 @@ public virtual IAsyncEnumerable GetMessagesAsync(string threadId, { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); - PageResultEnumerator enumerator = new MessagesPageEnumerator(_pipeline, _endpoint, threadId, limit, order, after, before, options); + MessagesPageEnumerator enumerator = new MessagesPageEnumerator(_pipeline, _endpoint, threadId, limit, order, after, before, options); return PageCollectionHelpers.CreateAsync(enumerator); } @@ -227,7 +226,7 @@ public virtual IEnumerable GetMessages(string threadId, int? limit { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); - PageResultEnumerator enumerator = new MessagesPageEnumerator(_pipeline, _endpoint, threadId, limit, order, after, before, options); + MessagesPageEnumerator enumerator = new MessagesPageEnumerator(_pipeline, _endpoint, threadId, limit, order, after, before, options); return PageCollectionHelpers.Create(enumerator); } @@ -273,7 +272,7 @@ public virtual IAsyncEnumerable GetRunsAsync(string threadId, int? { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); - PageResultEnumerator enumerator = new RunsPageEnumerator(_pipeline, _endpoint, threadId, limit, order, after, before, options); + RunsPageEnumerator enumerator = new RunsPageEnumerator(_pipeline, _endpoint, threadId, limit, order, after, before, options); return PageCollectionHelpers.CreateAsync(enumerator); } @@ -281,7 +280,7 @@ public virtual IEnumerable GetRuns(string threadId, int? limit, st { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); - PageResultEnumerator enumerator = new RunsPageEnumerator(_pipeline, _endpoint, threadId, limit, order, after, before, options); + RunsPageEnumerator enumerator = new RunsPageEnumerator(_pipeline, _endpoint, threadId, limit, order, after, before, options); return PageCollectionHelpers.Create(enumerator); } @@ -322,7 +321,7 @@ public virtual IAsyncEnumerable GetRunStepsAsync(string threadId, Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); Argument.AssertNotNullOrEmpty(runId, nameof(runId)); - PageResultEnumerator enumerator = new RunStepsPageEnumerator(_pipeline, _endpoint, threadId, runId, limit, order, after, before, options); + RunStepsPageEnumerator enumerator = new RunStepsPageEnumerator(_pipeline, _endpoint, threadId, runId, limit, order, after, before, options); return PageCollectionHelpers.CreateAsync(enumerator); } @@ -331,7 +330,7 @@ public virtual IEnumerable GetRunSteps(string threadId, string run Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); Argument.AssertNotNullOrEmpty(runId, nameof(runId)); - PageResultEnumerator enumerator = new RunStepsPageEnumerator(_pipeline, _endpoint, threadId, runId, limit, order, after, before, options); + RunStepsPageEnumerator enumerator = new RunStepsPageEnumerator(_pipeline, _endpoint, threadId, runId, limit, order, after, before, options); return PageCollectionHelpers.Create(enumerator); } diff --git a/src/Custom/Assistants/AssistantClient.cs b/src/Custom/Assistants/AssistantClient.cs index b39888e0f..52fa50147 100644 --- a/src/Custom/Assistants/AssistantClient.cs +++ b/src/Custom/Assistants/AssistantClient.cs @@ -3,7 +3,6 @@ using System.ClientModel.Primitives; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; -using System.Linq; using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; diff --git a/src/To.Be.Generated/MessagesPageEnumerator.cs b/src/To.Be.Generated/MessagesPageEnumerator.cs index 1df785aea..8ed555cd0 100644 --- a/src/To.Be.Generated/MessagesPageEnumerator.cs +++ b/src/To.Be.Generated/MessagesPageEnumerator.cs @@ -26,7 +26,8 @@ internal partial class MessagesPageEnumerator : PageEnumerator public MessagesPageEnumerator( ClientPipeline pipeline, Uri endpoint, - string threadId, int? limit, string order, string after, string before, + string threadId, + int? limit, string order, string after, string before, RequestOptions options) { _pipeline = pipeline; @@ -37,6 +38,7 @@ public MessagesPageEnumerator( _order = order; _after = after; _before = before; + _options = options; } diff --git a/src/To.Be.Generated/RunStepsPageEnumerator.cs b/src/To.Be.Generated/RunStepsPageEnumerator.cs index 09c7ab423..3cb0b285d 100644 --- a/src/To.Be.Generated/RunStepsPageEnumerator.cs +++ b/src/To.Be.Generated/RunStepsPageEnumerator.cs @@ -17,19 +17,19 @@ internal partial class RunStepsPageEnumerator : PageEnumerator private readonly string _runId; private readonly int? _limit; - private readonly string _order; + private readonly string? _order; // Note: this one is special - private string _after; + private string? _after; - private readonly string _before; + private readonly string? _before; private readonly RequestOptions _options; public RunStepsPageEnumerator( ClientPipeline pipeline, Uri endpoint, string threadId, string runId, - int? limit, string order, string after, string before, + int? limit, string? order, string? after, string? before, RequestOptions options) { _pipeline = pipeline; @@ -95,7 +95,7 @@ public override PageResult GetPageFromResult(ClientResult result) } // Note: these are the protocol methods - they are generated here - internal async virtual Task GetRunStepsPageAsync(string threadId, string runId, int? limit, string order, string after, string before, RequestOptions options) + internal async virtual Task GetRunStepsPageAsync(string threadId, string runId, int? limit, string? order, string? after, string? before, RequestOptions? options) { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); Argument.AssertNotNullOrEmpty(runId, nameof(runId)); @@ -104,7 +104,7 @@ internal async virtual Task GetRunStepsPageAsync(string threadId, return ClientResult.FromResponse(await _pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); } - internal virtual ClientResult GetRunStepsPage(string threadId, string runId, int? limit, string order, string after, string before, RequestOptions options) + internal virtual ClientResult GetRunStepsPage(string threadId, string runId, int? limit, string? order, string? after, string? before, RequestOptions? options) { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); Argument.AssertNotNullOrEmpty(runId, nameof(runId)); @@ -113,7 +113,7 @@ internal virtual ClientResult GetRunStepsPage(string threadId, string runId, int return ClientResult.FromResponse(_pipeline.ProcessMessage(message, options)); } - private PipelineMessage CreateGetRunStepsRequest(string threadId, string runId, int? limit, string order, string after, string before, RequestOptions options) + private PipelineMessage CreateGetRunStepsRequest(string threadId, string runId, int? limit, string? order, string? after, string? before, RequestOptions? options) { var message = _pipeline.CreateMessage(); message.ResponseClassifier = PipelineMessageClassifier200; diff --git a/src/To.Be.Generated/RunStepsPageToken.cs b/src/To.Be.Generated/RunStepsPageToken.cs index 309643c95..229f6f16d 100644 --- a/src/To.Be.Generated/RunStepsPageToken.cs +++ b/src/To.Be.Generated/RunStepsPageToken.cs @@ -22,6 +22,7 @@ protected RunStepsPageToken(string threadId, string runId, int? limit, string? o } public string ThreadId { get; } + public string RunId { get; } public int? Limit { get; } From 1ee04863929daa36fcacba0a97b98e2ed4f5b127 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Mon, 15 Jul 2024 10:18:41 -0700 Subject: [PATCH 59/72] some fixes --- .../VectorStores/VectorStoreClient.Convenience.cs | 1 - .../VectorStores/VectorStoreClient.Protocol.cs | 13 ++++++------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/Custom/VectorStores/VectorStoreClient.Convenience.cs b/src/Custom/VectorStores/VectorStoreClient.Convenience.cs index 886da3e5d..5cccf6129 100644 --- a/src/Custom/VectorStores/VectorStoreClient.Convenience.cs +++ b/src/Custom/VectorStores/VectorStoreClient.Convenience.cs @@ -2,7 +2,6 @@ using System.ClientModel; using System.Collections.Generic; using System.Linq; -using System.Threading; using System.Threading.Tasks; namespace OpenAI.VectorStores; diff --git a/src/Custom/VectorStores/VectorStoreClient.Protocol.cs b/src/Custom/VectorStores/VectorStoreClient.Protocol.cs index bd42ae360..69a82b365 100644 --- a/src/Custom/VectorStores/VectorStoreClient.Protocol.cs +++ b/src/Custom/VectorStores/VectorStoreClient.Protocol.cs @@ -4,7 +4,6 @@ using System.ClientModel.Primitives; using System.Collections.Generic; using System.ComponentModel; -using System.Threading; using System.Threading.Tasks; namespace OpenAI.VectorStores; @@ -54,7 +53,7 @@ public partial class VectorStoreClient [EditorBrowsable(EditorBrowsableState.Never)] public virtual IAsyncEnumerable GetVectorStoresAsync(int? limit, string order, string after, string before, RequestOptions options) { - PageResultEnumerator enumerator = new VectorStoresPageEnumerator(_pipeline, _endpoint, limit, order, after, before, options); + VectorStoresPageEnumerator enumerator = new VectorStoresPageEnumerator(_pipeline, _endpoint, limit, order, after, before, options); return PageCollectionHelpers.CreateAsync(enumerator); } @@ -85,7 +84,7 @@ public virtual IAsyncEnumerable GetVectorStoresAsync(int? limit, s [EditorBrowsable(EditorBrowsableState.Never)] public virtual IEnumerable GetVectorStores(int? limit, string order, string after, string before, RequestOptions options) { - PageResultEnumerator enumerator = new VectorStoresPageEnumerator(_pipeline, _endpoint, limit, order, after, before, options); + VectorStoresPageEnumerator enumerator = new VectorStoresPageEnumerator(_pipeline, _endpoint, limit, order, after, before, options); return PageCollectionHelpers.Create(enumerator); } @@ -263,7 +262,7 @@ public virtual IAsyncEnumerable GetFileAssociationsAsync(string ve { Argument.AssertNotNullOrEmpty(vectorStoreId, nameof(vectorStoreId)); - PageResultEnumerator enumerator = new VectorStoreFilesPageEnumerator(_pipeline, _endpoint, vectorStoreId, limit, order, after, before, filter, options); + VectorStoreFilesPageEnumerator enumerator = new VectorStoreFilesPageEnumerator(_pipeline, _endpoint, vectorStoreId, limit, order, after, before, filter, options); return PageCollectionHelpers.CreateAsync(enumerator); } @@ -300,7 +299,7 @@ public virtual IEnumerable GetFileAssociations(string vectorStoreI { Argument.AssertNotNullOrEmpty(vectorStoreId, nameof(vectorStoreId)); - PageResultEnumerator enumerator = new MessagesPageEnumerator(_pipeline, _endpoint, vectorStoreId, limit, order, after, before, options); + VectorStoreFilesPageEnumerator enumerator = new VectorStoreFilesPageEnumerator(_pipeline, _endpoint, vectorStoreId, limit, order, after, before, filter, options); return PageCollectionHelpers.Create(enumerator); } @@ -579,7 +578,7 @@ public virtual IAsyncEnumerable GetFileAssociationsAsync(string ve Argument.AssertNotNullOrEmpty(vectorStoreId, nameof(vectorStoreId)); Argument.AssertNotNullOrEmpty(batchId, nameof(batchId)); - PageResultEnumerator enumerator = new VectorStoreFileBatchesPageEnumerator(_pipeline, _endpoint, vectorStoreId, batchId, limit, order, after, before, filter, options); + VectorStoreFileBatchesPageEnumerator enumerator = new VectorStoreFileBatchesPageEnumerator(_pipeline, _endpoint, vectorStoreId, batchId, limit, order, after, before, filter, options); return PageCollectionHelpers.CreateAsync(enumerator); } @@ -618,7 +617,7 @@ public virtual IEnumerable GetFileAssociations(string vectorStoreI Argument.AssertNotNullOrEmpty(vectorStoreId, nameof(vectorStoreId)); Argument.AssertNotNullOrEmpty(batchId, nameof(batchId)); - PageResultEnumerator enumerator = new VectorStoreFileBatchesPageEnumerator(_pipeline, _endpoint, vectorStoreId, batchId, limit, order, after, before, filter, options); + VectorStoreFileBatchesPageEnumerator enumerator = new VectorStoreFileBatchesPageEnumerator(_pipeline, _endpoint, vectorStoreId, batchId, limit, order, after, before, filter, options); return PageCollectionHelpers.Create(enumerator); } } From 4ce3888cce53b19a62a703efb2dca795d7381ce4 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Mon, 15 Jul 2024 10:25:42 -0700 Subject: [PATCH 60/72] updates from SCM code --- .../Internal/PageCollectionHelpers.cs | 3 +-- .../Internal/PageResultEnumerator.cs | 13 ------------- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/src/To.Be.Generated/Internal/PageCollectionHelpers.cs b/src/To.Be.Generated/Internal/PageCollectionHelpers.cs index 5cac0d7d6..b5be39a6e 100644 --- a/src/To.Be.Generated/Internal/PageCollectionHelpers.cs +++ b/src/To.Be.Generated/Internal/PageCollectionHelpers.cs @@ -1,5 +1,4 @@ -using System; -using System.ClientModel; +using System.ClientModel; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; diff --git a/src/To.Be.Generated/Internal/PageResultEnumerator.cs b/src/To.Be.Generated/Internal/PageResultEnumerator.cs index 89932e02a..27629b171 100644 --- a/src/To.Be.Generated/Internal/PageResultEnumerator.cs +++ b/src/To.Be.Generated/Internal/PageResultEnumerator.cs @@ -8,7 +8,6 @@ namespace OpenAI; -// Note: implements both sync and async enumerator interfaces. internal abstract class PageResultEnumerator : IAsyncEnumerator, IEnumerator { private ClientResult? _current; @@ -16,8 +15,6 @@ internal abstract class PageResultEnumerator : IAsyncEnumerator, I public ClientResult Current => _current!; - #region Service-specific methods that need to be generated on the subclient - public abstract Task GetFirstAsync(); public abstract ClientResult GetFirst(); @@ -28,10 +25,6 @@ internal abstract class PageResultEnumerator : IAsyncEnumerator, I public abstract bool HasNext(ClientResult result); - #endregion - - #region IEnumerator implementation - object IEnumerator.Current => ((IEnumerator)this).Current; public bool MoveNext() @@ -58,10 +51,6 @@ public bool MoveNext() void IDisposable.Dispose() { } - #endregion - - #region IAsyncEnumerator implementation - public async ValueTask MoveNextAsync() { if (!_hasNext) @@ -83,6 +72,4 @@ public async ValueTask MoveNextAsync() } ValueTask IAsyncDisposable.DisposeAsync() => default; - - #endregion } \ No newline at end of file From 0622853453b71f45aa6d8ea3b29a134cb19e4e02 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Mon, 15 Jul 2024 10:54:33 -0700 Subject: [PATCH 61/72] fix tests --- src/Custom/Assistants/AssistantClient.cs | 1 + tests/Assistants/AssistantTests.cs | 44 +++++++++++++++--------- 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/src/Custom/Assistants/AssistantClient.cs b/src/Custom/Assistants/AssistantClient.cs index 52fa50147..b39888e0f 100644 --- a/src/Custom/Assistants/AssistantClient.cs +++ b/src/Custom/Assistants/AssistantClient.cs @@ -3,6 +3,7 @@ using System.ClientModel.Primitives; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; +using System.Linq; using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; diff --git a/tests/Assistants/AssistantTests.cs b/tests/Assistants/AssistantTests.cs index e568ab848..6b645301e 100644 --- a/tests/Assistants/AssistantTests.cs +++ b/tests/Assistants/AssistantTests.cs @@ -272,22 +272,24 @@ public void BasicRunStepFunctionalityWorks() PageCollection pages = client.GetRunSteps(run); PageResult firstPage = pages.GetCurrentPage(); + RunStep firstStep = firstPage.Values[0]; + RunStep secondStep = firstPage.Values[1]; - IEnumerable runSteps = pages.GetAllValues(); - Assert.That(runSteps.Count, Is.GreaterThan(1)); + Assert.That(firstPage.Values.Count, Is.GreaterThan(1)); Assert.Multiple(() => { - Assert.That(runSteps.First().AssistantId, Is.EqualTo(assistant.Id)); - Assert.That(runSteps.First().ThreadId, Is.EqualTo(thread.Id)); - Assert.That(runSteps.First().RunId, Is.EqualTo(run.Id)); - Assert.That(runSteps.First().CreatedAt, Is.GreaterThan(s_2024)); - Assert.That(runSteps.First().CompletedAt, Is.GreaterThan(s_2024)); + Assert.That(firstStep.AssistantId, Is.EqualTo(assistant.Id)); + Assert.That(firstStep.ThreadId, Is.EqualTo(thread.Id)); + Assert.That(firstStep.RunId, Is.EqualTo(run.Id)); + Assert.That(firstStep.CreatedAt, Is.GreaterThan(s_2024)); + Assert.That(firstStep.CompletedAt, Is.GreaterThan(s_2024)); }); - RunStepDetails details = runSteps.First().Details; + RunStepDetails details = firstStep.Details; Assert.That(details?.CreatedMessageId, Is.Not.Null.And.Not.Empty); string rawContent = firstPage.GetRawResponse().Content.ToString(); - details = runSteps.ElementAt(1).Details; + + details = secondStep.Details; Assert.Multiple(() => { Assert.That(details?.ToolCalls.Count, Is.GreaterThan(0)); @@ -393,11 +395,12 @@ public void FunctionToolsWork() } Assert.That(run.Status, Is.EqualTo(RunStatus.Completed)); - IEnumerable messages = client.GetMessages(run.ThreadId, new MessageCollectionOptions() { Order = ListOrder.NewestFirst }).GetAllValues(); - Assert.That(messages.Count, Is.GreaterThan(1)); - Assert.That(messages.First().Role, Is.EqualTo(MessageRole.Assistant)); - Assert.That(messages.First().Content?[0], Is.Not.Null); - Assert.That(messages.First().Content[0].Text.ToLowerInvariant(), Does.Contain("tacos")); + PageCollection messagePages = client.GetMessages(run.ThreadId, new MessageCollectionOptions() { Order = ListOrder.NewestFirst }); + PageResult firstPage = messagePages.GetCurrentPage(); + Assert.That(firstPage.Values.Count, Is.GreaterThan(1)); + Assert.That(firstPage.Values[0].Role, Is.EqualTo(MessageRole.Assistant)); + Assert.That(firstPage.Values[0].Content?[0], Is.Not.Null); + Assert.That(firstPage.Values[0].Content[0].Text.ToLowerInvariant(), Does.Contain("tacos")); } [Test] @@ -603,8 +606,12 @@ This file describes the favorite foods of several people. Assert.That(run.Status, Is.EqualTo(RunStatus.Completed)); IEnumerable messages = client.GetMessages(thread, new() { Order = ListOrder.NewestFirst }).GetAllValues(); + int messageCount = 0; + bool hasCake = false; foreach (ThreadMessage message in messages) { + messageCount++; + foreach (MessageContent content in message.Content) { Console.WriteLine(content.Text); @@ -612,10 +619,15 @@ This file describes the favorite foods of several people. { Console.WriteLine($" --> From file: {annotation.InputFileId}, replacement: {annotation.TextToReplace}"); } + + if (!hasCake) + { + hasCake = content.Text.ToLower().Contains("cake"); + } } } - Assert.That(messages.Count() > 1); - Assert.That(messages.Any(message => message.Content.Any(content => content.Text.ToLower().Contains("cake")))); + Assert.That(messageCount > 1); + Assert.That(hasCake, Is.True); } [Test] From e492b7c524fca8b08be0704a7ab60a0c4b8e26a2 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Mon, 15 Jul 2024 11:26:47 -0700 Subject: [PATCH 62/72] remove internal protocol method implementations that have moved to internal enumerator types --- .../Assistants/AssistantClient.Protocol.cs | 164 ++++++++++++++++++ ...InternalAssistantMessageClient.Protocol.cs | 70 -------- .../InternalAssistantRunClient.Protocol.cs | 144 --------------- .../AssistantsPageEnumerator.cs | 13 +- src/To.Be.Generated/MessagesPageEnumerator.cs | 15 +- src/To.Be.Generated/RunStepsPageEnumerator.cs | 15 +- src/To.Be.Generated/RunsPageEnumerator.cs | 15 +- 7 files changed, 188 insertions(+), 248 deletions(-) diff --git a/src/Custom/Assistants/AssistantClient.Protocol.cs b/src/Custom/Assistants/AssistantClient.Protocol.cs index 0f383cb56..aabe8bdbf 100644 --- a/src/Custom/Assistants/AssistantClient.Protocol.cs +++ b/src/Custom/Assistants/AssistantClient.Protocol.cs @@ -214,6 +214,33 @@ public virtual Task CreateMessageAsync(string threadId, BinaryCont public virtual ClientResult CreateMessage(string threadId, BinaryContent content, RequestOptions options = null) => _messageSubClient.CreateMessage(threadId, content, options); + /// + /// [Protocol Method] Returns a list of messages for a given thread. + /// + /// The ID of the [thread](/docs/api-reference/threads) the messages belong to. + /// + /// A limit on the number of objects to be returned. Limit can range between 1 and 100, and the + /// default is 20. + /// + /// + /// Sort order by the `created_at` timestamp of the objects. `asc` for ascending order and`desc` + /// for descending order. Allowed values: "asc" | "desc" + /// + /// + /// A cursor for use in pagination. `after` is an object ID that defines your place in the list. + /// For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + /// subsequent call can include after=obj_foo in order to fetch the next page of the list. + /// + /// + /// A cursor for use in pagination. `before` is an object ID that defines your place in the list. + /// For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + /// subsequent call can include before=obj_foo in order to fetch the previous page of the list. + /// + /// The request options, which can override default behaviors of the client pipeline on a per-call basis. + /// is null. + /// is an empty string, and was expected to be non-empty. + /// Service returned a non-success status code. + /// TODO public virtual IAsyncEnumerable GetMessagesAsync(string threadId, int? limit, string order, string after, string before, RequestOptions options) { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); @@ -222,6 +249,33 @@ public virtual IAsyncEnumerable GetMessagesAsync(string threadId, return PageCollectionHelpers.CreateAsync(enumerator); } + /// + /// [Protocol Method] Returns a list of messages for a given thread. + /// + /// The ID of the [thread](/docs/api-reference/threads) the messages belong to. + /// + /// A limit on the number of objects to be returned. Limit can range between 1 and 100, and the + /// default is 20. + /// + /// + /// Sort order by the `created_at` timestamp of the objects. `asc` for ascending order and`desc` + /// for descending order. Allowed values: "asc" | "desc" + /// + /// + /// A cursor for use in pagination. `after` is an object ID that defines your place in the list. + /// For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + /// subsequent call can include after=obj_foo in order to fetch the next page of the list. + /// + /// + /// A cursor for use in pagination. `before` is an object ID that defines your place in the list. + /// For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + /// subsequent call can include before=obj_foo in order to fetch the previous page of the list. + /// + /// The request options, which can override default behaviors of the client pipeline on a per-call basis. + /// is null. + /// is an empty string, and was expected to be non-empty. + /// Service returned a non-success status code. + /// TODO public virtual IEnumerable GetMessages(string threadId, int? limit, string order, string after, string before, RequestOptions options) { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); @@ -268,6 +322,33 @@ public virtual Task CreateRunAsync(string threadId, BinaryContent public virtual ClientResult CreateRun(string threadId, BinaryContent content, RequestOptions options = null) => _runSubClient.CreateRun(threadId, content, options); + /// + /// [Protocol Method] Returns a list of runs belonging to a thread. + /// + /// The ID of the thread the run belongs to. + /// + /// A limit on the number of objects to be returned. Limit can range between 1 and 100, and the + /// default is 20. + /// + /// + /// Sort order by the `created_at` timestamp of the objects. `asc` for ascending order and`desc` + /// for descending order. Allowed values: "asc" | "desc" + /// + /// + /// A cursor for use in pagination. `after` is an object ID that defines your place in the list. + /// For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + /// subsequent call can include after=obj_foo in order to fetch the next page of the list. + /// + /// + /// A cursor for use in pagination. `before` is an object ID that defines your place in the list. + /// For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + /// subsequent call can include before=obj_foo in order to fetch the previous page of the list. + /// + /// The request options, which can override default behaviors of the client pipeline on a per-call basis. + /// is null. + /// is an empty string, and was expected to be non-empty. + /// Service returned a non-success status code. + /// TODO public virtual IAsyncEnumerable GetRunsAsync(string threadId, int? limit, string order, string after, string before, RequestOptions options) { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); @@ -276,6 +357,33 @@ public virtual IAsyncEnumerable GetRunsAsync(string threadId, int? return PageCollectionHelpers.CreateAsync(enumerator); } + /// + /// [Protocol Method] Returns a list of runs belonging to a thread. + /// + /// The ID of the thread the run belongs to. + /// + /// A limit on the number of objects to be returned. Limit can range between 1 and 100, and the + /// default is 20. + /// + /// + /// Sort order by the `created_at` timestamp of the objects. `asc` for ascending order and`desc` + /// for descending order. Allowed values: "asc" | "desc" + /// + /// + /// A cursor for use in pagination. `after` is an object ID that defines your place in the list. + /// For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + /// subsequent call can include after=obj_foo in order to fetch the next page of the list. + /// + /// + /// A cursor for use in pagination. `before` is an object ID that defines your place in the list. + /// For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + /// subsequent call can include before=obj_foo in order to fetch the previous page of the list. + /// + /// The request options, which can override default behaviors of the client pipeline on a per-call basis. + /// is null. + /// is an empty string, and was expected to be non-empty. + /// Service returned a non-success status code. + /// TODO public virtual IEnumerable GetRuns(string threadId, int? limit, string order, string after, string before, RequestOptions options) { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); @@ -316,6 +424,34 @@ public virtual Task SubmitToolOutputsToRunAsync(string threadId, s public virtual ClientResult SubmitToolOutputsToRun(string threadId, string runId, BinaryContent content, RequestOptions options = null) => _runSubClient.SubmitToolOutputsToRun(threadId, runId, content, options); + /// + /// [Protocol Method] Returns a list of run steps belonging to a run. + /// + /// The ID of the thread the run and run steps belong to. + /// The ID of the run the run steps belong to. + /// + /// A limit on the number of objects to be returned. Limit can range between 1 and 100, and the + /// default is 20. + /// + /// + /// Sort order by the `created_at` timestamp of the objects. `asc` for ascending order and`desc` + /// for descending order. Allowed values: "asc" | "desc" + /// + /// + /// A cursor for use in pagination. `after` is an object ID that defines your place in the list. + /// For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + /// subsequent call can include after=obj_foo in order to fetch the next page of the list. + /// + /// + /// A cursor for use in pagination. `before` is an object ID that defines your place in the list. + /// For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + /// subsequent call can include before=obj_foo in order to fetch the previous page of the list. + /// + /// The request options, which can override default behaviors of the client pipeline on a per-call basis. + /// or is null. + /// or is an empty string, and was expected to be non-empty. + /// Service returned a non-success status code. + /// TODO public virtual IAsyncEnumerable GetRunStepsAsync(string threadId, string runId, int? limit, string order, string after, string before, RequestOptions options) { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); @@ -325,6 +461,34 @@ public virtual IAsyncEnumerable GetRunStepsAsync(string threadId, return PageCollectionHelpers.CreateAsync(enumerator); } + /// + /// [Protocol Method] Returns a list of run steps belonging to a run. + /// + /// The ID of the thread the run and run steps belong to. + /// The ID of the run the run steps belong to. + /// + /// A limit on the number of objects to be returned. Limit can range between 1 and 100, and the + /// default is 20. + /// + /// + /// Sort order by the `created_at` timestamp of the objects. `asc` for ascending order and`desc` + /// for descending order. Allowed values: "asc" | "desc" + /// + /// + /// A cursor for use in pagination. `after` is an object ID that defines your place in the list. + /// For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + /// subsequent call can include after=obj_foo in order to fetch the next page of the list. + /// + /// + /// A cursor for use in pagination. `before` is an object ID that defines your place in the list. + /// For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + /// subsequent call can include before=obj_foo in order to fetch the previous page of the list. + /// + /// The request options, which can override default behaviors of the client pipeline on a per-call basis. + /// or is null. + /// or is an empty string, and was expected to be non-empty. + /// Service returned a non-success status code. + /// TODO public virtual IEnumerable GetRunSteps(string threadId, string runId, int? limit, string order, string after, string before, RequestOptions options) { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); diff --git a/src/Custom/Assistants/Internal/InternalAssistantMessageClient.Protocol.cs b/src/Custom/Assistants/Internal/InternalAssistantMessageClient.Protocol.cs index 04717a612..fb54903bc 100644 --- a/src/Custom/Assistants/Internal/InternalAssistantMessageClient.Protocol.cs +++ b/src/Custom/Assistants/Internal/InternalAssistantMessageClient.Protocol.cs @@ -45,76 +45,6 @@ public virtual ClientResult CreateMessage(string threadId, BinaryContent content return ClientResult.FromResponse(_pipeline.ProcessMessage(message, options)); } - /// - /// [Protocol Method] Returns a list of messages for a given thread. - /// - /// The ID of the [thread](/docs/api-reference/threads) the messages belong to. - /// - /// A limit on the number of objects to be returned. Limit can range between 1 and 100, and the - /// default is 20. - /// - /// - /// Sort order by the `created_at` timestamp of the objects. `asc` for ascending order and`desc` - /// for descending order. Allowed values: "asc" | "desc" - /// - /// - /// A cursor for use in pagination. `after` is an object ID that defines your place in the list. - /// For instance, if you make a list request and receive 100 objects, ending with obj_foo, your - /// subsequent call can include after=obj_foo in order to fetch the next page of the list. - /// - /// - /// A cursor for use in pagination. `before` is an object ID that defines your place in the list. - /// For instance, if you make a list request and receive 100 objects, ending with obj_foo, your - /// subsequent call can include before=obj_foo in order to fetch the previous page of the list. - /// - /// The request options, which can override default behaviors of the client pipeline on a per-call basis. - /// is null. - /// is an empty string, and was expected to be non-empty. - /// Service returned a non-success status code. - /// The response returned from the service. - public virtual async Task GetMessagesAsync(string threadId, int? limit, string order, string after, string before, RequestOptions options) - { - Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); - - using PipelineMessage message = CreateGetMessagesRequest(threadId, limit, order, after, before, options); - return ClientResult.FromResponse(await _pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); - } - - /// - /// [Protocol Method] Returns a list of messages for a given thread. - /// - /// The ID of the [thread](/docs/api-reference/threads) the messages belong to. - /// - /// A limit on the number of objects to be returned. Limit can range between 1 and 100, and the - /// default is 20. - /// - /// - /// Sort order by the `created_at` timestamp of the objects. `asc` for ascending order and`desc` - /// for descending order. Allowed values: "asc" | "desc" - /// - /// - /// A cursor for use in pagination. `after` is an object ID that defines your place in the list. - /// For instance, if you make a list request and receive 100 objects, ending with obj_foo, your - /// subsequent call can include after=obj_foo in order to fetch the next page of the list. - /// - /// - /// A cursor for use in pagination. `before` is an object ID that defines your place in the list. - /// For instance, if you make a list request and receive 100 objects, ending with obj_foo, your - /// subsequent call can include before=obj_foo in order to fetch the previous page of the list. - /// - /// The request options, which can override default behaviors of the client pipeline on a per-call basis. - /// is null. - /// is an empty string, and was expected to be non-empty. - /// Service returned a non-success status code. - /// The response returned from the service. - public virtual ClientResult GetMessages(string threadId, int? limit, string order, string after, string before, RequestOptions options) - { - Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); - - using PipelineMessage message = CreateGetMessagesRequest(threadId, limit, order, after, before, options); - return ClientResult.FromResponse(_pipeline.ProcessMessage(message, options)); - } - /// /// [Protocol Method] Retrieve a message. /// diff --git a/src/Custom/Assistants/Internal/InternalAssistantRunClient.Protocol.cs b/src/Custom/Assistants/Internal/InternalAssistantRunClient.Protocol.cs index 626228d85..4ffef5d1b 100644 --- a/src/Custom/Assistants/Internal/InternalAssistantRunClient.Protocol.cs +++ b/src/Custom/Assistants/Internal/InternalAssistantRunClient.Protocol.cs @@ -121,76 +121,6 @@ public virtual ClientResult CreateRun(string threadId, BinaryContent content, Re } } - /// - /// [Protocol Method] Returns a list of runs belonging to a thread. - /// - /// The ID of the thread the run belongs to. - /// - /// A limit on the number of objects to be returned. Limit can range between 1 and 100, and the - /// default is 20. - /// - /// - /// Sort order by the `created_at` timestamp of the objects. `asc` for ascending order and`desc` - /// for descending order. Allowed values: "asc" | "desc" - /// - /// - /// A cursor for use in pagination. `after` is an object ID that defines your place in the list. - /// For instance, if you make a list request and receive 100 objects, ending with obj_foo, your - /// subsequent call can include after=obj_foo in order to fetch the next page of the list. - /// - /// - /// A cursor for use in pagination. `before` is an object ID that defines your place in the list. - /// For instance, if you make a list request and receive 100 objects, ending with obj_foo, your - /// subsequent call can include before=obj_foo in order to fetch the previous page of the list. - /// - /// The request options, which can override default behaviors of the client pipeline on a per-call basis. - /// is null. - /// is an empty string, and was expected to be non-empty. - /// Service returned a non-success status code. - /// The response returned from the service. - public virtual async Task GetRunsAsync(string threadId, int? limit, string order, string after, string before, RequestOptions options) - { - Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); - - using PipelineMessage message = CreateGetRunsRequest(threadId, limit, order, after, before, options); - return ClientResult.FromResponse(await _pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); - } - - /// - /// [Protocol Method] Returns a list of runs belonging to a thread. - /// - /// The ID of the thread the run belongs to. - /// - /// A limit on the number of objects to be returned. Limit can range between 1 and 100, and the - /// default is 20. - /// - /// - /// Sort order by the `created_at` timestamp of the objects. `asc` for ascending order and`desc` - /// for descending order. Allowed values: "asc" | "desc" - /// - /// - /// A cursor for use in pagination. `after` is an object ID that defines your place in the list. - /// For instance, if you make a list request and receive 100 objects, ending with obj_foo, your - /// subsequent call can include after=obj_foo in order to fetch the next page of the list. - /// - /// - /// A cursor for use in pagination. `before` is an object ID that defines your place in the list. - /// For instance, if you make a list request and receive 100 objects, ending with obj_foo, your - /// subsequent call can include before=obj_foo in order to fetch the previous page of the list. - /// - /// The request options, which can override default behaviors of the client pipeline on a per-call basis. - /// is null. - /// is an empty string, and was expected to be non-empty. - /// Service returned a non-success status code. - /// The response returned from the service. - public virtual ClientResult GetRuns(string threadId, int? limit, string order, string after, string before, RequestOptions options) - { - Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); - - using PipelineMessage message = CreateGetRunsRequest(threadId, limit, order, after, before, options); - return ClientResult.FromResponse(_pipeline.ProcessMessage(message, options)); - } - /// /// [Protocol Method] Retrieves a run. /// @@ -377,80 +307,6 @@ public virtual ClientResult SubmitToolOutputsToRun(string threadId, string runId } } - /// - /// [Protocol Method] Returns a list of run steps belonging to a run. - /// - /// The ID of the thread the run and run steps belong to. - /// The ID of the run the run steps belong to. - /// - /// A limit on the number of objects to be returned. Limit can range between 1 and 100, and the - /// default is 20. - /// - /// - /// Sort order by the `created_at` timestamp of the objects. `asc` for ascending order and`desc` - /// for descending order. Allowed values: "asc" | "desc" - /// - /// - /// A cursor for use in pagination. `after` is an object ID that defines your place in the list. - /// For instance, if you make a list request and receive 100 objects, ending with obj_foo, your - /// subsequent call can include after=obj_foo in order to fetch the next page of the list. - /// - /// - /// A cursor for use in pagination. `before` is an object ID that defines your place in the list. - /// For instance, if you make a list request and receive 100 objects, ending with obj_foo, your - /// subsequent call can include before=obj_foo in order to fetch the previous page of the list. - /// - /// The request options, which can override default behaviors of the client pipeline on a per-call basis. - /// or is null. - /// or is an empty string, and was expected to be non-empty. - /// Service returned a non-success status code. - /// The response returned from the service. - public virtual async Task GetRunStepsAsync(string threadId, string runId, int? limit, string order, string after, string before, RequestOptions options) - { - Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); - Argument.AssertNotNullOrEmpty(runId, nameof(runId)); - - using PipelineMessage message = CreateGetRunStepsRequest(threadId, runId, limit, order, after, before, options); - return ClientResult.FromResponse(await _pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); - } - - /// - /// [Protocol Method] Returns a list of run steps belonging to a run. - /// - /// The ID of the thread the run and run steps belong to. - /// The ID of the run the run steps belong to. - /// - /// A limit on the number of objects to be returned. Limit can range between 1 and 100, and the - /// default is 20. - /// - /// - /// Sort order by the `created_at` timestamp of the objects. `asc` for ascending order and`desc` - /// for descending order. Allowed values: "asc" | "desc" - /// - /// - /// A cursor for use in pagination. `after` is an object ID that defines your place in the list. - /// For instance, if you make a list request and receive 100 objects, ending with obj_foo, your - /// subsequent call can include after=obj_foo in order to fetch the next page of the list. - /// - /// - /// A cursor for use in pagination. `before` is an object ID that defines your place in the list. - /// For instance, if you make a list request and receive 100 objects, ending with obj_foo, your - /// subsequent call can include before=obj_foo in order to fetch the previous page of the list. - /// - /// The request options, which can override default behaviors of the client pipeline on a per-call basis. - /// or is null. - /// or is an empty string, and was expected to be non-empty. - /// Service returned a non-success status code. - /// The response returned from the service. - public virtual ClientResult GetRunSteps(string threadId, string runId, int? limit, string order, string after, string before, RequestOptions options) - { - Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); - Argument.AssertNotNullOrEmpty(runId, nameof(runId)); - - using PipelineMessage message = CreateGetRunStepsRequest(threadId, runId, limit, order, after, before, options); - return ClientResult.FromResponse(_pipeline.ProcessMessage(message, options)); - } - /// /// [Protocol Method] Retrieves a run step. /// diff --git a/src/To.Be.Generated/AssistantsPageEnumerator.cs b/src/To.Be.Generated/AssistantsPageEnumerator.cs index f18521c1e..44ae3e9ea 100644 --- a/src/To.Be.Generated/AssistantsPageEnumerator.cs +++ b/src/To.Be.Generated/AssistantsPageEnumerator.cs @@ -16,7 +16,6 @@ internal partial class AssistantsPageEnumerator : PageEnumerator private readonly int? _limit; private readonly string _order; - // Note: this one is special private string _after; private readonly string _before; @@ -39,10 +38,10 @@ public AssistantsPageEnumerator( } public override async Task GetFirstAsync() - => await GetAssistantsPageAsync(_limit, _order, _after, _before, _options).ConfigureAwait(false); + => await GetAssistantsAsync(_limit, _order, _after, _before, _options).ConfigureAwait(false); public override ClientResult GetFirst() - => GetAssistantsPage(_limit, _order, _after, _before, _options); + => GetAssistants(_limit, _order, _after, _before, _options); public override async Task GetNextAsync(ClientResult result) { @@ -51,7 +50,7 @@ public override async Task GetNextAsync(ClientResult result) using JsonDocument doc = JsonDocument.Parse(response.Content); _after = doc.RootElement.GetProperty("last_id"u8).GetString()!; - return await GetAssistantsPageAsync(_limit, _order, _after, _before, _options).ConfigureAwait(false); + return await GetAssistantsAsync(_limit, _order, _after, _before, _options).ConfigureAwait(false); } public override ClientResult GetNext(ClientResult result) @@ -61,7 +60,7 @@ public override ClientResult GetNext(ClientResult result) using JsonDocument doc = JsonDocument.Parse(response.Content); _after = doc.RootElement.GetProperty("last_id"u8).GetString()!; - return GetAssistantsPage(_limit, _order, _after, _before, _options); + return GetAssistants(_limit, _order, _after, _before, _options); } public override bool HasNext(ClientResult result) @@ -88,13 +87,13 @@ public override PageResult GetPageFromResult(ClientResult result) // Note: these are the protocol methods - they are generated here - internal virtual async Task GetAssistantsPageAsync(int? limit, string order, string after, string before, RequestOptions options) + internal virtual async Task GetAssistantsAsync(int? limit, string order, string after, string before, RequestOptions options) { using PipelineMessage message = CreateGetAssistantsRequest(limit, order, after, before, options); return ClientResult.FromResponse(await _pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); } - internal virtual ClientResult GetAssistantsPage(int? limit, string order, string after, string before, RequestOptions options) + internal virtual ClientResult GetAssistants(int? limit, string order, string after, string before, RequestOptions options) { using PipelineMessage message = CreateGetAssistantsRequest(limit, order, after, before, options); return ClientResult.FromResponse(_pipeline.ProcessMessage(message, options)); diff --git a/src/To.Be.Generated/MessagesPageEnumerator.cs b/src/To.Be.Generated/MessagesPageEnumerator.cs index 8ed555cd0..a4a262c33 100644 --- a/src/To.Be.Generated/MessagesPageEnumerator.cs +++ b/src/To.Be.Generated/MessagesPageEnumerator.cs @@ -17,7 +17,6 @@ internal partial class MessagesPageEnumerator : PageEnumerator private readonly int? _limit; private readonly string _order; - // Note: this one is special private string _after; private readonly string _before; @@ -43,10 +42,10 @@ public MessagesPageEnumerator( } public override async Task GetFirstAsync() - => await GetMessagesPageAsync(_threadId, _limit, _order, _after, _before, _options).ConfigureAwait(false); + => await GetMessagesAsync(_threadId, _limit, _order, _after, _before, _options).ConfigureAwait(false); public override ClientResult GetFirst() - => GetMessagesPage(_threadId, _limit, _order, _after, _before, _options); + => GetMessages(_threadId, _limit, _order, _after, _before, _options); public override async Task GetNextAsync(ClientResult result) { @@ -55,7 +54,7 @@ public override async Task GetNextAsync(ClientResult result) using JsonDocument doc = JsonDocument.Parse(response.Content); _after = doc.RootElement.GetProperty("last_id"u8).GetString()!; - return await GetMessagesPageAsync(_threadId, _limit, _order, _after, _before, _options).ConfigureAwait(false); + return await GetMessagesAsync(_threadId, _limit, _order, _after, _before, _options).ConfigureAwait(false); } public override ClientResult GetNext(ClientResult result) @@ -65,7 +64,7 @@ public override ClientResult GetNext(ClientResult result) using JsonDocument doc = JsonDocument.Parse(response.Content); _after = doc.RootElement.GetProperty("last_id"u8).GetString()!; - return GetMessagesPage(_threadId, _limit, _order, _after, _before, _options); + return GetMessages(_threadId, _limit, _order, _after, _before, _options); } public override bool HasNext(ClientResult result) @@ -78,7 +77,6 @@ public override bool HasNext(ClientResult result) return hasMore; } - // Note: this is the deserialization method that converts protocol to convenience public override PageResult GetPageFromResult(ClientResult result) { PipelineResponse response = result.GetRawResponse(); @@ -91,8 +89,7 @@ public override PageResult GetPageFromResult(ClientResult result) return PageResult.Create(list.Data, pageToken, nextPageToken, response); } - // Note: these are the protocol methods - they are generated here - internal virtual async Task GetMessagesPageAsync(string threadId, int? limit, string order, string after, string before, RequestOptions options) + internal virtual async Task GetMessagesAsync(string threadId, int? limit, string order, string after, string before, RequestOptions options) { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); @@ -100,7 +97,7 @@ internal virtual async Task GetMessagesPageAsync(string threadId, return ClientResult.FromResponse(await _pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); } - internal virtual ClientResult GetMessagesPage(string threadId, int? limit, string order, string after, string before, RequestOptions options) + internal virtual ClientResult GetMessages(string threadId, int? limit, string order, string after, string before, RequestOptions options) { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); diff --git a/src/To.Be.Generated/RunStepsPageEnumerator.cs b/src/To.Be.Generated/RunStepsPageEnumerator.cs index 3cb0b285d..87f98d93d 100644 --- a/src/To.Be.Generated/RunStepsPageEnumerator.cs +++ b/src/To.Be.Generated/RunStepsPageEnumerator.cs @@ -19,7 +19,6 @@ internal partial class RunStepsPageEnumerator : PageEnumerator private readonly int? _limit; private readonly string? _order; - // Note: this one is special private string? _after; private readonly string? _before; @@ -46,10 +45,10 @@ public RunStepsPageEnumerator( } public override async Task GetFirstAsync() - => await GetRunStepsPageAsync(_threadId, _runId, _limit, _order, _after, _before, _options).ConfigureAwait(false); + => await GetRunStepsAsync(_threadId, _runId, _limit, _order, _after, _before, _options).ConfigureAwait(false); public override ClientResult GetFirst() - => GetRunStepsPage(_threadId, _runId, _limit, _order, _after, _before, _options); + => GetRunSteps(_threadId, _runId, _limit, _order, _after, _before, _options); public override async Task GetNextAsync(ClientResult result) { @@ -58,7 +57,7 @@ public override async Task GetNextAsync(ClientResult result) using JsonDocument doc = JsonDocument.Parse(response.Content); _after = doc.RootElement.GetProperty("last_id"u8).GetString()!; - return await GetRunStepsPageAsync(_threadId, _runId, _limit, _order, _after, _before, _options).ConfigureAwait(false); + return await GetRunStepsAsync(_threadId, _runId, _limit, _order, _after, _before, _options).ConfigureAwait(false); } public override ClientResult GetNext(ClientResult result) @@ -68,7 +67,7 @@ public override ClientResult GetNext(ClientResult result) using JsonDocument doc = JsonDocument.Parse(response.Content); _after = doc.RootElement.GetProperty("last_id"u8).GetString()!; - return GetRunStepsPage(_threadId, _runId, _limit, _order, _after, _before, _options); + return GetRunSteps(_threadId, _runId, _limit, _order, _after, _before, _options); } public override bool HasNext(ClientResult result) @@ -81,7 +80,6 @@ public override bool HasNext(ClientResult result) return hasMore; } - // Note: this is the deserialization method that converts protocol to convenience public override PageResult GetPageFromResult(ClientResult result) { PipelineResponse response = result.GetRawResponse(); @@ -94,8 +92,7 @@ public override PageResult GetPageFromResult(ClientResult result) return PageResult.Create(list.Data, pageToken, nextPageToken, response); } - // Note: these are the protocol methods - they are generated here - internal async virtual Task GetRunStepsPageAsync(string threadId, string runId, int? limit, string? order, string? after, string? before, RequestOptions? options) + internal async virtual Task GetRunStepsAsync(string threadId, string runId, int? limit, string? order, string? after, string? before, RequestOptions? options) { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); Argument.AssertNotNullOrEmpty(runId, nameof(runId)); @@ -104,7 +101,7 @@ internal async virtual Task GetRunStepsPageAsync(string threadId, return ClientResult.FromResponse(await _pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); } - internal virtual ClientResult GetRunStepsPage(string threadId, string runId, int? limit, string? order, string? after, string? before, RequestOptions? options) + internal virtual ClientResult GetRunSteps(string threadId, string runId, int? limit, string? order, string? after, string? before, RequestOptions? options) { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); Argument.AssertNotNullOrEmpty(runId, nameof(runId)); diff --git a/src/To.Be.Generated/RunsPageEnumerator.cs b/src/To.Be.Generated/RunsPageEnumerator.cs index 0f1e6dc89..3f9ee113f 100644 --- a/src/To.Be.Generated/RunsPageEnumerator.cs +++ b/src/To.Be.Generated/RunsPageEnumerator.cs @@ -17,7 +17,6 @@ internal partial class RunsPageEnumerator : PageEnumerator private readonly int? _limit; private readonly string _order; - // Note: this one is special private string _after; private readonly string _before; @@ -41,10 +40,10 @@ public RunsPageEnumerator( } public override async Task GetFirstAsync() - => await GetRunsPageAsync(_threadId, _limit, _order, _after, _before, _options).ConfigureAwait(false); + => await GetRunsAsync(_threadId, _limit, _order, _after, _before, _options).ConfigureAwait(false); public override ClientResult GetFirst() - => GetRunsPage(_threadId, _limit, _order, _after, _before, _options); + => GetRuns(_threadId, _limit, _order, _after, _before, _options); public override async Task GetNextAsync(ClientResult result) { @@ -53,7 +52,7 @@ public override async Task GetNextAsync(ClientResult result) using JsonDocument doc = JsonDocument.Parse(response.Content); _after = doc.RootElement.GetProperty("last_id"u8).GetString()!; - return await GetRunsPageAsync(_threadId, _limit, _order, _after, _before, _options).ConfigureAwait(false); + return await GetRunsAsync(_threadId, _limit, _order, _after, _before, _options).ConfigureAwait(false); } public override ClientResult GetNext(ClientResult result) @@ -63,7 +62,7 @@ public override ClientResult GetNext(ClientResult result) using JsonDocument doc = JsonDocument.Parse(response.Content); _after = doc.RootElement.GetProperty("last_id"u8).GetString()!; - return GetRunsPage(_threadId, _limit, _order, _after, _before, _options); + return GetRuns(_threadId, _limit, _order, _after, _before, _options); } public override bool HasNext(ClientResult result) @@ -76,7 +75,6 @@ public override bool HasNext(ClientResult result) return hasMore; } - // Note: this is the deserialization method that converts protocol to convenience public override PageResult GetPageFromResult(ClientResult result) { PipelineResponse response = result.GetRawResponse(); @@ -89,8 +87,7 @@ public override PageResult GetPageFromResult(ClientResult result) return PageResult.Create(list.Data, pageToken, nextPageToken, response); } - // Note: these are the protocol methods - they are generated here - internal async virtual Task GetRunsPageAsync(string threadId, int? limit, string order, string after, string before, RequestOptions options) + internal async virtual Task GetRunsAsync(string threadId, int? limit, string order, string after, string before, RequestOptions options) { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); @@ -98,7 +95,7 @@ internal async virtual Task GetRunsPageAsync(string threadId, int? return ClientResult.FromResponse(await _pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); } - internal virtual ClientResult GetRunsPage(string threadId, int? limit, string order, string after, string before, RequestOptions options) + internal virtual ClientResult GetRuns(string threadId, int? limit, string order, string after, string before, RequestOptions options) { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); From f811de19328988a3cadd6097e422665e7b6b2057 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Mon, 15 Jul 2024 14:08:52 -0700 Subject: [PATCH 63/72] nits --- OpenAI.sln | 4 ++-- src/Custom/Assistants/AssistantClient.cs | 1 - src/Custom/VectorStores/VectorStoreClient.Protocol.cs | 3 +-- src/To.Be.Generated/AssistantsPageEnumerator.cs | 2 -- .../VectorStoreFileBatchesPageEnumerator.cs | 7 ++----- src/To.Be.Generated/VectorStoreFilesPageEnumerator.cs | 7 ++----- src/To.Be.Generated/VectorStoresPageEnumerator.cs | 8 ++------ 7 files changed, 9 insertions(+), 23 deletions(-) diff --git a/OpenAI.sln b/OpenAI.sln index 79cc37611..d6350d85f 100644 --- a/OpenAI.sln +++ b/OpenAI.sln @@ -6,7 +6,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenAI", "src\OpenAI.csproj EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenAI.Examples", "examples\OpenAI.Examples.csproj", "{1F1CD1D4-9932-4B73-99D8-C252A67D4B46}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenAI.Tests", "tests\OpenAI.Tests.csproj", "{6F156401-2544-41D7-B204-3148C51C1D09}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenAI.Tests", "tests\OpenAI.Tests.csproj", "{6F156401-2544-41D7-B204-3148C51C1D09}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -33,4 +33,4 @@ Global GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {A97F4B90-2591-4689-B1F8-5F21FE6D6CAE} EndGlobalSection -EndGlobal +EndGlobal \ No newline at end of file diff --git a/src/Custom/Assistants/AssistantClient.cs b/src/Custom/Assistants/AssistantClient.cs index b39888e0f..f0f0c44cc 100644 --- a/src/Custom/Assistants/AssistantClient.cs +++ b/src/Custom/Assistants/AssistantClient.cs @@ -1117,7 +1117,6 @@ public virtual PageCollection GetRunSteps( return PageCollectionHelpers.Create(enumerator); } - /// /// Gets a single run step from a run. /// diff --git a/src/Custom/VectorStores/VectorStoreClient.Protocol.cs b/src/Custom/VectorStores/VectorStoreClient.Protocol.cs index 69a82b365..617ef9a9f 100644 --- a/src/Custom/VectorStores/VectorStoreClient.Protocol.cs +++ b/src/Custom/VectorStores/VectorStoreClient.Protocol.cs @@ -1,5 +1,4 @@ -using OpenAI.Assistants; -using System; +using System; using System.ClientModel; using System.ClientModel.Primitives; using System.Collections.Generic; diff --git a/src/To.Be.Generated/AssistantsPageEnumerator.cs b/src/To.Be.Generated/AssistantsPageEnumerator.cs index 44ae3e9ea..15dbcc2dc 100644 --- a/src/To.Be.Generated/AssistantsPageEnumerator.cs +++ b/src/To.Be.Generated/AssistantsPageEnumerator.cs @@ -85,8 +85,6 @@ public override PageResult GetPageFromResult(ClientResult result) return PageResult.Create(list.Data, pageToken, nextPageToken, response); } - - // Note: these are the protocol methods - they are generated here internal virtual async Task GetAssistantsAsync(int? limit, string order, string after, string before, RequestOptions options) { using PipelineMessage message = CreateGetAssistantsRequest(limit, order, after, before, options); diff --git a/src/To.Be.Generated/VectorStoreFileBatchesPageEnumerator.cs b/src/To.Be.Generated/VectorStoreFileBatchesPageEnumerator.cs index a0b20f710..cb1a78576 100644 --- a/src/To.Be.Generated/VectorStoreFileBatchesPageEnumerator.cs +++ b/src/To.Be.Generated/VectorStoreFileBatchesPageEnumerator.cs @@ -18,13 +18,12 @@ internal partial class VectorStoreFileBatchesPageEnumerator : PageEnumerator GetPageFromResult(ClientResult result) { PipelineResponse response = result.GetRawResponse(); @@ -95,7 +93,6 @@ public override PageResult GetPageFromResult(ClientR return PageResult.Create(list.Data, pageToken, nextPageToken, response); } - // Note: these are the protocol methods - they are generated here internal virtual async Task GetFileAssociationsAsync(string vectorStoreId, string batchId, int? limit, string? order, string? after, string? before, string? filter, RequestOptions options) { Argument.AssertNotNullOrEmpty(vectorStoreId, nameof(vectorStoreId)); diff --git a/src/To.Be.Generated/VectorStoreFilesPageEnumerator.cs b/src/To.Be.Generated/VectorStoreFilesPageEnumerator.cs index d4825a0e9..d78384e31 100644 --- a/src/To.Be.Generated/VectorStoreFilesPageEnumerator.cs +++ b/src/To.Be.Generated/VectorStoreFilesPageEnumerator.cs @@ -17,13 +17,12 @@ internal partial class VectorStoreFilesPageEnumerator : PageEnumerator GetPageFromResult(ClientResult result) { PipelineResponse response = result.GetRawResponse(); @@ -92,7 +90,6 @@ public override PageResult GetPageFromResult(ClientR return PageResult.Create(list.Data, pageToken, nextPageToken, response); } - // Note: these are the protocol methods - they are generated here internal virtual async Task GetFileAssociationsAsync(string vectorStoreId, int? limit, string? order, string? after, string? before, string? filter, RequestOptions options) { Argument.AssertNotNullOrEmpty(vectorStoreId, nameof(vectorStoreId)); diff --git a/src/To.Be.Generated/VectorStoresPageEnumerator.cs b/src/To.Be.Generated/VectorStoresPageEnumerator.cs index 94ac83e5d..4a2aac725 100644 --- a/src/To.Be.Generated/VectorStoresPageEnumerator.cs +++ b/src/To.Be.Generated/VectorStoresPageEnumerator.cs @@ -15,13 +15,11 @@ internal partial class VectorStoresPageEnumerator : PageEnumerator private readonly int? _limit; private readonly string _order; - - // Note: this one is special - private string _after; - private readonly string _before; private readonly RequestOptions _options; + private string _after; + public VectorStoresPageEnumerator( ClientPipeline pipeline, Uri endpoint, @@ -74,7 +72,6 @@ public override bool HasNext(ClientResult result) return hasMore; } - // Note: this is the deserialization method that converts protocol to convenience public override PageResult GetPageFromResult(ClientResult result) { PipelineResponse response = result.GetRawResponse(); @@ -87,7 +84,6 @@ public override PageResult GetPageFromResult(ClientResult result) return PageResult.Create(list.Data, pageToken, nextPageToken, response); } - // Note: these are the protocol methods - they are generated here internal virtual async Task GetVectorStoresAsync(int? limit, string order, string after, string before, RequestOptions options) { using PipelineMessage message = CreateGetVectorStoresRequest(limit, order, after, before, options); From e7e3de77a76b5d221efbfc8efc7e3147c304a610 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Mon, 15 Jul 2024 15:28:10 -0700 Subject: [PATCH 64/72] add refdocs for paginated endpoint service methods --- .../Assistants/AssistantClient.Convenience.cs | 62 +++++++++----- .../Assistants/AssistantClient.Protocol.cs | 32 ++++---- src/Custom/Assistants/AssistantClient.cs | 82 +++++++++++++------ .../VectorStoreClient.Convenience.cs | 48 +++++------ .../VectorStoreClient.Protocol.cs | 24 +++--- src/Custom/VectorStores/VectorStoreClient.cs | 71 ++++++++-------- 6 files changed, 184 insertions(+), 135 deletions(-) diff --git a/src/Custom/Assistants/AssistantClient.Convenience.cs b/src/Custom/Assistants/AssistantClient.Convenience.cs index 67a382471..5eb15133d 100644 --- a/src/Custom/Assistants/AssistantClient.Convenience.cs +++ b/src/Custom/Assistants/AssistantClient.Convenience.cs @@ -125,11 +125,14 @@ public virtual ClientResult CreateMessage( => CreateMessage(thread?.Id, role, content, options); /// - /// Returns a collection of instances from an existing . + /// Gets a page collection holding instances from an existing . /// /// The thread to list messages from. - /// Options describing the collection to return. - /// + /// Options describing the collection to return. + /// holds pages of values. To obtain a collection of values, call + /// . To obtain the current + /// page of values, call . + /// A collection of pages of . public virtual AsyncPageCollection GetMessagesAsync( AssistantThread thread, MessageCollectionOptions options = default) @@ -140,11 +143,14 @@ public virtual AsyncPageCollection GetMessagesAsync( } /// - /// Returns a collection of instances from an existing . + /// Gets a page collection holding instances from an existing . /// /// The thread to list messages from. - /// Options describing the collection to return. - /// + /// Options describing the collection to return. + /// holds pages of values. To obtain a collection of values, call + /// . To obtain the current + /// page of values, call . + /// A collection of pages of . public virtual PageCollection GetMessages( AssistantThread thread, MessageCollectionOptions options = default) @@ -303,11 +309,14 @@ public virtual CollectionResult CreateThreadAndRunStreaming( => CreateThreadAndRunStreaming(assistant?.Id, threadOptions, runOptions); /// - /// Returns a collection of instances associated with an existing . + /// Gets a page collection holding instances associated with an existing . /// /// The thread that runs in the list should be associated with. - /// Options describing the collection to return. - /// + /// Options describing the collection to return. + /// holds pages of values. To obtain a collection of values, call + /// . To obtain the current + /// page of values, call . + /// A collection of pages of . public virtual AsyncPageCollection GetRunsAsync( AssistantThread thread, RunCollectionOptions options = default) @@ -318,11 +327,14 @@ public virtual AsyncPageCollection GetRunsAsync( } /// - /// Returns a collection of instances associated with an existing . + /// Gets a page collection holding instances associated with an existing . /// /// The thread that runs in the list should be associated with. - /// Options describing the collection to return. - /// + /// Options describing the collection to return. + /// holds pages of values. To obtain a collection of values, call + /// . To obtain the current + /// page of values, call . + /// A collection of pages of . public virtual PageCollection GetRuns( AssistantThread thread, RunCollectionOptions options = default) @@ -415,32 +427,38 @@ public virtual ClientResult CancelRun(ThreadRun run) => CancelRun(run?.ThreadId, run?.Id); /// - /// Gets a collection of instances associated with a . + /// Gets a page collection holding instances associated with a . /// /// The run to list run steps from. - /// Options describing the collection to return. - /// - public virtual PageCollection GetRunSteps( + /// Options describing the collection to return. + /// holds pages of values. To obtain a collection of values, call + /// . To obtain the current + /// page of values, call . + /// A collection of pages of . + public virtual AsyncPageCollection GetRunStepsAsync( ThreadRun run, RunStepCollectionOptions options = default) { Argument.AssertNotNull(run, nameof(run)); - return GetRunSteps(run.ThreadId, run.Id, options); + return GetRunStepsAsync(run.ThreadId, run.Id, options); } /// - /// Gets a collection of instances associated with a . + /// Gets a page collection holding instances associated with a . /// /// The run to list run steps from. - /// Options describing the collection to return. - /// - public virtual AsyncPageCollection GetRunStepsAsync( + /// Options describing the collection to return. + /// holds pages of values. To obtain a collection of values, call + /// . To obtain the current + /// page of values, call . + /// A collection of pages of . + public virtual PageCollection GetRunSteps( ThreadRun run, RunStepCollectionOptions options = default) { Argument.AssertNotNull(run, nameof(run)); - return GetRunStepsAsync(run.ThreadId, run.Id, options); + return GetRunSteps(run.ThreadId, run.Id, options); } } diff --git a/src/Custom/Assistants/AssistantClient.Protocol.cs b/src/Custom/Assistants/AssistantClient.Protocol.cs index aabe8bdbf..7e6344b3c 100644 --- a/src/Custom/Assistants/AssistantClient.Protocol.cs +++ b/src/Custom/Assistants/AssistantClient.Protocol.cs @@ -41,7 +41,7 @@ public virtual ClientResult CreateAssistant(BinaryContent content, RequestOption } /// - /// [Protocol Method] Returns a list of assistants. + /// [Protocol Method] Returns a paginated collection of assistants. /// /// /// A limit on the number of objects to be returned. Limit can range between 1 and 100, and the @@ -63,7 +63,7 @@ public virtual ClientResult CreateAssistant(BinaryContent content, RequestOption /// /// The request options, which can override default behaviors of the client pipeline on a per-call basis. /// Service returned a non-success status code. - /// The response returned from the service. + /// A collection of service responses, each holding a page of values. public virtual IAsyncEnumerable GetAssistantsAsync(int? limit, string order, string after, string before, RequestOptions options) { AssistantsPageEnumerator enumerator = new AssistantsPageEnumerator(_pipeline, _endpoint, limit, order, after, before, options); @@ -71,7 +71,7 @@ public virtual IAsyncEnumerable GetAssistantsAsync(int? limit, str } /// - /// [Protocol Method] Returns a list of assistants. + /// [Protocol Method] Returns a paginated collection of assistants. /// /// /// A limit on the number of objects to be returned. Limit can range between 1 and 100, and the @@ -93,7 +93,7 @@ public virtual IAsyncEnumerable GetAssistantsAsync(int? limit, str /// /// The request options, which can override default behaviors of the client pipeline on a per-call basis. /// Service returned a non-success status code. - /// The response returned from the service. + /// A collection of service responses, each holding a page of values. public virtual IEnumerable GetAssistants(int? limit, string order, string after, string before, RequestOptions options) { AssistantsPageEnumerator enumerator = new AssistantsPageEnumerator(_pipeline, _endpoint, limit, order, after, before, options); @@ -215,7 +215,7 @@ public virtual ClientResult CreateMessage(string threadId, BinaryContent content => _messageSubClient.CreateMessage(threadId, content, options); /// - /// [Protocol Method] Returns a list of messages for a given thread. + /// [Protocol Method] Returns a paginated collection of messages for a given thread. /// /// The ID of the [thread](/docs/api-reference/threads) the messages belong to. /// @@ -240,7 +240,7 @@ public virtual ClientResult CreateMessage(string threadId, BinaryContent content /// is null. /// is an empty string, and was expected to be non-empty. /// Service returned a non-success status code. - /// TODO + /// A collection of service responses, each holding a page of values. public virtual IAsyncEnumerable GetMessagesAsync(string threadId, int? limit, string order, string after, string before, RequestOptions options) { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); @@ -250,7 +250,7 @@ public virtual IAsyncEnumerable GetMessagesAsync(string threadId, } /// - /// [Protocol Method] Returns a list of messages for a given thread. + /// [Protocol Method] Returns a paginated collection of messages for a given thread. /// /// The ID of the [thread](/docs/api-reference/threads) the messages belong to. /// @@ -275,7 +275,7 @@ public virtual IAsyncEnumerable GetMessagesAsync(string threadId, /// is null. /// is an empty string, and was expected to be non-empty. /// Service returned a non-success status code. - /// TODO + /// A collection of service responses, each holding a page of values. public virtual IEnumerable GetMessages(string threadId, int? limit, string order, string after, string before, RequestOptions options) { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); @@ -323,7 +323,7 @@ public virtual ClientResult CreateRun(string threadId, BinaryContent content, Re => _runSubClient.CreateRun(threadId, content, options); /// - /// [Protocol Method] Returns a list of runs belonging to a thread. + /// [Protocol Method] Returns a paginated collection of runs belonging to a thread. /// /// The ID of the thread the run belongs to. /// @@ -348,7 +348,7 @@ public virtual ClientResult CreateRun(string threadId, BinaryContent content, Re /// is null. /// is an empty string, and was expected to be non-empty. /// Service returned a non-success status code. - /// TODO + /// A collection of service responses, each holding a page of values. public virtual IAsyncEnumerable GetRunsAsync(string threadId, int? limit, string order, string after, string before, RequestOptions options) { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); @@ -358,7 +358,7 @@ public virtual IAsyncEnumerable GetRunsAsync(string threadId, int? } /// - /// [Protocol Method] Returns a list of runs belonging to a thread. + /// [Protocol Method] Returns a paginated collection of runs belonging to a thread. /// /// The ID of the thread the run belongs to. /// @@ -383,7 +383,7 @@ public virtual IAsyncEnumerable GetRunsAsync(string threadId, int? /// is null. /// is an empty string, and was expected to be non-empty. /// Service returned a non-success status code. - /// TODO + /// A collection of service responses, each holding a page of values. public virtual IEnumerable GetRuns(string threadId, int? limit, string order, string after, string before, RequestOptions options) { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); @@ -425,7 +425,7 @@ public virtual ClientResult SubmitToolOutputsToRun(string threadId, string runId => _runSubClient.SubmitToolOutputsToRun(threadId, runId, content, options); /// - /// [Protocol Method] Returns a list of run steps belonging to a run. + /// [Protocol Method] Returns a paginated collection of run steps belonging to a run. /// /// The ID of the thread the run and run steps belong to. /// The ID of the run the run steps belong to. @@ -451,7 +451,7 @@ public virtual ClientResult SubmitToolOutputsToRun(string threadId, string runId /// or is null. /// or is an empty string, and was expected to be non-empty. /// Service returned a non-success status code. - /// TODO + /// A collection of service responses, each holding a page of values. public virtual IAsyncEnumerable GetRunStepsAsync(string threadId, string runId, int? limit, string order, string after, string before, RequestOptions options) { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); @@ -462,7 +462,7 @@ public virtual IAsyncEnumerable GetRunStepsAsync(string threadId, } /// - /// [Protocol Method] Returns a list of run steps belonging to a run. + /// [Protocol Method] Returns a paginated collection of run steps belonging to a run. /// /// The ID of the thread the run and run steps belong to. /// The ID of the run the run steps belong to. @@ -488,7 +488,7 @@ public virtual IAsyncEnumerable GetRunStepsAsync(string threadId, /// or is null. /// or is an empty string, and was expected to be non-empty. /// Service returned a non-success status code. - /// TODO + /// A collection of service responses, each holding a page of values. public virtual IEnumerable GetRunSteps(string threadId, string runId, int? limit, string order, string after, string before, RequestOptions options) { Argument.AssertNotNullOrEmpty(threadId, nameof(threadId)); diff --git a/src/Custom/Assistants/AssistantClient.cs b/src/Custom/Assistants/AssistantClient.cs index f0f0c44cc..5b97d8c4e 100644 --- a/src/Custom/Assistants/AssistantClient.cs +++ b/src/Custom/Assistants/AssistantClient.cs @@ -102,11 +102,14 @@ public virtual ClientResult CreateAssistant(string model, AssistantCr } /// - /// Returns a collection of instances. + /// Gets a page collection holding instances. /// - /// Options describing the collection to return. + /// Options describing the collection to return. /// A token that can be used to cancel this method call. - /// + /// holds pages of values. To obtain a collection of values, call + /// . To obtain the current + /// page of values, call . + /// A collection of pages of . public virtual AsyncPageCollection GetAssistantsAsync( AssistantCollectionOptions options = default, CancellationToken cancellationToken = default) @@ -122,11 +125,14 @@ public virtual AsyncPageCollection GetAssistantsAsync( } /// - /// Rehydrates a collection of instances a page token's serialized bytes. + /// Rehydrates a page collection holding instances from a page token's serialized bytes. /// /// Serialized page token indicating the first page of the collection to rehydrate. /// A token that can be used to cancel this method call. - /// + /// holds pages of values. To obtain a collection of values, call + /// . To obtain the current + /// page of values, call . + /// A collection of pages of . public virtual AsyncPageCollection GetAssistantsAsync( ContinuationToken firstPageToken, CancellationToken cancellationToken = default) @@ -145,11 +151,14 @@ public virtual AsyncPageCollection GetAssistantsAsync( } /// - /// Returns a collection of instances. + /// Gets a page collection holding instances. /// - /// Options describing the collection to return. + /// Options describing the collection to return. /// A token that can be used to cancel this method call. - /// + /// holds pages of values. To obtain a collection of values, call + /// . To obtain the current + /// page of values, call . + /// A collection of pages of . public virtual PageCollection GetAssistants( AssistantCollectionOptions options = default, CancellationToken cancellationToken = default) @@ -165,11 +174,14 @@ public virtual PageCollection GetAssistants( } /// - /// Rehydrates a collection of instances a page token's serialized bytes. + /// Rehydrates a page collection holding instances from a page token's serialized bytes. /// /// Serialized page token indicating the first page of the collection to rehydrate. /// A token that can be used to cancel this method call. - /// + /// holds pages of values. To obtain a collection of values, call + /// . To obtain the current + /// page of values, call . + /// A collection of pages of . public virtual PageCollection GetAssistants( ContinuationToken firstPageToken, CancellationToken cancellationToken = default) @@ -391,12 +403,15 @@ public virtual ClientResult CreateMessage( } /// - /// Returns a collection of instances from an existing . + /// Gets a page collection of instances from an existing . /// /// The ID of the thread to list messages from. - /// Options describing the collection to return. + /// Options describing the collection to return. /// A token that can be used to cancel this method call. - /// + /// holds pages of values. To obtain a collection of values, call + /// . To obtain the current + /// page of values, call . + /// A collection of pages of . public virtual AsyncPageCollection GetMessagesAsync( string threadId, MessageCollectionOptions options = default, @@ -434,12 +449,15 @@ public virtual AsyncPageCollection GetMessagesAsync( } /// - /// Returns a collection of instances from an existing . + /// Gets a page collection holding instances from an existing . /// /// The ID of the thread to list messages from. - /// Options describing the collection to return. + /// Options describing the collection to return. /// A token that can be used to cancel this method call. - /// + /// holds pages of values. To obtain a collection of values, call + /// . To obtain the current + /// page of values, call . + /// A collection of pages of . public virtual PageCollection GetMessages( string threadId, MessageCollectionOptions options = default, @@ -769,12 +787,15 @@ public virtual CollectionResult CreateThreadAndRunStreaming( } /// - /// Returns a collection of instances associated with an existing . + /// Gets a page collection holding instances associated with an existing . /// /// The ID of the thread that runs in the list should be associated with. - /// Options describing the collection to return. + /// Options describing the collection to return. /// A token that can be used to cancel this method call. - /// + /// holds pages of values. To obtain a collection of values, call + /// . To obtain the current + /// page of values, call . + /// A collection of pages of . public virtual AsyncPageCollection GetRunsAsync( string threadId, RunCollectionOptions options = default, @@ -812,12 +833,15 @@ public virtual AsyncPageCollection GetRunsAsync( } /// - /// Returns a collection of instances associated with an existing . + /// Gets a page collection holding instances associated with an existing . /// /// The ID of the thread that runs in the list should be associated with. - /// Options describing the collection to return. + /// Options describing the collection to return. /// A token that can be used to cancel this method call. - /// + /// holds pages of values. To obtain a collection of values, call + /// . To obtain the current + /// page of values, call . + /// A collection of pages of . public virtual PageCollection GetRuns( string threadId, RunCollectionOptions options = default, @@ -1022,13 +1046,16 @@ public virtual ClientResult CancelRun(string threadId, string runId, } /// - /// Gets a collection of instances associated with a . + /// Gets a page collection holding instances associated with a . /// /// The ID of the thread associated with the run. /// The ID of the run to list run steps from. /// /// A token that can be used to cancel this method call. - /// + /// holds pages of values. To obtain a collection of values, call + /// . To obtain the current + /// page of values, call . + /// A collection of pages of . public virtual AsyncPageCollection GetRunStepsAsync( string threadId, string runId, @@ -1070,13 +1097,16 @@ public virtual AsyncPageCollection GetRunStepsAsync( } /// - /// Gets a collection of instances associated with a . + /// Gets a page collection holding instances associated with a . /// /// The ID of the thread associated with the run. /// The ID of the run to list run steps from. /// /// A token that can be used to cancel this method call. - /// + /// holds pages of values. To obtain a collection of values, call + /// . To obtain the current + /// page of values, call . + /// A collection of pages of . public virtual PageCollection GetRunSteps( string threadId, string runId, diff --git a/src/Custom/VectorStores/VectorStoreClient.Convenience.cs b/src/Custom/VectorStores/VectorStoreClient.Convenience.cs index 5cccf6129..5330978b4 100644 --- a/src/Custom/VectorStores/VectorStoreClient.Convenience.cs +++ b/src/Custom/VectorStores/VectorStoreClient.Convenience.cs @@ -81,34 +81,34 @@ public virtual ClientResult AddFileToVectorStore(Vec => AddFileToVectorStore(vectorStore?.Id, file?.Id); /// - /// Gets the collection of instances representing file inclusions in the + /// Gets a page collection holding instances that represent file inclusions in the /// specified vector store. /// /// /// The vector store to enumerate the file associations of. /// - /// Options describing the collection to return. - /// - /// A collection of instances that can be asynchronously enumerated via - /// await foreach. - /// + /// Options describing the collection to return. + /// holds pages of values. To obtain a collection of values, call + /// . To obtain the current + /// page of values, call . + /// A collection of pages of . public virtual AsyncPageCollection GetFileAssociationsAsync( VectorStore vectorStore, VectorStoreFileAssociationCollectionOptions options = default) => GetFileAssociationsAsync(vectorStore?.Id, options); /// - /// Gets the collection of instances representing file inclusions in the + /// Gets a page collection holding instances that represent file inclusions in the /// specified vector store. /// /// /// The ID vector store to enumerate the file associations of. /// - /// Options describing the collection to return. - /// - /// A collection of instances that can be synchronously enumerated via - /// foreach. - /// + /// Options describing the collection to return. + /// holds pages of values. To obtain a collection of values, call + /// . To obtain the current + /// page of values, call . + /// A collection of pages of . public virtual PageCollection GetFileAssociations( VectorStore vectorStore, VectorStoreFileAssociationCollectionOptions options = default) @@ -215,30 +215,30 @@ public virtual ClientResult CancelBatchFileJob(VectorSt => CancelBatchFileJob(batchJob?.VectorStoreId, batchJob?.BatchId); /// - /// Gets the collection of file associations associated with a vector store batch file job, representing the files + /// Gets a page collection holding file associations associated with a vector store batch file job, representing the files /// that were scheduled for ingestion into the vector store. /// /// The vector store batch file job to retrieve file associations from. - /// Options describing the collection to return. - /// - /// A collection of instances that can be asynchronously enumerated via - /// await foreach. - /// + /// Options describing the collection to return. + /// holds pages of values. To obtain a collection of values, call + /// . To obtain the current + /// page of values, call . + /// A collection of pages of . public virtual AsyncPageCollection GetFileAssociationsAsync( VectorStoreBatchFileJob batchJob, VectorStoreFileAssociationCollectionOptions options = default) => GetFileAssociationsAsync(batchJob?.VectorStoreId, batchJob?.BatchId, options); /// - /// Gets the collection of file associations associated with a vector store batch file job, representing the files + /// Gets a page collection holding file associations associated with a vector store batch file job, representing the files /// that were scheduled for ingestion into the vector store. /// /// The vector store batch file job to retrieve file associations from. - /// Options describing the collection to return. - /// - /// A collection of instances that can be synchronously enumerated via - /// foreach. - /// + /// Options describing the collection to return. + /// holds pages of values. To obtain a collection of values, call + /// . To obtain the current + /// page of values, call . + /// A collection of pages of . public virtual PageCollection GetFileAssociations( VectorStoreBatchFileJob batchJob, VectorStoreFileAssociationCollectionOptions options = default) diff --git a/src/Custom/VectorStores/VectorStoreClient.Protocol.cs b/src/Custom/VectorStores/VectorStoreClient.Protocol.cs index 617ef9a9f..c3c9dad7e 100644 --- a/src/Custom/VectorStores/VectorStoreClient.Protocol.cs +++ b/src/Custom/VectorStores/VectorStoreClient.Protocol.cs @@ -26,7 +26,7 @@ namespace OpenAI.VectorStores; public partial class VectorStoreClient { /// - /// [Protocol Method] Returns a list of vector-stores. + /// [Protocol Method] Returns a paginated collection of vector-stores. /// /// /// A limit on the number of objects to be returned. Limit can range between 1 and 100, and the @@ -48,7 +48,7 @@ public partial class VectorStoreClient /// /// The request options, which can override default behaviors of the client pipeline on a per-call basis. /// Service returned a non-success status code. - /// The response returned from the service. + /// A collection of service responses, each holding a page of values. [EditorBrowsable(EditorBrowsableState.Never)] public virtual IAsyncEnumerable GetVectorStoresAsync(int? limit, string order, string after, string before, RequestOptions options) { @@ -57,7 +57,7 @@ public virtual IAsyncEnumerable GetVectorStoresAsync(int? limit, s } /// - /// [Protocol Method] Returns a list of vector-stores. + /// [Protocol Method] Returns a paginated collection of vector-stores. /// /// /// A limit on the number of objects to be returned. Limit can range between 1 and 100, and the @@ -79,7 +79,7 @@ public virtual IAsyncEnumerable GetVectorStoresAsync(int? limit, s /// /// The request options, which can override default behaviors of the client pipeline on a per-call basis. /// Service returned a non-success status code. - /// The response returned from the service. + /// A collection of service responses, each holding a page of values. [EditorBrowsable(EditorBrowsableState.Never)] public virtual IEnumerable GetVectorStores(int? limit, string order, string after, string before, RequestOptions options) { @@ -229,7 +229,7 @@ public virtual ClientResult DeleteVectorStore(string vectorStoreId, RequestOptio } /// - /// [Protocol Method] Returns a list of vector store files. + /// [Protocol Method] Returns a paginated collection of vector store files. /// /// The ID of the vector store that the files belong to. /// @@ -255,7 +255,7 @@ public virtual ClientResult DeleteVectorStore(string vectorStoreId, RequestOptio /// is null. /// is an empty string, and was expected to be non-empty. /// Service returned a non-success status code. - /// The response returned from the service. + /// A collection of service responses, each holding a page of values. [EditorBrowsable(EditorBrowsableState.Never)] public virtual IAsyncEnumerable GetFileAssociationsAsync(string vectorStoreId, int? limit, string order, string after, string before, string filter, RequestOptions options) { @@ -266,7 +266,7 @@ public virtual IAsyncEnumerable GetFileAssociationsAsync(string ve } /// - /// [Protocol Method] Returns a list of vector store files. + /// [Protocol Method] Returns a paginated collection of vector store files. /// /// The ID of the vector store that the files belong to. /// @@ -292,7 +292,7 @@ public virtual IAsyncEnumerable GetFileAssociationsAsync(string ve /// is null. /// is an empty string, and was expected to be non-empty. /// Service returned a non-success status code. - /// The response returned from the service. + /// A collection of service responses, each holding a page of values. [EditorBrowsable(EditorBrowsableState.Never)] public virtual IEnumerable GetFileAssociations(string vectorStoreId, int? limit, string order, string after, string before, string filter, RequestOptions options) { @@ -543,7 +543,7 @@ public virtual ClientResult CancelBatchFileJob(string vectorStoreId, string batc } /// - /// [Protocol Method] Returns a list of vector store files in a batch. + /// [Protocol Method] Returns a paginated collection of vector store files in a batch. /// /// The ID of the vector store that the file batch belongs to. /// The ID of the file batch that the files belong to. @@ -570,7 +570,7 @@ public virtual ClientResult CancelBatchFileJob(string vectorStoreId, string batc /// or is null. /// or is an empty string, and was expected to be non-empty. /// Service returned a non-success status code. - /// The response returned from the service. + /// A collection of service responses, each holding a page of values. [EditorBrowsable(EditorBrowsableState.Never)] public virtual IAsyncEnumerable GetFileAssociationsAsync(string vectorStoreId, string batchId, int? limit, string order, string after, string before, string filter, RequestOptions options) { @@ -582,7 +582,7 @@ public virtual IAsyncEnumerable GetFileAssociationsAsync(string ve } /// - /// [Protocol Method] Returns a list of vector store files in a batch. + /// [Protocol Method] Returns a paginated collection of vector store files in a batch. /// /// The ID of the vector store that the file batch belongs to. /// The ID of the file batch that the files belong to. @@ -609,7 +609,7 @@ public virtual IAsyncEnumerable GetFileAssociationsAsync(string ve /// or is null. /// or is an empty string, and was expected to be non-empty. /// Service returned a non-success status code. - /// The response returned from the service. + /// A collection of service responses, each holding a page of values. [EditorBrowsable(EditorBrowsableState.Never)] public virtual IEnumerable GetFileAssociations(string vectorStoreId, string batchId, int? limit, string order, string after, string before, string filter, RequestOptions options) { diff --git a/src/Custom/VectorStores/VectorStoreClient.cs b/src/Custom/VectorStores/VectorStoreClient.cs index c8c3c4308..f5e4eb9ca 100644 --- a/src/Custom/VectorStores/VectorStoreClient.cs +++ b/src/Custom/VectorStores/VectorStoreClient.cs @@ -134,14 +134,14 @@ public virtual ClientResult DeleteVectorStore(string vectorStoreId, Cancel } /// - /// Gets the collection of instances for the configured organization. + /// Gets a page collection holding instances for the configured organization. /// - /// Options describing the collection to return. + /// Options describing the collection to return. /// A token that can be used to cancel this method call. - /// - /// A collection of instances that can be asynchronously enumerated via - /// await foreach. - /// + /// holds pages of values. To obtain a collection of values, call + /// . To obtain the current + /// page of values, call . + /// A collection of pages of . public virtual AsyncPageCollection GetVectorStoresAsync( VectorStoreCollectionOptions options = default, CancellationToken cancellationToken = default) @@ -174,13 +174,14 @@ public virtual AsyncPageCollection GetVectorStoresAsync( } /// - /// Gets the collection of instances for the configured organization. + /// Gets a page collection holding instances for the configured organization. /// - /// Options describing the collection to return. + /// Options describing the collection to return. /// A token that can be used to cancel this method call. - /// - /// A collection of instances that can be synchronously enumerated via foreach. - /// + /// holds pages of values. To obtain a collection of values, call + /// . To obtain the current + /// page of values, call . + /// A collection of pages of . public virtual PageCollection GetVectorStores( VectorStoreCollectionOptions options = default, CancellationToken cancellationToken = default) @@ -249,18 +250,18 @@ public virtual ClientResult AddFileToVectorStore(str } /// - /// Gets the collection of instances representing file inclusions in the + /// Gets a page collection holding instances that represent file inclusions in the /// specified vector store. /// /// /// The ID of the vector store to enumerate the file associations of. /// - /// Options describing the collection to return. + /// Options describing the collection to return. /// A token that can be used to cancel this method call. - /// - /// A collection of instances that can be asynchronously enumerated via - /// await foreach. - /// + /// holds pages of values. To obtain a collection of values, call + /// . To obtain the current + /// page of values, call . + /// A collection of pages of . public virtual AsyncPageCollection GetFileAssociationsAsync( string vectorStoreId, VectorStoreFileAssociationCollectionOptions options = default, @@ -300,18 +301,18 @@ public virtual AsyncPageCollection GetFileAssociatio } /// - /// Gets the collection of instances representing file inclusions in the + /// Gets a page collection holding instances that represent file inclusions in the /// specified vector store. /// /// /// The ID of the vector store to enumerate the file associations of. /// - /// Options describing the collection to return. + /// Options describing the collection to return. /// A token that can be used to cancel this method call. - /// - /// A collection of instances that can be synchronously enumerated via - /// foreach. - /// + /// holds pages of values. To obtain a collection of values, call + /// . To obtain the current + /// page of values, call . + /// A collection of pages of . public virtual PageCollection GetFileAssociations( string vectorStoreId, VectorStoreFileAssociationCollectionOptions options = default, @@ -551,7 +552,7 @@ public virtual ClientResult CancelBatchFileJob(string v } /// - /// Gets the collection of file associations associated with a vector store batch file job, representing the files + /// Gets a page collection of file associations associated with a vector store batch file job, representing the files /// that were scheduled for ingestion into the vector store. /// /// @@ -560,12 +561,12 @@ public virtual ClientResult CancelBatchFileJob(string v /// /// The ID of the batch file job that was previously scheduled. /// - /// Options describing the collection to return. + /// Options describing the collection to return. /// A token that can be used to cancel this method call. - /// - /// A collection of instances that can be asynchronously enumerated via - /// await foreach. - /// + /// holds pages of values. To obtain a collection of values, call + /// . To obtain the current + /// page of values, call . + /// A collection of pages of . public virtual AsyncPageCollection GetFileAssociationsAsync( string vectorStoreId, string batchJobId, @@ -626,7 +627,7 @@ public virtual AsyncPageCollection GetFileAssociatio } /// - /// Gets the collection of file associations associated with a vector store batch file job, representing the files + /// Gets a page collection of file associations associated with a vector store batch file job, representing the files /// that were scheduled for ingestion into the vector store. /// /// @@ -635,12 +636,12 @@ public virtual AsyncPageCollection GetFileAssociatio /// /// The ID of the batch file job that was previously scheduled. /// - /// Options describing the collection to return. + /// Options describing the collection to return. /// A token that can be used to cancel this method call. - /// - /// A collection of instances that can be synchronously enumerated via - /// foreach. - /// + /// holds pages of values. To obtain a collection of values, call + /// . To obtain the current + /// page of values, call . + /// A collection of pages of . public virtual PageCollection GetFileAssociations( string vectorStoreId, string batchJobId, From 88319b8bdc92420e84ef61ffff1fcbe91e62355f Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Mon, 15 Jul 2024 15:42:47 -0700 Subject: [PATCH 65/72] add refdocs for options types --- src/Custom/Assistants/AssistantCollectionOptions.cs | 12 +++++++----- src/Custom/Assistants/MessageCollectionOptions.cs | 12 +++++++----- src/Custom/Assistants/RunCollectionOptions.cs | 12 +++++++----- src/Custom/Assistants/RunStepCollectionOptions.cs | 12 +++++++----- .../VectorStores/VectorStoreCollectionOptions.cs | 12 +++++++----- .../VectorStoreFileAssociationCollectionOptions.cs | 13 +++++++------ 6 files changed, 42 insertions(+), 31 deletions(-) diff --git a/src/Custom/Assistants/AssistantCollectionOptions.cs b/src/Custom/Assistants/AssistantCollectionOptions.cs index d78696b94..731401eff 100644 --- a/src/Custom/Assistants/AssistantCollectionOptions.cs +++ b/src/Custom/Assistants/AssistantCollectionOptions.cs @@ -1,11 +1,13 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace OpenAI.Assistants; +namespace OpenAI.Assistants; +/// +/// Represents addition options available when requesting a collection of instances. +/// public class AssistantCollectionOptions { + /// + /// Creates a new instance of . + /// public AssistantCollectionOptions() { } /// diff --git a/src/Custom/Assistants/MessageCollectionOptions.cs b/src/Custom/Assistants/MessageCollectionOptions.cs index e4aa159fa..213d58419 100644 --- a/src/Custom/Assistants/MessageCollectionOptions.cs +++ b/src/Custom/Assistants/MessageCollectionOptions.cs @@ -1,11 +1,13 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace OpenAI.Assistants; +namespace OpenAI.Assistants; +/// +/// Represents addition options available when requesting a collection of instances. +/// public class MessageCollectionOptions { + /// + /// Creates a new instance of . + /// public MessageCollectionOptions() { } /// diff --git a/src/Custom/Assistants/RunCollectionOptions.cs b/src/Custom/Assistants/RunCollectionOptions.cs index 53d503ba3..d99f1a4b6 100644 --- a/src/Custom/Assistants/RunCollectionOptions.cs +++ b/src/Custom/Assistants/RunCollectionOptions.cs @@ -1,11 +1,13 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace OpenAI.Assistants; +namespace OpenAI.Assistants; +/// +/// Represents addition options available when requesting a collection of instances. +/// public class RunCollectionOptions { + /// + /// Creates a new instance of . + /// public RunCollectionOptions() { } /// diff --git a/src/Custom/Assistants/RunStepCollectionOptions.cs b/src/Custom/Assistants/RunStepCollectionOptions.cs index aeb3d9813..19ad62937 100644 --- a/src/Custom/Assistants/RunStepCollectionOptions.cs +++ b/src/Custom/Assistants/RunStepCollectionOptions.cs @@ -1,11 +1,13 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace OpenAI.Assistants; +namespace OpenAI.Assistants; +/// +/// Represents addition options available when requesting a collection of instances. +/// public class RunStepCollectionOptions { + /// + /// Creates a new instance of . + /// public RunStepCollectionOptions() { } /// diff --git a/src/Custom/VectorStores/VectorStoreCollectionOptions.cs b/src/Custom/VectorStores/VectorStoreCollectionOptions.cs index 2361aebde..de0834bd3 100644 --- a/src/Custom/VectorStores/VectorStoreCollectionOptions.cs +++ b/src/Custom/VectorStores/VectorStoreCollectionOptions.cs @@ -1,11 +1,13 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace OpenAI.VectorStores; +namespace OpenAI.VectorStores; +/// +/// Represents addition options available when requesting a collection of instances. +/// public class VectorStoreCollectionOptions { + /// + /// Creates a new instance of . + /// public VectorStoreCollectionOptions() { } /// diff --git a/src/Custom/VectorStores/VectorStoreFileAssociationCollectionOptions.cs b/src/Custom/VectorStores/VectorStoreFileAssociationCollectionOptions.cs index 0b8bb697d..cf1788a72 100644 --- a/src/Custom/VectorStores/VectorStoreFileAssociationCollectionOptions.cs +++ b/src/Custom/VectorStores/VectorStoreFileAssociationCollectionOptions.cs @@ -1,12 +1,13 @@ -using OpenAI.Files; -using System; -using System.Collections.Generic; -using System.Text; - -namespace OpenAI.VectorStores; +namespace OpenAI.VectorStores; +/// +/// Represents addition options available when requesting a collection of instances. +/// public class VectorStoreFileAssociationCollectionOptions { + /// + /// Creates a new instance of . + /// public VectorStoreFileAssociationCollectionOptions() { } /// From 7118d132a174b935033d8abae6f3eb553bce5945 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Mon, 15 Jul 2024 15:56:03 -0700 Subject: [PATCH 66/72] add refdocs for collection rehydration overloads --- src/Custom/Assistants/AssistantClient.cs | 62 ++++++++++++++++-- src/Custom/VectorStores/VectorStoreClient.cs | 67 ++++++++++++++++++++ 2 files changed, 125 insertions(+), 4 deletions(-) diff --git a/src/Custom/Assistants/AssistantClient.cs b/src/Custom/Assistants/AssistantClient.cs index 5b97d8c4e..9e47b4f0d 100644 --- a/src/Custom/Assistants/AssistantClient.cs +++ b/src/Custom/Assistants/AssistantClient.cs @@ -125,9 +125,9 @@ public virtual AsyncPageCollection GetAssistantsAsync( } /// - /// Rehydrates a page collection holding instances from a page token's serialized bytes. + /// Rehydrates a page collection holding instances from a page token. /// - /// Serialized page token indicating the first page of the collection to rehydrate. + /// Page token corresponding to the first page of the collection to rehydrate. /// A token that can be used to cancel this method call. /// holds pages of values. To obtain a collection of values, call /// . To obtain the current @@ -174,9 +174,9 @@ public virtual PageCollection GetAssistants( } /// - /// Rehydrates a page collection holding instances from a page token's serialized bytes. + /// Rehydrates a page collection holding instances from a page token. /// - /// Serialized page token indicating the first page of the collection to rehydrate. + /// Page token corresponding to the first page of the collection to rehydrate. /// A token that can be used to cancel this method call. /// holds pages of values. To obtain a collection of values, call /// . To obtain the current @@ -430,6 +430,15 @@ public virtual AsyncPageCollection GetMessagesAsync( return PageCollectionHelpers.CreateAsync(enumerator); } + /// + /// Rehydrates a page collection of instances from a page token. + /// + /// Page token corresponding to the first page of the collection to rehydrate. + /// A token that can be used to cancel this method call. + /// holds pages of values. To obtain a collection of values, call + /// . To obtain the current + /// page of values, call . + /// A collection of pages of . public virtual AsyncPageCollection GetMessagesAsync( ContinuationToken firstPageToken, CancellationToken cancellationToken = default) @@ -476,6 +485,15 @@ public virtual PageCollection GetMessages( return PageCollectionHelpers.Create(enumerator); } + /// + /// Rehydrates a page collection holding instances from a page token. + /// + /// Page token corresponding to the first page of the collection to rehydrate. + /// A token that can be used to cancel this method call. + /// holds pages of values. To obtain a collection of values, call + /// . To obtain the current + /// page of values, call . + /// A collection of pages of . public virtual PageCollection GetMessages( ContinuationToken firstPageToken, CancellationToken cancellationToken = default) @@ -814,6 +832,15 @@ public virtual AsyncPageCollection GetRunsAsync( return PageCollectionHelpers.CreateAsync(enumerator); } + /// + /// Rehydrates a page collection holding instances from a page token. + /// + /// Page token corresponding to the first page of the collection to rehydrate. + /// A token that can be used to cancel this method call. + /// holds pages of values. To obtain a collection of values, call + /// . To obtain the current + /// page of values, call . + /// A collection of pages of . public virtual AsyncPageCollection GetRunsAsync( ContinuationToken firstPageToken, CancellationToken cancellationToken = default) @@ -860,6 +887,15 @@ public virtual PageCollection GetRuns( return PageCollectionHelpers.Create(enumerator); } + /// + /// Rehydrates a page collection holding instances from a page token. + /// + /// Page token corresponding to the first page of the collection to rehydrate. + /// A token that can be used to cancel this method call. + /// holds pages of values. To obtain a collection of values, call + /// . To obtain the current + /// page of values, call . + /// A collection of pages of . public virtual PageCollection GetRuns( ContinuationToken firstPageToken, CancellationToken cancellationToken = default) @@ -1077,6 +1113,15 @@ public virtual AsyncPageCollection GetRunStepsAsync( return PageCollectionHelpers.CreateAsync(enumerator); } + /// + /// Rehydrates a page collection holding instances from a page token. + /// + /// Page token corresponding to the first page of the collection to rehydrate. + /// A token that can be used to cancel this method call. + /// holds pages of values. To obtain a collection of values, call + /// . To obtain the current + /// page of values, call . + /// A collection of pages of . public virtual AsyncPageCollection GetRunStepsAsync( ContinuationToken firstPageToken, CancellationToken cancellationToken = default) @@ -1128,6 +1173,15 @@ public virtual PageCollection GetRunSteps( return PageCollectionHelpers.Create(enumerator); } + /// + /// Rehydrates a page collection holding instances from a page token. + /// + /// Page token corresponding to the first page of the collection to rehydrate. + /// A token that can be used to cancel this method call. + /// holds pages of values. To obtain a collection of values, call + /// . To obtain the current + /// page of values, call . + /// A collection of pages of . public virtual PageCollection GetRunSteps( ContinuationToken firstPageToken, CancellationToken cancellationToken = default) diff --git a/src/Custom/VectorStores/VectorStoreClient.cs b/src/Custom/VectorStores/VectorStoreClient.cs index f5e4eb9ca..0f7f46af6 100644 --- a/src/Custom/VectorStores/VectorStoreClient.cs +++ b/src/Custom/VectorStores/VectorStoreClient.cs @@ -156,6 +156,15 @@ public virtual AsyncPageCollection GetVectorStoresAsync( return PageCollectionHelpers.CreateAsync(enumerator); } + /// + /// Rehydrates a page collection holding instances from a page token. + /// + /// Page token corresponding to the first page of the collection to rehydrate. + /// A token that can be used to cancel this method call. + /// holds pages of values. To obtain a collection of values, call + /// . To obtain the current + /// page of values, call . + /// A collection of pages of . public virtual AsyncPageCollection GetVectorStoresAsync( ContinuationToken firstPageToken, CancellationToken cancellationToken = default) @@ -196,6 +205,15 @@ public virtual PageCollection GetVectorStores( return PageCollectionHelpers.Create(enumerator); } + /// + /// Rehydrates a page collection holding instances from a page token. + /// + /// Page token corresponding to the first page of the collection to rehydrate. + /// A token that can be used to cancel this method call. + /// holds pages of values. To obtain a collection of values, call + /// . To obtain the current + /// page of values, call . + /// A collection of pages of . public virtual PageCollection GetVectorStores( ContinuationToken firstPageToken, CancellationToken cancellationToken = default) @@ -281,6 +299,15 @@ public virtual AsyncPageCollection GetFileAssociatio return PageCollectionHelpers.CreateAsync(enumerator); } + /// + /// Rehydrates a page collection holding instances from a page token. + /// + /// Page token corresponding to the first page of the collection to rehydrate. + /// A token that can be used to cancel this method call. + /// holds pages of values. To obtain a collection of values, call + /// . To obtain the current + /// page of values, call . + /// A collection of pages of . public virtual AsyncPageCollection GetFileAssociationsAsync( ContinuationToken firstPageToken, CancellationToken cancellationToken = default) @@ -332,6 +359,15 @@ public virtual PageCollection GetFileAssociations( return PageCollectionHelpers.Create(enumerator); } + /// + /// Rehydrates a page collection holding instances from a page token. + /// + /// Page token corresponding to the first page of the collection to rehydrate. + /// A token that can be used to cancel this method call. + /// holds pages of values. To obtain a collection of values, call + /// . To obtain the current + /// page of values, call . + /// A collection of pages of . public virtual PageCollection GetFileAssociations( ContinuationToken firstPageToken, CancellationToken cancellationToken = default) @@ -589,6 +625,21 @@ public virtual AsyncPageCollection GetFileAssociatio return PageCollectionHelpers.CreateAsync(enumerator); } + /// + /// Rehydrates a page collection of file associations from a page token. + /// + /// + /// The ID of the vector store into which the file batch was scheduled for ingestion. + /// + /// + /// The ID of the batch file job that was previously scheduled. + /// + /// Page token corresponding to the first page of the collection to rehydrate. + /// A token that can be used to cancel this method call. + /// holds pages of values. To obtain a collection of values, call + /// . To obtain the current + /// page of values, call . + /// A collection of pages of . public virtual AsyncPageCollection GetFileAssociationsAsync( string vectorStoreId, string batchJobId, @@ -664,6 +715,22 @@ public virtual PageCollection GetFileAssociations( return PageCollectionHelpers.Create(enumerator); } + /// + /// Rehydrates a page collection of file associations from a page token. + /// that were scheduled for ingestion into the vector store. + /// + /// + /// The ID of the vector store into which the file batch was scheduled for ingestion. + /// + /// + /// The ID of the batch file job that was previously scheduled. + /// + /// Page token corresponding to the first page of the collection to rehydrate. + /// A token that can be used to cancel this method call. + /// holds pages of values. To obtain a collection of values, call + /// . To obtain the current + /// page of values, call . + /// A collection of pages of . public virtual PageCollection GetFileAssociations( string vectorStoreId, string batchJobId, From e2758013fa09a925521e534bea3b34b9268da40a Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Mon, 15 Jul 2024 16:33:53 -0700 Subject: [PATCH 67/72] add test and fix bugs --- src/To.Be.Generated/RunStepsPageEnumerator.cs | 5 +- src/To.Be.Generated/RunStepsPageToken.cs | 4 +- .../VectorStoreFileBatchesPageToken.cs | 2 +- tests/Assistants/AssistantTests.cs | 93 +++++++++++++++++-- 4 files changed, 92 insertions(+), 12 deletions(-) diff --git a/src/To.Be.Generated/RunStepsPageEnumerator.cs b/src/To.Be.Generated/RunStepsPageEnumerator.cs index 87f98d93d..77660e761 100644 --- a/src/To.Be.Generated/RunStepsPageEnumerator.cs +++ b/src/To.Be.Generated/RunStepsPageEnumerator.cs @@ -18,12 +18,11 @@ internal partial class RunStepsPageEnumerator : PageEnumerator private readonly int? _limit; private readonly string? _order; - - private string? _after; - private readonly string? _before; private readonly RequestOptions _options; + private string? _after; + public RunStepsPageEnumerator( ClientPipeline pipeline, Uri endpoint, diff --git a/src/To.Be.Generated/RunStepsPageToken.cs b/src/To.Be.Generated/RunStepsPageToken.cs index 229f6f16d..65f522815 100644 --- a/src/To.Be.Generated/RunStepsPageToken.cs +++ b/src/To.Be.Generated/RunStepsPageToken.cs @@ -40,7 +40,7 @@ public override BinaryData ToBytes() writer.WriteStartObject(); writer.WriteString("threadId", ThreadId); - writer.WriteString("runId", ThreadId); + writer.WriteString("runId", RunId); if (Limit.HasValue) { @@ -128,7 +128,7 @@ public static RunStepsPageToken FromToken(ContinuationToken pageToken) case "runId": reader.Read(); Debug.Assert(reader.TokenType == JsonTokenType.String); - threadId = reader.GetString()!; + runId = reader.GetString()!; break; case "limit": reader.Read(); diff --git a/src/To.Be.Generated/VectorStoreFileBatchesPageToken.cs b/src/To.Be.Generated/VectorStoreFileBatchesPageToken.cs index 798f0c760..8db14097f 100644 --- a/src/To.Be.Generated/VectorStoreFileBatchesPageToken.cs +++ b/src/To.Be.Generated/VectorStoreFileBatchesPageToken.cs @@ -137,7 +137,7 @@ public static VectorStoreFileBatchesPageToken FromToken(ContinuationToken pageTo case "batchId": reader.Read(); Debug.Assert(reader.TokenType == JsonTokenType.String); - vectorStoreId = reader.GetString()!; + batchId = reader.GetString()!; break; case "limit": reader.Read(); diff --git a/tests/Assistants/AssistantTests.cs b/tests/Assistants/AssistantTests.cs index 6b645301e..148508d94 100644 --- a/tests/Assistants/AssistantTests.cs +++ b/tests/Assistants/AssistantTests.cs @@ -631,7 +631,7 @@ This file describes the favorite foods of several people. } [Test] - public async Task CanEnumerateAssistants() + public async Task Pagination_CanEnumerateAssistants() { AssistantClient client = GetTestClient(); @@ -672,7 +672,7 @@ public async Task CanEnumerateAssistants() } [Test] - public async Task CanPageThroughAssistantCollection() + public async Task Pagination_CanPageThroughAssistantCollection() { AssistantClient client = GetTestClient(); @@ -725,7 +725,7 @@ public async Task CanPageThroughAssistantCollection() } [Test] - public async Task CanRehydratePageCollectionFromBytes() + public async Task Pagination_CanRehydrateAssistantPageCollectionFromBytes() { AssistantClient client = GetTestClient(); @@ -748,7 +748,6 @@ public async Task CanRehydratePageCollectionFromBytes() }); // Simulate rehydration of the collection - // TODO: too complicated? BinaryData rehydrationBytes = (await pages.GetCurrentPageAsync().ConfigureAwait(false)).PageToken.ToBytes(); ContinuationToken rehydrationToken = ContinuationToken.FromBytes(rehydrationBytes); @@ -784,7 +783,7 @@ public async Task CanRehydratePageCollectionFromBytes() } [Test] - public async Task CanRehydratePageCollectionFromPageToken() + public async Task Pagination_CanRehydrateAssistantPageCollectionFromPageToken() { AssistantClient client = GetTestClient(); @@ -840,7 +839,7 @@ public async Task CanRehydratePageCollectionFromPageToken() } [Test] - public async Task CanCastPageCollectionToConvenienceFromProtocol() + public async Task Pagination_CanCastAssistantPageCollectionToConvenienceFromProtocol() { AssistantClient client = GetTestClient(); @@ -890,6 +889,88 @@ public async Task CanCastPageCollectionToConvenienceFromProtocol() Assert.That(pageCount, Is.GreaterThanOrEqualTo(5)); } + [Test] + public void Pagination_CanRehydrateRunStepPageCollectionFromBytes() + { + AssistantClient client = GetTestClient(); + Assistant assistant = client.CreateAssistant("gpt-4o", new AssistantCreationOptions() + { + Tools = { new CodeInterpreterToolDefinition() }, + Instructions = "You help the user with mathematical descriptions and visualizations.", + }); + Validate(assistant); + + FileClient fileClient = new(); + OpenAIFileInfo equationFile = fileClient.UploadFile( + BinaryData.FromString(""" + x,y + 2,5 + 7,14, + 8,22 + """).ToStream(), + "text/csv", + FileUploadPurpose.Assistants); + Validate(equationFile); + + AssistantThread thread = client.CreateThread(new ThreadCreationOptions() + { + InitialMessages = + { + "Describe the contents of any available tool resource file." + + " Graph a linear regression and provide the coefficient of correlation." + + " Explain any code executed to evaluate.", + }, + ToolResources = new() + { + CodeInterpreter = new() + { + FileIds = { equationFile.Id }, + } + } + }); + Validate(thread); + + ThreadRun run = client.CreateRun(thread, assistant); + Validate(run); + + while (!run.Status.IsTerminal) + { + Thread.Sleep(1000); + run = client.GetRun(run); + } + Assert.That(run.Status, Is.EqualTo(RunStatus.Completed)); + Assert.That(run.Usage?.TotalTokens, Is.GreaterThan(0)); + + PageCollection pages = client.GetRunSteps(run); + IEnumerator> pageEnumerator = ((IEnumerable>)pages).GetEnumerator(); + + // Simulate rehydration of the collection + BinaryData rehydrationBytes = pages.GetCurrentPage().PageToken.ToBytes(); + ContinuationToken rehydrationToken = ContinuationToken.FromBytes(rehydrationBytes); + + PageCollection rehydratedPages = client.GetRunSteps(rehydrationToken); + IEnumerator> rehydratedPageEnumerator = ((IEnumerable>)rehydratedPages).GetEnumerator(); + + int pageCount = 0; + + while (pageEnumerator.MoveNext() && rehydratedPageEnumerator.MoveNext()) + { + PageResult page = pageEnumerator.Current; + PageResult rehydratedPage = rehydratedPageEnumerator.Current; + + Assert.AreEqual(page.Values.Count, rehydratedPage.Values.Count); + + for (int i = 0; i < page.Values.Count; i++) + { + Assert.AreEqual(page.Values[0].Id, rehydratedPage.Values[0].Id); + } + + pageCount++; + } + + Assert.That(pageCount, Is.GreaterThanOrEqualTo(1)); + } + [Test] public async Task MessagesWithRoles() { From 8d66ade6baafb0680a48c97df4fdd4361b7b1931 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Mon, 15 Jul 2024 16:44:21 -0700 Subject: [PATCH 68/72] add a test for vector store --- tests/Assistants/VectorStoreTests.cs | 63 ++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/tests/Assistants/VectorStoreTests.cs b/tests/Assistants/VectorStoreTests.cs index efd8c59b8..8b959e08c 100644 --- a/tests/Assistants/VectorStoreTests.cs +++ b/tests/Assistants/VectorStoreTests.cs @@ -201,6 +201,69 @@ public void CanAssociateFiles() Assert.That(count, Is.EqualTo(2)); } + [Test] + public void Pagination_CanRehydrateFileAssociationCollection() + { + VectorStoreClient client = GetTestClient(); + VectorStore vectorStore = client.CreateVectorStore(); + Validate(vectorStore); + + IReadOnlyList files = GetNewTestFiles(3); + + foreach (OpenAIFileInfo file in files) + { + VectorStoreFileAssociation association = client.AddFileToVectorStore(vectorStore, file); + Validate(association); + Assert.Multiple(() => + { + Assert.That(association.FileId, Is.EqualTo(file.Id)); + Assert.That(association.VectorStoreId, Is.EqualTo(vectorStore.Id)); + Assert.That(association.LastError, Is.Null); + Assert.That(association.CreatedAt, Is.GreaterThan(s_2024)); + Assert.That(association.Status, Is.EqualTo(VectorStoreFileAssociationStatus.InProgress)); + }); + } + + bool removed = client.RemoveFileFromStore(vectorStore, files[0]); + Assert.True(removed); + _associationsToRemove.RemoveAt(0); + + // Errata: removals aren't immediately reflected when requesting the list + Thread.Sleep(1000); + + PageCollection pages = client.GetFileAssociations(vectorStore); + IEnumerator> pageEnumerator = ((IEnumerable>)pages).GetEnumerator(); + + // Simulate rehydration of the collection + BinaryData rehydrationBytes = pages.GetCurrentPage().PageToken.ToBytes(); + ContinuationToken rehydrationToken = ContinuationToken.FromBytes(rehydrationBytes); + + PageCollection rehydratedPages = client.GetFileAssociations(rehydrationToken); + IEnumerator> rehydratedPageEnumerator = ((IEnumerable>)rehydratedPages).GetEnumerator(); + + int pageCount = 0; + + while (pageEnumerator.MoveNext() && rehydratedPageEnumerator.MoveNext()) + { + PageResult page = pageEnumerator.Current; + PageResult rehydratedPage = rehydratedPageEnumerator.Current; + + Assert.AreEqual(page.Values.Count, rehydratedPage.Values.Count); + + for (int i = 0; i < page.Values.Count; i++) + { + Assert.AreEqual(page.Values[0].FileId, rehydratedPage.Values[0].FileId); + Assert.AreEqual(page.Values[0].VectorStoreId, rehydratedPage.Values[0].VectorStoreId); + Assert.AreEqual(page.Values[0].CreatedAt, rehydratedPage.Values[0].CreatedAt); + Assert.AreEqual(page.Values[0].Size, rehydratedPage.Values[0].Size); + } + + pageCount++; + } + + Assert.That(pageCount, Is.GreaterThanOrEqualTo(1)); + } + [Test] public void CanUseBatchIngestion() { From 8468c204a21b43b079de5b15c182c2b528bb7309 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Mon, 22 Jul 2024 15:03:21 -0700 Subject: [PATCH 69/72] move files To.Be.Generated -> Custom --- .../Assistants}/AssistantsPageEnumerator.cs | 0 src/{To.Be.Generated => Custom/Assistants}/AssistantsPageToken.cs | 0 .../Assistants}/MessagesPageEnumerator.cs | 0 src/{To.Be.Generated => Custom/Assistants}/MessagesPageToken.cs | 0 .../Assistants}/RunStepsPageEnumerator.cs | 0 src/{To.Be.Generated => Custom/Assistants}/RunStepsPageToken.cs | 0 src/{To.Be.Generated => Custom/Assistants}/RunsPageEnumerator.cs | 0 src/{To.Be.Generated => Custom/Assistants}/RunsPageToken.cs | 0 .../VectorStores}/VectorStoreFileBatchesPageEnumerator.cs | 0 .../VectorStores}/VectorStoreFileBatchesPageToken.cs | 0 .../VectorStores}/VectorStoreFilesPageEnumerator.cs | 0 .../VectorStores}/VectorStoreFilesPageToken.cs | 0 .../VectorStores}/VectorStoresPageEnumerator.cs | 0 .../VectorStores}/VectorStoresPageToken.cs | 0 .../Internal => Utility}/PageCollectionHelpers.cs | 0 src/{To.Be.Generated/Internal => Utility}/PageEnumerator.cs | 0 src/{To.Be.Generated/Internal => Utility}/PageResultEnumerator.cs | 0 17 files changed, 0 insertions(+), 0 deletions(-) rename src/{To.Be.Generated => Custom/Assistants}/AssistantsPageEnumerator.cs (100%) rename src/{To.Be.Generated => Custom/Assistants}/AssistantsPageToken.cs (100%) rename src/{To.Be.Generated => Custom/Assistants}/MessagesPageEnumerator.cs (100%) rename src/{To.Be.Generated => Custom/Assistants}/MessagesPageToken.cs (100%) rename src/{To.Be.Generated => Custom/Assistants}/RunStepsPageEnumerator.cs (100%) rename src/{To.Be.Generated => Custom/Assistants}/RunStepsPageToken.cs (100%) rename src/{To.Be.Generated => Custom/Assistants}/RunsPageEnumerator.cs (100%) rename src/{To.Be.Generated => Custom/Assistants}/RunsPageToken.cs (100%) rename src/{To.Be.Generated => Custom/VectorStores}/VectorStoreFileBatchesPageEnumerator.cs (100%) rename src/{To.Be.Generated => Custom/VectorStores}/VectorStoreFileBatchesPageToken.cs (100%) rename src/{To.Be.Generated => Custom/VectorStores}/VectorStoreFilesPageEnumerator.cs (100%) rename src/{To.Be.Generated => Custom/VectorStores}/VectorStoreFilesPageToken.cs (100%) rename src/{To.Be.Generated => Custom/VectorStores}/VectorStoresPageEnumerator.cs (100%) rename src/{To.Be.Generated => Custom/VectorStores}/VectorStoresPageToken.cs (100%) rename src/{To.Be.Generated/Internal => Utility}/PageCollectionHelpers.cs (100%) rename src/{To.Be.Generated/Internal => Utility}/PageEnumerator.cs (100%) rename src/{To.Be.Generated/Internal => Utility}/PageResultEnumerator.cs (100%) diff --git a/src/To.Be.Generated/AssistantsPageEnumerator.cs b/src/Custom/Assistants/AssistantsPageEnumerator.cs similarity index 100% rename from src/To.Be.Generated/AssistantsPageEnumerator.cs rename to src/Custom/Assistants/AssistantsPageEnumerator.cs diff --git a/src/To.Be.Generated/AssistantsPageToken.cs b/src/Custom/Assistants/AssistantsPageToken.cs similarity index 100% rename from src/To.Be.Generated/AssistantsPageToken.cs rename to src/Custom/Assistants/AssistantsPageToken.cs diff --git a/src/To.Be.Generated/MessagesPageEnumerator.cs b/src/Custom/Assistants/MessagesPageEnumerator.cs similarity index 100% rename from src/To.Be.Generated/MessagesPageEnumerator.cs rename to src/Custom/Assistants/MessagesPageEnumerator.cs diff --git a/src/To.Be.Generated/MessagesPageToken.cs b/src/Custom/Assistants/MessagesPageToken.cs similarity index 100% rename from src/To.Be.Generated/MessagesPageToken.cs rename to src/Custom/Assistants/MessagesPageToken.cs diff --git a/src/To.Be.Generated/RunStepsPageEnumerator.cs b/src/Custom/Assistants/RunStepsPageEnumerator.cs similarity index 100% rename from src/To.Be.Generated/RunStepsPageEnumerator.cs rename to src/Custom/Assistants/RunStepsPageEnumerator.cs diff --git a/src/To.Be.Generated/RunStepsPageToken.cs b/src/Custom/Assistants/RunStepsPageToken.cs similarity index 100% rename from src/To.Be.Generated/RunStepsPageToken.cs rename to src/Custom/Assistants/RunStepsPageToken.cs diff --git a/src/To.Be.Generated/RunsPageEnumerator.cs b/src/Custom/Assistants/RunsPageEnumerator.cs similarity index 100% rename from src/To.Be.Generated/RunsPageEnumerator.cs rename to src/Custom/Assistants/RunsPageEnumerator.cs diff --git a/src/To.Be.Generated/RunsPageToken.cs b/src/Custom/Assistants/RunsPageToken.cs similarity index 100% rename from src/To.Be.Generated/RunsPageToken.cs rename to src/Custom/Assistants/RunsPageToken.cs diff --git a/src/To.Be.Generated/VectorStoreFileBatchesPageEnumerator.cs b/src/Custom/VectorStores/VectorStoreFileBatchesPageEnumerator.cs similarity index 100% rename from src/To.Be.Generated/VectorStoreFileBatchesPageEnumerator.cs rename to src/Custom/VectorStores/VectorStoreFileBatchesPageEnumerator.cs diff --git a/src/To.Be.Generated/VectorStoreFileBatchesPageToken.cs b/src/Custom/VectorStores/VectorStoreFileBatchesPageToken.cs similarity index 100% rename from src/To.Be.Generated/VectorStoreFileBatchesPageToken.cs rename to src/Custom/VectorStores/VectorStoreFileBatchesPageToken.cs diff --git a/src/To.Be.Generated/VectorStoreFilesPageEnumerator.cs b/src/Custom/VectorStores/VectorStoreFilesPageEnumerator.cs similarity index 100% rename from src/To.Be.Generated/VectorStoreFilesPageEnumerator.cs rename to src/Custom/VectorStores/VectorStoreFilesPageEnumerator.cs diff --git a/src/To.Be.Generated/VectorStoreFilesPageToken.cs b/src/Custom/VectorStores/VectorStoreFilesPageToken.cs similarity index 100% rename from src/To.Be.Generated/VectorStoreFilesPageToken.cs rename to src/Custom/VectorStores/VectorStoreFilesPageToken.cs diff --git a/src/To.Be.Generated/VectorStoresPageEnumerator.cs b/src/Custom/VectorStores/VectorStoresPageEnumerator.cs similarity index 100% rename from src/To.Be.Generated/VectorStoresPageEnumerator.cs rename to src/Custom/VectorStores/VectorStoresPageEnumerator.cs diff --git a/src/To.Be.Generated/VectorStoresPageToken.cs b/src/Custom/VectorStores/VectorStoresPageToken.cs similarity index 100% rename from src/To.Be.Generated/VectorStoresPageToken.cs rename to src/Custom/VectorStores/VectorStoresPageToken.cs diff --git a/src/To.Be.Generated/Internal/PageCollectionHelpers.cs b/src/Utility/PageCollectionHelpers.cs similarity index 100% rename from src/To.Be.Generated/Internal/PageCollectionHelpers.cs rename to src/Utility/PageCollectionHelpers.cs diff --git a/src/To.Be.Generated/Internal/PageEnumerator.cs b/src/Utility/PageEnumerator.cs similarity index 100% rename from src/To.Be.Generated/Internal/PageEnumerator.cs rename to src/Utility/PageEnumerator.cs diff --git a/src/To.Be.Generated/Internal/PageResultEnumerator.cs b/src/Utility/PageResultEnumerator.cs similarity index 100% rename from src/To.Be.Generated/Internal/PageResultEnumerator.cs rename to src/Utility/PageResultEnumerator.cs From 6a4e01d6ca99b219344d475fc27fb6310f9cfde0 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Mon, 22 Jul 2024 15:12:11 -0700 Subject: [PATCH 70/72] address PR FB for examples --- .../Assistants/Example03_ListAssistantsWithPagination.cs | 4 ++-- .../Example03_ListAssistantsWithPaginationAsync.cs | 4 ++-- examples/Assistants/Example04_AllTheTools.cs | 6 +++++- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/examples/Assistants/Example03_ListAssistantsWithPagination.cs b/examples/Assistants/Example03_ListAssistantsWithPagination.cs index e8640f1c5..83776d7a1 100644 --- a/examples/Assistants/Example03_ListAssistantsWithPagination.cs +++ b/examples/Assistants/Example03_ListAssistantsWithPagination.cs @@ -17,8 +17,8 @@ public void Example03_ListAssistantsWithPagination() int count = 0; - PageCollection assitantPages = client.GetAssistants(); - IEnumerable assistants = assitantPages.GetAllValues(); + PageCollection assistantPages = client.GetAssistants(); + IEnumerable assistants = assistantPages.GetAllValues(); foreach (Assistant assistant in assistants) { Console.WriteLine($"[{count,3}] {assistant.Id} {assistant.CreatedAt:s} {assistant.Name}"); diff --git a/examples/Assistants/Example03_ListAssistantsWithPaginationAsync.cs b/examples/Assistants/Example03_ListAssistantsWithPaginationAsync.cs index fa67a713f..1f4d8218e 100644 --- a/examples/Assistants/Example03_ListAssistantsWithPaginationAsync.cs +++ b/examples/Assistants/Example03_ListAssistantsWithPaginationAsync.cs @@ -18,8 +18,8 @@ public async Task Example03_ListAssistantsWithPaginationAsync() int count = 0; - AsyncPageCollection assitantPages = client.GetAssistantsAsync(); - IAsyncEnumerable assistants = assitantPages.GetAllValuesAsync(); + AsyncPageCollection assistantPages = client.GetAssistantsAsync(); + IAsyncEnumerable assistants = assistantPages.GetAllValuesAsync(); await foreach (Assistant assistant in assistants) { Console.WriteLine($"[{count,3}] {assistant.Id} {assistant.CreatedAt:s} {assistant.Name}"); diff --git a/examples/Assistants/Example04_AllTheTools.cs b/examples/Assistants/Example04_AllTheTools.cs index 94b801f95..3d55253d0 100644 --- a/examples/Assistants/Example04_AllTheTools.cs +++ b/examples/Assistants/Example04_AllTheTools.cs @@ -172,7 +172,11 @@ PageCollection messagePages #endregion #region List run steps for details about tool calls - PageCollection runSteps = client.GetRunSteps(run, new() { Order = ListOrder.OldestFirst }); + PageCollection runSteps = client.GetRunSteps( + run, new RunStepCollectionOptions() + { + Order = ListOrder.OldestFirst + }); foreach (RunStep step in runSteps.GetAllValues()) { Console.WriteLine($"Run step: {step.Status}"); From 0a2d6f5ff4b1cbde9a05e8feff42a7884c09f2aa Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Mon, 22 Jul 2024 16:03:37 -0700 Subject: [PATCH 71/72] remove unused helper methods --- src/Utility/PageCollectionHelpers.cs | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/Utility/PageCollectionHelpers.cs b/src/Utility/PageCollectionHelpers.cs index b5be39a6e..f7863ce21 100644 --- a/src/Utility/PageCollectionHelpers.cs +++ b/src/Utility/PageCollectionHelpers.cs @@ -15,22 +15,6 @@ public static PageCollection Create(PageEnumerator enumerator) public static AsyncPageCollection CreateAsync(PageEnumerator enumerator) => new AsyncEnumeratorPageCollection(enumerator); - public static IEnumerable Create(PageResultEnumerator enumerator) - { - while (enumerator.MoveNext()) - { - yield return enumerator.Current; - } - } - - public static async IAsyncEnumerable CreateAsync(PageResultEnumerator enumerator) - { - while (await enumerator.MoveNextAsync().ConfigureAwait(false)) - { - yield return enumerator.Current; - } - } - private class EnumeratorPageCollection : PageCollection { private readonly PageEnumerator _enumerator; From a09c1f3b233d55cd6dd0f32d774a275ea08820c6 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Mon, 22 Jul 2024 17:36:48 -0700 Subject: [PATCH 72/72] fix merge issue --- tests/Chat/ChatSmokeTests.cs | 6 +----- tests/Chat/ChatTests.cs | 10 +++++----- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/tests/Chat/ChatSmokeTests.cs b/tests/Chat/ChatSmokeTests.cs index f414e1cdc..100aaeef6 100644 --- a/tests/Chat/ChatSmokeTests.cs +++ b/tests/Chat/ChatSmokeTests.cs @@ -55,8 +55,7 @@ public async Task SmokeTest() { Transport = mockTransport }; - ResultCollection streamingResult = client.CompleteChatStreaming(messages); - Assert.That(streamingResult, Is.InstanceOf>()); + ChatClient client = new("model_name_replaced", new ApiKeyCredential("sk-not-a-real-key"), options); ChatCompletion completion = IsAsync ? await client.CompleteChatAsync(["Mock me!"]) @@ -74,8 +73,6 @@ public void CanCreateClients() Uri fakeUri = new("https://127.0.0.1"); ApiKeyCredential fakeCredential = new("sk-not-a-real-credential"); - AsyncResultCollection streamingResult = client.CompleteChatStreamingAsync(messages); - Assert.That(streamingResult, Is.InstanceOf>()); { OpenAIClient topLevelClient = new(fakeCredential); Assert.That(topLevelClient, Is.Not.Null); @@ -130,7 +127,6 @@ [new UserChatMessage("Uh oh, this isn't going to work with that key")])) [Test] [TestCase(true)] [TestCase(false)] - AsyncResultCollection chatCompletionUpdates = client.CompleteChatStreamingAsync(messages, options); public void SerializeChatToolChoiceAsString(bool fromRawJson) { ChatToolChoice choice; diff --git a/tests/Chat/ChatTests.cs b/tests/Chat/ChatTests.cs index 81e55452e..5527c2d3d 100644 --- a/tests/Chat/ChatTests.cs +++ b/tests/Chat/ChatTests.cs @@ -77,8 +77,8 @@ public void StreamingChat() TimeSpan? latestTokenReceiptTime = null; Stopwatch stopwatch = Stopwatch.StartNew(); - ResultCollection streamingResult = client.CompleteChatStreaming(messages); - Assert.That(streamingResult, Is.InstanceOf>()); + CollectionResult streamingResult = client.CompleteChatStreaming(messages); + Assert.That(streamingResult, Is.InstanceOf>()); int updateCount = 0; foreach (StreamingChatCompletionUpdate chatUpdate in streamingResult) @@ -109,8 +109,8 @@ public async Task StreamingChatAsync() TimeSpan? latestTokenReceiptTime = null; Stopwatch stopwatch = Stopwatch.StartNew(); - AsyncResultCollection streamingResult = client.CompleteChatStreamingAsync(messages); - Assert.That(streamingResult, Is.InstanceOf>()); + AsyncCollectionResult streamingResult = client.CompleteChatStreamingAsync(messages); + Assert.That(streamingResult, Is.InstanceOf>()); int updateCount = 0; ChatTokenUsage usage = null; @@ -277,7 +277,7 @@ public async Task TokenLogProbabilitiesStreaming(bool includeLogProbabilities) options = new(); } - AsyncResultCollection chatCompletionUpdates = client.CompleteChatStreamingAsync(messages, options); + AsyncCollectionResult chatCompletionUpdates = client.CompleteChatStreamingAsync(messages, options); Assert.That(chatCompletionUpdates, Is.Not.Null); await foreach (StreamingChatCompletionUpdate chatCompletionUpdate in chatCompletionUpdates)