openai/openai-dotnet

Public

mirrored from https://github.com/openai/openai-dotnetAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
OpenAI_2.2.0

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

src/Custom/Assistants/AssistantClient.cs

1273lines · modecode

1using System;
2using System.ClientModel;
3using System.ClientModel.Primitives;
4using System.Collections.Generic;
5using System.Diagnostics.CodeAnalysis;
6using System.Linq;
7using System.Runtime.CompilerServices;
8using System.Threading;
9using System.Threading.Tasks;
10
11namespace OpenAI.Assistants;
12
13/// <summary> The service client for OpenAI assistants operations. </summary>
14[Experimental("OPENAI001")]
15[CodeGenType("Assistants")]
16[CodeGenSuppress("AssistantClient", typeof(ClientPipeline), typeof(Uri))]
17[CodeGenSuppress("CreateAssistantAsync", typeof(AssistantCreationOptions), typeof(CancellationToken))]
18[CodeGenSuppress("CreateAssistant", typeof(AssistantCreationOptions), typeof(CancellationToken))]
19[CodeGenSuppress("GetAssistantAsync", typeof(string))]
20[CodeGenSuppress("GetAssistant", typeof(string))]
21[CodeGenSuppress("ModifyAssistantAsync", typeof(string), typeof(AssistantModificationOptions))]
22[CodeGenSuppress("ModifyAssistant", typeof(string), typeof(AssistantModificationOptions))]
23[CodeGenSuppress("DeleteAssistantAsync", typeof(string))]
24[CodeGenSuppress("DeleteAssistant", typeof(string))]
25[CodeGenSuppress("GetAssistantsAsync", typeof(int?), typeof(OpenAI.VectorStores.VectorStoreCollectionOrder?), typeof(string), typeof(string), typeof(CancellationToken))]
26[CodeGenSuppress("GetAssistants", typeof(int?), typeof(OpenAI.VectorStores.VectorStoreCollectionOrder?), typeof(string), typeof(string), typeof(CancellationToken))]
27public partial class AssistantClient
28{
29 private readonly InternalAssistantMessageClient _messageSubClient;
30 private readonly InternalAssistantRunClient _runSubClient;
31 private readonly InternalAssistantThreadClient _threadSubClient;
32
33 // CUSTOM: Added as a convenience.
34 /// <summary> Initializes a new instance of <see cref="AssistantClient"/>. </summary>
35 /// <param name="apiKey"> The API key to authenticate with the service. </param>
36 /// <exception cref="ArgumentNullException"> <paramref name="apiKey"/> is null. </exception>
37 public AssistantClient(string apiKey) : this(new ApiKeyCredential(apiKey), new OpenAIClientOptions())
38 {
39 }
40
41 // CUSTOM:
42 // - Used a custom pipeline.
43 // - Demoted the endpoint parameter to be a property in the options class.
44 /// <summary> Initializes a new instance of <see cref="AssistantClient"/>. </summary>
45 /// <param name="credential"> The API key to authenticate with the service. </param>
46 /// <exception cref="ArgumentNullException"> <paramref name="credential"/> is null. </exception>
47 public AssistantClient(ApiKeyCredential credential) : this(credential, new OpenAIClientOptions())
48 {
49 }
50
51 // CUSTOM:
52 // - Used a custom pipeline.
53 // - Demoted the endpoint parameter to be a property in the options class.
54 /// <summary> Initializes a new instance of <see cref="AssistantClient"/>. </summary>
55 /// <param name="credential"> The API key to authenticate with the service. </param>
56 /// <param name="options"> The options to configure the client. </param>
57 /// <exception cref="ArgumentNullException"> <paramref name="credential"/> is null. </exception>
58 public AssistantClient(ApiKeyCredential credential, OpenAIClientOptions options)
59 {
60 Argument.AssertNotNull(credential, nameof(credential));
61 options ??= new OpenAIClientOptions();
62
63 Pipeline = OpenAIClient.CreatePipeline(credential, options);
64 _endpoint = OpenAIClient.GetEndpoint(options);
65 _messageSubClient = new(Pipeline, options);
66 _runSubClient = new(Pipeline, options);
67 _threadSubClient = new(Pipeline, options);
68 }
69
70 // CUSTOM:
71 // - Used a custom pipeline.
72 // - Demoted the endpoint parameter to be a property in the options class.
73 // - Made protected.
74 /// <summary> Initializes a new instance of <see cref="AssistantClient"/>. </summary>
75 /// <param name="pipeline"> The HTTP pipeline to send and receive REST requests and responses. </param>
76 /// <param name="options"> The options to configure the client. </param>
77 /// <exception cref="ArgumentNullException"> <paramref name="pipeline"/> is null. </exception>
78 protected internal AssistantClient(ClientPipeline pipeline, OpenAIClientOptions options)
79 {
80 Argument.AssertNotNull(pipeline, nameof(pipeline));
81 options ??= new OpenAIClientOptions();
82
83 Pipeline = pipeline;
84 _endpoint = OpenAIClient.GetEndpoint(options);
85 _messageSubClient = new(Pipeline, options);
86 _runSubClient = new(Pipeline, options);
87 _threadSubClient = new(Pipeline, options);
88 }
89
90 /// <summary> Creates a new assistant. </summary>
91 /// <param name="model"> The default model that the assistant should use. </param>
92 /// <param name="options"> The additional <see cref="AssistantCreationOptions"/> to use. </param>
93 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
94 /// <exception cref="ArgumentException"> <paramref name="model"/> is null or empty. </exception>
95 public virtual async Task<ClientResult<Assistant>> CreateAssistantAsync(string model, AssistantCreationOptions options = null, CancellationToken cancellationToken = default)
96 {
97 Argument.AssertNotNullOrEmpty(model, nameof(model));
98 options ??= new();
99 options.Model = model;
100
101 ClientResult protocolResult = await CreateAssistantAsync(options?.ToBinaryContent(), cancellationToken.ToRequestOptions()).ConfigureAwait(false);
102 return ClientResult.FromValue(Assistant.FromClientResult(protocolResult), protocolResult.GetRawResponse());
103 }
104
105 /// <summary> Creates a new assistant. </summary>
106 /// <param name="model"> The default model that the assistant should use. </param>
107 /// <param name="options"> The additional <see cref="AssistantCreationOptions"/> to use. </param>
108 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
109 /// <exception cref="ArgumentException"> <paramref name="model"/> is null or empty. </exception>
110 public virtual ClientResult<Assistant> CreateAssistant(string model, AssistantCreationOptions options = null, CancellationToken cancellationToken = default)
111 {
112 Argument.AssertNotNullOrEmpty(model, nameof(model));
113 options ??= new();
114 options.Model = model;
115
116 ClientResult protocolResult = CreateAssistant(options?.ToBinaryContent(), cancellationToken.ToRequestOptions());
117 return ClientResult.FromValue(Assistant.FromClientResult(protocolResult), protocolResult.GetRawResponse());
118 }
119
120 /// <summary>
121 /// Gets a page collection holding <see cref="Assistant"/> instances.
122 /// </summary>
123 /// <param name="options"> Options describing the collection to return. </param>
124 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
125 /// <returns> A collection of <see cref="Assistant"/>. </returns>
126 public virtual AsyncCollectionResult<Assistant> GetAssistantsAsync(
127 AssistantCollectionOptions options = default,
128 CancellationToken cancellationToken = default)
129 {
130 AsyncCollectionResult result = GetAssistantsAsync(options?.PageSizeLimit, options?.Order?.ToString(), options?.AfterId, options?.BeforeId, cancellationToken.ToRequestOptions());
131
132 if (result is not AsyncCollectionResult<Assistant> assistantCollection)
133 {
134 throw new InvalidOperationException("Failed to cast protocol return type to expected collection type 'AsyncCollectionResult<Assistant>'.");
135 }
136
137 return assistantCollection;
138 }
139
140 /// <summary>
141 /// Rehydrates a page collection holding <see cref="Assistant"/> instances from a page token.
142 /// </summary>
143 /// <param name="firstPageToken"> Page token corresponding to the first page of the collection to rehydrate. </param>
144 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
145 /// <returns> A collection of <see cref="Assistant"/>. </returns>
146 public virtual AsyncCollectionResult<Assistant> GetAssistantsAsync(
147 ContinuationToken firstPageToken,
148 CancellationToken cancellationToken = default)
149 {
150 Argument.AssertNotNull(firstPageToken, nameof(firstPageToken));
151
152 AssistantCollectionPageToken pageToken = AssistantCollectionPageToken.FromToken(firstPageToken);
153 AsyncCollectionResult result = GetAssistantsAsync(pageToken?.Limit, pageToken?.Order, pageToken?.After, pageToken.Before, cancellationToken.ToRequestOptions());
154
155 if (result is not AsyncCollectionResult<Assistant> assistantCollection)
156 {
157 throw new InvalidOperationException("Failed to cast protocol return type to expected collection type 'AsyncCollectionResult<Assistant>'.");
158 }
159
160 return assistantCollection;
161 }
162
163 /// <summary>
164 /// Gets a page collection holding <see cref="Assistant"/> instances.
165 /// </summary>
166 /// <param name="options"> Options describing the collection to return. </param>
167 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
168 /// <returns> A collection of <see cref="Assistant"/>. </returns>
169 public virtual CollectionResult<Assistant> GetAssistants(
170 AssistantCollectionOptions options = default,
171 CancellationToken cancellationToken = default)
172 {
173 CollectionResult result = GetAssistants(options?.PageSizeLimit, options?.Order?.ToString(), options?.AfterId, options?.BeforeId, cancellationToken.ToRequestOptions());
174
175 if (result is not CollectionResult<Assistant> assistantCollection)
176 {
177 throw new InvalidOperationException("Failed to cast protocol return type to expected collection type 'CollectionResult<Assistant>'.");
178 }
179
180 return assistantCollection;
181 }
182
183 /// <summary>
184 /// Rehydrates a page collection holding <see cref="Assistant"/> instances from a page token.
185 /// </summary>
186 /// <param name="firstPageToken"> Page token corresponding to the first page of the collection to rehydrate. </param>
187 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
188 /// <returns> A collection of <see cref="Assistant"/>. </returns>
189 public virtual CollectionResult<Assistant> GetAssistants(
190 ContinuationToken firstPageToken,
191 CancellationToken cancellationToken = default)
192 {
193 Argument.AssertNotNull(firstPageToken, nameof(firstPageToken));
194
195 AssistantCollectionPageToken pageToken = AssistantCollectionPageToken.FromToken(firstPageToken);
196 CollectionResult result = GetAssistants(pageToken?.Limit, pageToken?.Order, pageToken?.After, pageToken.Before, cancellationToken.ToRequestOptions());
197
198 if (result is not CollectionResult<Assistant> assistantCollection)
199 {
200 throw new InvalidOperationException("Failed to cast protocol return type to expected collection type 'CollectionResult<Assistant>'.");
201 }
202
203 return assistantCollection;
204 }
205
206 /// <summary>
207 /// Gets an instance representing an existing <see cref="Assistant"/> based on its ID.
208 /// </summary>
209 /// <param name="assistantId"> The ID of the Assistant to retrieve. </param>
210 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
211 /// <returns>An <see cref="Assistant"/> instance representing the state of the Assistant with the provided ID.</returns>
212 public virtual async Task<ClientResult<Assistant>> GetAssistantAsync(string assistantId, CancellationToken cancellationToken = default)
213 {
214 Argument.AssertNotNullOrEmpty(assistantId, nameof(assistantId));
215
216 ClientResult protocolResult = await GetAssistantAsync(assistantId, cancellationToken.ToRequestOptions()).ConfigureAwait(false);
217 return ClientResult.FromValue(Assistant.FromClientResult(protocolResult), protocolResult.GetRawResponse());
218 }
219
220 /// <summary>
221 /// Gets an instance representing an existing <see cref="Assistant"/> based on its ID.
222 /// </summary>
223 /// <param name="assistantId"> The ID of the Assistant to retrieve. </param>
224 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
225 /// <returns>An <see cref="Assistant"/> instance representing the state of the Assistant with the provided ID.</returns>
226 public virtual ClientResult<Assistant> GetAssistant(string assistantId, CancellationToken cancellationToken = default)
227 {
228 Argument.AssertNotNullOrEmpty(assistantId, nameof(assistantId));
229
230 ClientResult protocolResult = GetAssistant(assistantId, cancellationToken.ToRequestOptions());
231 return ClientResult.FromValue(Assistant.FromClientResult(protocolResult), protocolResult.GetRawResponse());
232 }
233
234 /// <summary>
235 /// Modifies an existing <see cref="Assistant"/>.
236 /// </summary>
237 /// <param name="assistantId"> The ID of the Assistant to retrieve. </param>
238 /// <param name="options"> The new options to apply to the existing Assistant. </param>
239 /// <param name="cancellationToken"> A token that can be used to cancel this method call. </param>
240 /// <returns> An updated <see cref="Assistant"/> instance representing the state of the Assistant with the provided ID. </returns>
241 public virtual async Task<ClientResult<Assistant>> ModifyAssistantAsync(string assistantId, AssistantModificationOptions options, CancellationToken cancellationToken = default)
242 {
243 Argument.AssertNotNullOrEmpty(assistantId, nameof(assistantId));
244 Argument.AssertNotNull(options, nameof(options));
245
246 using BinaryContent content = options?.ToBinaryContent();
247 ClientResult protocolResult
248 = await ModifyAssistantAsync(assistantId, content, cancellationToken.ToRequestOptions()).ConfigureAwait(false);
249 return ClientResult.FromValue(Assistant.FromClientResult(protocolResult), protocolResult.GetRawResponse());
250 }
251
252 /// <summary>
253 /// Modifies an existing <see cref="Assistant"/>.
254 /// </summary>
255 /// <param name="assistantId"> The ID of the Assistant to retrieve. </param>
256 /// <param name="options"> The new options to apply to the existing Assistant. </param>
257 /// <param name="cancellationToken"> A token that can be used to cancel this method call. </param>
258 /// <returns> An updated <see cref="Assistant"/> instance representing the state of the Assistant with the provided ID. </returns>
259 public virtual ClientResult<Assistant> ModifyAssistant(string assistantId, AssistantModificationOptions options, CancellationToken cancellationToken = default)
260 {
261 Argument.AssertNotNullOrEmpty(assistantId, nameof(assistantId));
262 Argument.AssertNotNull(options, nameof(options));
263
264 using BinaryContent content = options?.ToBinaryContent();
265 ClientResult protocolResult = ModifyAssistant(assistantId, content, null);
266 return ClientResult.FromValue(Assistant.FromClientResult(protocolResult), protocolResult.GetRawResponse());
267 }
268
269 /// <summary>
270 /// Deletes an existing <see cref="Assistant"/>.
271 /// </summary>
272 /// <param name="assistantId"> The ID of the assistant to delete. </param>
273 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
274 /// <returns> A <see cref="AssistantDeletionResult"/> instance. </returns>
275 public virtual async Task<ClientResult<AssistantDeletionResult>> DeleteAssistantAsync(string assistantId, CancellationToken cancellationToken = default)
276 {
277 Argument.AssertNotNullOrEmpty(assistantId, nameof(assistantId));
278
279 ClientResult protocolResult = await DeleteAssistantAsync(assistantId, cancellationToken.ToRequestOptions()).ConfigureAwait(false);
280 return ClientResult.FromValue(AssistantDeletionResult.FromClientResult(protocolResult), protocolResult.GetRawResponse());
281 }
282
283 /// <summary>
284 /// Deletes an existing <see cref="Assistant"/>.
285 /// </summary>
286 /// <param name="assistantId"> The ID of the assistant to delete. </param>
287 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
288 /// <returns> A <see cref="AssistantDeletionResult"/> instance. </returns>
289 public virtual ClientResult<AssistantDeletionResult> DeleteAssistant(string assistantId, CancellationToken cancellationToken = default)
290 {
291 Argument.AssertNotNullOrEmpty(assistantId, nameof(assistantId));
292
293 ClientResult protocolResult = DeleteAssistant(assistantId, cancellationToken.ToRequestOptions());
294 return ClientResult.FromValue(AssistantDeletionResult.FromClientResult(protocolResult), protocolResult.GetRawResponse());
295 }
296
297 /// <summary>
298 /// Creates a new <see cref="AssistantThread"/>.
299 /// </summary>
300 /// <param name="options"> Additional options to use when creating the thread. </param>
301 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
302 /// <returns> A new thread. </returns>
303 public virtual async Task<ClientResult<AssistantThread>> CreateThreadAsync(ThreadCreationOptions options = null, CancellationToken cancellationToken = default)
304 {
305 ClientResult protocolResult = await CreateThreadAsync(options?.ToBinaryContent(), cancellationToken.ToRequestOptions()).ConfigureAwait(false);
306 return ClientResult.FromValue(AssistantThread.FromClientResult(protocolResult), protocolResult.GetRawResponse());;
307 }
308
309 /// <summary>
310 /// Creates a new <see cref="AssistantThread"/>.
311 /// </summary>
312 /// <param name="options"> Additional options to use when creating the thread. </param>
313 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
314 /// <returns> A new thread. </returns>
315 public virtual ClientResult<AssistantThread> CreateThread(ThreadCreationOptions options = null, CancellationToken cancellationToken = default)
316 {
317 ClientResult protocolResult = CreateThread(options?.ToBinaryContent(), cancellationToken.ToRequestOptions());
318 return ClientResult.FromValue(AssistantThread.FromClientResult(protocolResult), protocolResult.GetRawResponse());
319 }
320
321 /// <summary>
322 /// Gets an existing <see cref="AssistantThread"/>, retrieved via a known ID.
323 /// </summary>
324 /// <param name="threadId"> The ID of the thread to retrieve. </param>
325 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
326 /// <returns> The existing thread instance. </returns>
327 public virtual async Task<ClientResult<AssistantThread>> GetThreadAsync(string threadId, CancellationToken cancellationToken = default)
328 {
329 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
330
331 ClientResult protocolResult = await GetThreadAsync(threadId, cancellationToken.ToRequestOptions()).ConfigureAwait(false);
332 return ClientResult.FromValue(AssistantThread.FromClientResult(protocolResult), protocolResult.GetRawResponse());
333 }
334
335 /// <summary>
336 /// Gets an existing <see cref="AssistantThread"/>, retrieved via a known ID.
337 /// </summary>
338 /// <param name="threadId"> The ID of the thread to retrieve. </param>
339 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
340 /// <returns> The existing thread instance. </returns>
341 public virtual ClientResult<AssistantThread> GetThread(string threadId, CancellationToken cancellationToken = default)
342 {
343 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
344
345 ClientResult protocolResult = GetThread(threadId, cancellationToken.ToRequestOptions());
346 return ClientResult.FromValue(AssistantThread.FromClientResult(protocolResult), protocolResult.GetRawResponse());
347 }
348
349 /// <summary>
350 /// Modifies an existing <see cref="AssistantThread"/>.
351 /// </summary>
352 /// <param name="threadId"> The ID of the thread to modify. </param>
353 /// <param name="options"> The modifications to apply to the thread. </param>
354 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
355 /// <returns> The updated <see cref="AssistantThread"/> instance. </returns>
356 public virtual async Task<ClientResult<AssistantThread>> ModifyThreadAsync(string threadId, ThreadModificationOptions options, CancellationToken cancellationToken = default)
357 {
358 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
359 Argument.AssertNotNull(options, nameof(options));
360
361 ClientResult protocolResult = await ModifyThreadAsync(threadId, options?.ToBinaryContent(), cancellationToken.ToRequestOptions()).ConfigureAwait(false);
362 return ClientResult.FromValue(AssistantThread.FromClientResult(protocolResult), protocolResult.GetRawResponse());
363 }
364
365 /// <summary>
366 /// Modifies an existing <see cref="AssistantThread"/>.
367 /// </summary>
368 /// <param name="threadId"> The ID of the thread to modify. </param>
369 /// <param name="options"> The modifications to apply to the thread. </param>
370 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
371 /// <returns> The updated <see cref="AssistantThread"/> instance. </returns>
372 public virtual ClientResult<AssistantThread> ModifyThread(string threadId, ThreadModificationOptions options, CancellationToken cancellationToken = default)
373 {
374 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
375 Argument.AssertNotNull(options, nameof(options));
376
377 ClientResult protocolResult = ModifyThread(threadId, options?.ToBinaryContent(), cancellationToken.ToRequestOptions());
378 return ClientResult.FromValue(AssistantThread.FromClientResult(protocolResult), protocolResult.GetRawResponse());
379 }
380
381 /// <summary>
382 /// Deletes an existing <see cref="AssistantThread"/>.
383 /// </summary>
384 /// <param name="threadId"> The ID of the thread to delete. </param>
385 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
386 /// <returns> A <see cref="ThreadDeletionResult"/> instance. </returns>
387 public virtual async Task<ClientResult<ThreadDeletionResult>> DeleteThreadAsync(string threadId, CancellationToken cancellationToken = default)
388 {
389 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
390
391 ClientResult protocolResult = await DeleteThreadAsync(threadId, cancellationToken.ToRequestOptions()).ConfigureAwait(false);
392 return ClientResult.FromValue(ThreadDeletionResult.FromClientResult(protocolResult), protocolResult.GetRawResponse());
393 }
394
395 /// <summary>
396 /// Deletes an existing <see cref="AssistantThread"/>.
397 /// </summary>
398 /// <param name="threadId"> The ID of the thread to delete. </param>
399 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
400 /// <returns> A <see cref="ThreadDeletionResult"/> instance. </returns>
401 public virtual ClientResult<ThreadDeletionResult> DeleteThread(string threadId, CancellationToken cancellationToken = default)
402 {
403 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
404
405 ClientResult protocolResult = DeleteThread(threadId, cancellationToken.ToRequestOptions());
406 return ClientResult.FromValue(ThreadDeletionResult.FromClientResult(protocolResult), protocolResult.GetRawResponse());
407 }
408
409 /// <summary>
410 /// Creates a new <see cref="ThreadMessage"/> on an existing <see cref="AssistantThread"/>.
411 /// </summary>
412 /// <param name="threadId"> The ID of the thread to associate the new message with. </param>
413 /// <param name="role"> The role to associate with the new message. </param>
414 /// <param name="content"> The collection of <see cref="MessageContent"/> items for the message. </param>
415 /// <param name="options"> Additional options to apply to the new message. </param>
416 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
417 /// <returns> A new <see cref="ThreadMessage"/>. </returns>
418 public virtual async Task<ClientResult<ThreadMessage>> CreateMessageAsync(
419 string threadId,
420 MessageRole role,
421 IEnumerable<MessageContent> content,
422 MessageCreationOptions options = null,
423 CancellationToken cancellationToken = default)
424 {
425 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
426 options ??= new();
427 options.Role = role;
428 options.Content.Clear();
429 foreach (MessageContent contentItem in content)
430 {
431 options.Content.Add(contentItem);
432 }
433
434 ClientResult protocolResult = await CreateMessageAsync(threadId, options?.ToBinaryContent(), cancellationToken.ToRequestOptions())
435 .ConfigureAwait(false);
436 return ClientResult.FromValue(ThreadMessage.FromClientResult(protocolResult), protocolResult.GetRawResponse());
437 }
438
439 /// <summary>
440 /// Creates a new <see cref="ThreadMessage"/> on an existing <see cref="AssistantThread"/>.
441 /// </summary>
442 /// <param name="threadId"> The ID of the thread to associate the new message with. </param>
443 /// <param name="role"> The role to associate with the new message. </param>
444 /// <param name="content"> The collection of <see cref="MessageContent"/> items for the message. </param>
445 /// <param name="options"> Additional options to apply to the new message. </param>
446 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
447 /// <returns> A new <see cref="ThreadMessage"/>. </returns>
448 public virtual ClientResult<ThreadMessage> CreateMessage(
449 string threadId,
450 MessageRole role,
451 IEnumerable<MessageContent> content,
452 MessageCreationOptions options = null,
453 CancellationToken cancellationToken = default)
454 {
455 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
456 options ??= new();
457 options.Role = role;
458 options.Content.Clear();
459 foreach (MessageContent contentItem in content)
460 {
461 options.Content.Add(contentItem);
462 }
463
464 ClientResult protocolResult = CreateMessage(threadId, options?.ToBinaryContent(), cancellationToken.ToRequestOptions());
465 return ClientResult.FromValue(ThreadMessage.FromClientResult(protocolResult), protocolResult.GetRawResponse());
466 }
467
468 /// <summary>
469 /// Gets a page collection of <see cref="ThreadMessage"/> instances from an existing <see cref="AssistantThread"/>.
470 /// </summary>
471 /// <param name="threadId"> The ID of the thread to list messages from. </param>
472 /// <param name="options"> Options describing the collection to return. </param>
473 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
474 /// <returns> A collection of <see cref="ThreadMessage"/>. </returns>
475 public virtual AsyncCollectionResult<ThreadMessage> GetMessagesAsync(
476 string threadId,
477 MessageCollectionOptions options = default,
478 CancellationToken cancellationToken = default)
479 {
480 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
481
482 AsyncCollectionResult result = GetMessagesAsync(threadId, options?.PageSizeLimit, options?.Order?.ToString(), options?.AfterId, options?.BeforeId, cancellationToken.ToRequestOptions());
483
484 if (result is not AsyncCollectionResult<ThreadMessage> collection)
485 {
486 throw new InvalidOperationException("Failed to cast protocol return type to expected collection type 'AsyncCollectionResult<ThreadMessage>'.");
487 }
488
489 return collection;
490 }
491
492 /// <summary>
493 /// Rehydrates a page collection of <see cref="ThreadMessage"/> instances from a page token.
494 /// </summary>
495 /// <param name="firstPageToken"> Page token corresponding to the first page of the collection to rehydrate. </param>
496 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
497 /// <returns> A collection of <see cref="ThreadMessage"/>. </returns>
498 public virtual AsyncCollectionResult<ThreadMessage> GetMessagesAsync(
499 ContinuationToken firstPageToken,
500 CancellationToken cancellationToken = default)
501 {
502 Argument.AssertNotNull(firstPageToken, nameof(firstPageToken));
503
504 MessageCollectionPageToken pageToken = MessageCollectionPageToken.FromToken(firstPageToken);
505 AsyncCollectionResult result = GetMessagesAsync(pageToken?.ThreadId, pageToken?.Limit, pageToken?.Order, pageToken?.After, pageToken?.Before, cancellationToken.ToRequestOptions());
506
507 if (result is not AsyncCollectionResult<ThreadMessage> collection)
508 {
509 throw new InvalidOperationException("Failed to cast protocol return type to expected collection type 'AsyncCollectionResult<ThreadMessage>'.");
510 }
511
512 return collection;
513 }
514
515 /// <summary>
516 /// Gets a page collection holding <see cref="ThreadMessage"/> instances from an existing <see cref="AssistantThread"/>.
517 /// </summary>
518 /// <param name="threadId"> The ID of the thread to list messages from. </param>
519 /// <param name="options"> Options describing the collection to return. </param>
520 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
521 /// <returns> A collection of <see cref="ThreadMessage"/>. </returns>
522 public virtual CollectionResult<ThreadMessage> GetMessages(
523 string threadId,
524 MessageCollectionOptions options = default,
525 CancellationToken cancellationToken = default)
526 {
527 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
528
529 CollectionResult result = GetMessages(threadId, options?.PageSizeLimit, options?.Order?.ToString(), options?.AfterId, options?.BeforeId, cancellationToken.ToRequestOptions());
530
531 if (result is not CollectionResult<ThreadMessage> collection)
532 {
533 throw new InvalidOperationException("Failed to cast protocol return type to expected collection type 'CollectionResult<ThreadMessage>'.");
534 }
535
536 return collection;
537 }
538
539 /// <summary>
540 /// Rehydrates a page collection holding <see cref="ThreadMessage"/> instances from a page token.
541 /// </summary>
542 /// <param name="firstPageToken"> Page token corresponding to the first page of the collection to rehydrate. </param>
543 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
544 /// <returns> A collection of <see cref="ThreadMessage"/>. </returns>
545 public virtual CollectionResult<ThreadMessage> GetMessages(
546 ContinuationToken firstPageToken,
547 CancellationToken cancellationToken = default)
548 {
549 Argument.AssertNotNull(firstPageToken, nameof(firstPageToken));
550
551 MessageCollectionPageToken pageToken = MessageCollectionPageToken.FromToken(firstPageToken);
552 CollectionResult result = GetMessages(pageToken?.ThreadId, pageToken?.Limit, pageToken?.Order, pageToken?.After, pageToken?.Before, cancellationToken.ToRequestOptions());
553
554 if (result is not CollectionResult<ThreadMessage> collection)
555 {
556 throw new InvalidOperationException("Failed to cast protocol return type to expected collection type 'CollectionResult<ThreadMessage>'.");
557 }
558
559 return collection;
560
561 }
562
563 /// <summary>
564 /// Gets an existing <see cref="ThreadMessage"/> from a known <see cref="AssistantThread"/>.
565 /// </summary>
566 /// <param name="threadId"> The ID of the thread to retrieve the message from. </param>
567 /// <param name="messageId"> The ID of the message to retrieve. </param>
568 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
569 /// <returns> The existing <see cref="ThreadMessage"/> instance. </returns>
570 public virtual async Task<ClientResult<ThreadMessage>> GetMessageAsync(string threadId, string messageId, CancellationToken cancellationToken = default)
571 {
572 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
573 Argument.AssertNotNullOrEmpty(messageId, nameof(messageId));
574
575 ClientResult protocolResult = await GetMessageAsync(threadId, messageId, cancellationToken.ToRequestOptions()).ConfigureAwait(false);
576 return ClientResult.FromValue(ThreadMessage.FromClientResult(protocolResult), protocolResult.GetRawResponse());
577 }
578
579 /// <summary>
580 /// Gets an existing <see cref="ThreadMessage"/> from a known <see cref="AssistantThread"/>.
581 /// </summary>
582 /// <param name="threadId"> The ID of the thread to retrieve the message from. </param>
583 /// <param name="messageId"> The ID of the message to retrieve. </param>
584 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
585 /// <returns> The existing <see cref="ThreadMessage"/> instance. </returns>
586 public virtual ClientResult<ThreadMessage> GetMessage(string threadId, string messageId, CancellationToken cancellationToken = default)
587 {
588 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
589 Argument.AssertNotNullOrEmpty(messageId, nameof(messageId));
590
591 ClientResult protocolResult = GetMessage(threadId, messageId, cancellationToken.ToRequestOptions());
592 return ClientResult.FromValue(ThreadMessage.FromClientResult(protocolResult), protocolResult.GetRawResponse());
593 }
594
595 /// <summary>
596 /// Modifies an existing <see cref="ThreadMessage"/>.
597 /// </summary>
598 /// <param name="threadId"> The ID of the thread associated with the message to modify. </param>
599 /// <param name="messageId"> The ID of the message to modify. </param>
600 /// <param name="options"> The changes to apply to the message. </param>
601 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
602 /// <returns> The updated <see cref="ThreadMessage"/>. </returns>
603 public virtual async Task<ClientResult<ThreadMessage>> ModifyMessageAsync(string threadId, string messageId, MessageModificationOptions options, CancellationToken cancellationToken = default)
604 {
605 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
606 Argument.AssertNotNullOrEmpty(messageId, nameof(messageId));
607 Argument.AssertNotNull(options, nameof(options));
608
609 ClientResult protocolResult = await ModifyMessageAsync(threadId, messageId, options?.ToBinaryContent(), cancellationToken.ToRequestOptions())
610 .ConfigureAwait(false);
611 return ClientResult.FromValue(ThreadMessage.FromClientResult(protocolResult), protocolResult.GetRawResponse());
612 }
613
614 /// <summary>
615 /// Modifies an existing <see cref="ThreadMessage"/>.
616 /// </summary>
617 /// <param name="threadId"> The ID of the thread associated with the message to modify. </param>
618 /// <param name="messageId"> The ID of the message to modify. </param>
619 /// <param name="options"> The changes to apply to the message. </param>
620 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
621 /// <returns> The updated <see cref="ThreadMessage"/>. </returns>
622 public virtual ClientResult<ThreadMessage> ModifyMessage(string threadId, string messageId, MessageModificationOptions options, CancellationToken cancellationToken = default)
623 {
624 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
625 Argument.AssertNotNullOrEmpty(messageId, nameof(messageId));
626 Argument.AssertNotNull(options, nameof(options));
627
628 ClientResult protocolResult = ModifyMessage(threadId, messageId, options?.ToBinaryContent(), cancellationToken.ToRequestOptions());
629 return ClientResult.FromValue(ThreadMessage.FromClientResult(protocolResult), protocolResult.GetRawResponse());
630 }
631
632 /// <summary>
633 /// Deletes an existing <see cref="ThreadMessage"/>.
634 /// </summary>
635 /// <param name="threadId"> The ID of the thread associated with the message. </param>
636 /// <param name="messageId"> The ID of the message. </param>
637 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
638 /// <returns> A <see cref="MessageDeletionResult"/> instance. </returns>
639 public virtual async Task<ClientResult<MessageDeletionResult>> DeleteMessageAsync(string threadId, string messageId, CancellationToken cancellationToken = default)
640 {
641 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
642 Argument.AssertNotNullOrEmpty(messageId, nameof(messageId));
643
644 ClientResult protocolResult = await DeleteMessageAsync(threadId, messageId, cancellationToken.ToRequestOptions()).ConfigureAwait(false);
645 return ClientResult.FromValue(MessageDeletionResult.FromClientResult(protocolResult), protocolResult.GetRawResponse());
646 }
647
648 /// <summary>
649 /// Deletes an existing <see cref="ThreadMessage"/>.
650 /// </summary>
651 /// <param name="threadId"> The ID of the thread associated with the message. </param>
652 /// <param name="messageId"> The ID of the message. </param>
653 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
654 /// <returns> A <see cref="MessageDeletionResult"/> instance. </returns>
655 public virtual ClientResult<MessageDeletionResult> DeleteMessage(string threadId, string messageId, CancellationToken cancellationToken = default)
656 {
657 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
658 Argument.AssertNotNullOrEmpty(messageId, nameof(messageId));
659
660 ClientResult protocolResult = DeleteMessage(threadId, messageId, cancellationToken.ToRequestOptions());
661 return ClientResult.FromValue(MessageDeletionResult.FromClientResult(protocolResult), protocolResult.GetRawResponse());
662 }
663
664 /// <summary>
665 /// Begins a new <see cref="ThreadRun"/> that evaluates a <see cref="AssistantThread"/> using a specified
666 /// <see cref="Assistant"/>.
667 /// </summary>
668 /// <param name="threadId"> The ID of the thread that the run should evaluate. </param>
669 /// <param name="assistantId"> The ID of the assistant that should be used when evaluating the thread. </param>
670 /// <param name="options"> Additional options for the run. </param>
671 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
672 /// <returns> A new <see cref="ThreadRun"/> instance. </returns>
673 public virtual async Task<ClientResult<ThreadRun>> CreateRunAsync(string threadId, string assistantId, RunCreationOptions options = null, CancellationToken cancellationToken = default)
674 {
675 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
676 Argument.AssertNotNullOrEmpty(assistantId, nameof(assistantId));
677 options ??= new();
678 options.AssistantId = assistantId;
679 options.Stream = null;
680
681 ClientResult protocolResult = await CreateRunAsync(threadId, options?.ToBinaryContent(), cancellationToken.ToRequestOptions())
682 .ConfigureAwait(false);
683 return ClientResult.FromValue(ThreadRun.FromClientResult(protocolResult), protocolResult.GetRawResponse());
684 }
685
686 /// <summary>
687 /// Begins a new <see cref="ThreadRun"/> that evaluates a <see cref="AssistantThread"/> using a specified
688 /// <see cref="Assistant"/>.
689 /// </summary>
690 /// <param name="threadId"> The ID of the thread that the run should evaluate. </param>
691 /// <param name="assistantId"> The ID of the assistant that should be used when evaluating the thread. </param>
692 /// <param name="options"> Additional options for the run. </param>
693 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
694 /// <returns> A new <see cref="ThreadRun"/> instance. </returns>
695 public virtual ClientResult<ThreadRun> CreateRun(string threadId, string assistantId, RunCreationOptions options = null, CancellationToken cancellationToken = default)
696 {
697 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
698 Argument.AssertNotNullOrEmpty(assistantId, nameof(assistantId));
699 options ??= new();
700 options.AssistantId = assistantId;
701 options.Stream = null;
702
703 ClientResult protocolResult = CreateRun(threadId, options?.ToBinaryContent(), cancellationToken.ToRequestOptions());
704 return ClientResult.FromValue(ThreadRun.FromClientResult(protocolResult), protocolResult.GetRawResponse());
705 }
706
707 /// <summary>
708 /// Begins a new streaming <see cref="ThreadRun"/> that evaluates a <see cref="AssistantThread"/> using a specified
709 /// <see cref="Assistant"/>.
710 /// </summary>
711 /// <param name="threadId"> The ID of the thread that the run should evaluate. </param>
712 /// <param name="assistantId"> The ID of the assistant that should be used when evaluating the thread. </param>
713 /// <param name="options"> Additional options for the run. </param>
714 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
715 public virtual AsyncCollectionResult<StreamingUpdate> CreateRunStreamingAsync(
716 string threadId,
717 string assistantId,
718 RunCreationOptions options = null,
719 CancellationToken cancellationToken = default)
720 {
721 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
722 Argument.AssertNotNullOrEmpty(assistantId, nameof(assistantId));
723
724 options ??= new();
725 options.AssistantId = assistantId;
726 options.Stream = true;
727
728 return new AsyncSseUpdateCollection<StreamingUpdate>(
729 async () => await CreateRunAsync(threadId, options?.ToBinaryContent(), cancellationToken.ToRequestOptions(streaming: true)).ConfigureAwait(false),
730 StreamingUpdate.FromSseItem,
731 cancellationToken);
732 }
733
734 /// <summary>
735 /// Begins a new streaming <see cref="ThreadRun"/> that evaluates a <see cref="AssistantThread"/> using a specified
736 /// <see cref="Assistant"/>.
737 /// </summary>
738 /// <param name="threadId"> The ID of the thread that the run should evaluate. </param>
739 /// <param name="assistantId"> The ID of the assistant that should be used when evaluating the thread. </param>
740 /// <param name="options"> Additional options for the run. </param>
741 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
742 public virtual CollectionResult<StreamingUpdate> CreateRunStreaming(
743 string threadId,
744 string assistantId,
745 RunCreationOptions options = null,
746 CancellationToken cancellationToken = default)
747 {
748 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
749 Argument.AssertNotNullOrEmpty(assistantId, nameof(assistantId));
750
751 options ??= new();
752 options.AssistantId = assistantId;
753 options.Stream = true;
754
755 return new SseUpdateCollection<StreamingUpdate>(
756 () => CreateRun(threadId, options?.ToBinaryContent(), cancellationToken.ToRequestOptions(streaming: true)),
757 StreamingUpdate.FromSseItem,
758 cancellationToken);
759 }
760
761 /// <summary>
762 /// Creates a new thread and immediately begins a run against it using the specified <see cref="Assistant"/>.
763 /// </summary>
764 /// <param name="assistantId"> The ID of the assistant that the new run should use. </param>
765 /// <param name="threadOptions"> Options for the new thread that will be created. </param>
766 /// <param name="runOptions"> Additional options to apply to the run that will begin. </param>
767 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
768 /// <returns> A new <see cref="ThreadRun"/>. </returns>
769 public virtual async Task<ClientResult<ThreadRun>> CreateThreadAndRunAsync(
770 string assistantId,
771 ThreadCreationOptions threadOptions = null,
772 RunCreationOptions runOptions = null,
773 CancellationToken cancellationToken = default)
774 {
775 runOptions ??= new();
776 runOptions.Stream = null;
777 BinaryContent protocolContent = CreateThreadAndRunProtocolContent(assistantId, threadOptions, runOptions);
778 ClientResult protocolResult = await CreateThreadAndRunAsync(protocolContent, cancellationToken.ToRequestOptions()).ConfigureAwait(false);
779 return ClientResult.FromValue(ThreadRun.FromClientResult(protocolResult), protocolResult.GetRawResponse());
780 }
781
782 /// <summary>
783 /// Creates a new thread and immediately begins a run against it using the specified <see cref="Assistant"/>.
784 /// </summary>
785 /// <param name="assistantId"> The ID of the assistant that the new run should use. </param>
786 /// <param name="threadOptions"> Options for the new thread that will be created. </param>
787 /// <param name="runOptions"> Additional options to apply to the run that will begin. </param>
788 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
789 /// <returns> A new <see cref="ThreadRun"/>. </returns>
790 public virtual ClientResult<ThreadRun> CreateThreadAndRun(
791 string assistantId,
792 ThreadCreationOptions threadOptions = null,
793 RunCreationOptions runOptions = null,
794 CancellationToken cancellationToken = default)
795 {
796 runOptions ??= new();
797 runOptions.Stream = null;
798 BinaryContent protocolContent = CreateThreadAndRunProtocolContent(assistantId, threadOptions, runOptions);
799 ClientResult protocolResult = CreateThreadAndRun(protocolContent, cancellationToken.ToRequestOptions());
800 return ClientResult.FromValue(ThreadRun.FromClientResult(protocolResult), protocolResult.GetRawResponse());
801 }
802
803 /// <summary>
804 /// Creates a new thread and immediately begins a streaming run against it using the specified <see cref="Assistant"/>.
805 /// </summary>
806 /// <param name="assistantId"> The ID of the assistant that the new run should use. </param>
807 /// <param name="threadOptions"> Options for the new thread that will be created. </param>
808 /// <param name="runOptions"> Additional options to apply to the run that will begin. </param>
809 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
810 public virtual AsyncCollectionResult<StreamingUpdate> CreateThreadAndRunStreamingAsync(
811 string assistantId,
812 ThreadCreationOptions threadOptions = null,
813 RunCreationOptions runOptions = null,
814 CancellationToken cancellationToken = default)
815 {
816 Argument.AssertNotNullOrEmpty(assistantId, nameof(assistantId));
817
818 runOptions ??= new();
819 runOptions.Stream = true;
820 BinaryContent protocolContent = CreateThreadAndRunProtocolContent(assistantId, threadOptions, runOptions);
821
822 return new AsyncSseUpdateCollection<StreamingUpdate>(
823 async () => await CreateThreadAndRunAsync(protocolContent, cancellationToken.ToRequestOptions(streaming: true)).ConfigureAwait(false),
824 StreamingUpdate.FromSseItem,
825 cancellationToken);
826 }
827
828 /// <summary>
829 /// Creates a new thread and immediately begins a streaming run against it using the specified <see cref="Assistant"/>.
830 /// </summary>
831 /// <param name="assistantId"> The ID of the assistant that the new run should use. </param>
832 /// <param name="threadOptions"> Options for the new thread that will be created. </param>
833 /// <param name="runOptions"> Additional options to apply to the run that will begin. </param>
834 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
835 public virtual CollectionResult<StreamingUpdate> CreateThreadAndRunStreaming(
836 string assistantId,
837 ThreadCreationOptions threadOptions = null,
838 RunCreationOptions runOptions = null,
839 CancellationToken cancellationToken = default)
840 {
841 Argument.AssertNotNullOrEmpty(assistantId, nameof(assistantId));
842
843 runOptions ??= new();
844 runOptions.Stream = true;
845 BinaryContent protocolContent = CreateThreadAndRunProtocolContent(assistantId, threadOptions, runOptions);
846
847 return new SseUpdateCollection<StreamingUpdate>(
848 () => CreateThreadAndRun(protocolContent, cancellationToken.ToRequestOptions(streaming: true)),
849 StreamingUpdate.FromSseItem,
850 cancellationToken);
851 }
852
853 /// <summary>
854 /// Gets a page collection holding <see cref="ThreadRun"/> instances associated with an existing <see cref="AssistantThread"/>.
855 /// </summary>
856 /// <param name="threadId"> The ID of the thread that runs in the list should be associated with. </param>
857 /// <param name="options"> Options describing the collection to return. </param>
858 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
859 /// <returns> A collection of <see cref="ThreadRun"/>. </returns>
860 public virtual AsyncCollectionResult<ThreadRun> GetRunsAsync(
861 string threadId,
862 RunCollectionOptions options = default,
863 CancellationToken cancellationToken = default)
864 {
865 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
866
867 AsyncCollectionResult result = GetRunsAsync(threadId, options?.PageSizeLimit, options?.Order?.ToString(), options?.AfterId, options?.BeforeId, cancellationToken.ToRequestOptions());
868
869 if (result is not AsyncCollectionResult<ThreadRun> collection)
870 {
871 throw new InvalidOperationException("Failed to cast protocol return type to expected collection type 'AsyncCollectionResult<ThreadRun>'.");
872 }
873
874 return collection;
875 }
876
877 /// <summary>
878 /// Rehydrates a page collection holding <see cref="ThreadRun"/> instances from a page token.
879 /// </summary>
880 /// <param name="firstPageToken"> Page token corresponding to the first page of the collection to rehydrate. </param>
881 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
882 /// <returns> A collection of <see cref="ThreadRun"/>. </returns>
883 public virtual AsyncCollectionResult<ThreadRun> GetRunsAsync(
884 ContinuationToken firstPageToken,
885 CancellationToken cancellationToken = default)
886 {
887 Argument.AssertNotNull(firstPageToken, nameof(firstPageToken));
888
889 RunCollectionPageToken pageToken = RunCollectionPageToken.FromToken(firstPageToken);
890 AsyncCollectionResult result = GetRunsAsync(pageToken?.ThreadId, pageToken?.Limit, pageToken?.Order, pageToken?.After, pageToken?.Before, cancellationToken.ToRequestOptions());
891
892 if (result is not AsyncCollectionResult<ThreadRun> collection)
893 {
894 throw new InvalidOperationException("Failed to cast protocol return type to expected collection type 'AsyncCollectionResult<ThreadRun>'.");
895 }
896
897 return collection;
898 }
899
900 /// <summary>
901 /// Gets a page collection holding <see cref="ThreadRun"/> instances associated with an existing <see cref="AssistantThread"/>.
902 /// </summary>
903 /// <param name="threadId"> The ID of the thread that runs in the list should be associated with. </param>
904 /// <param name="options"> Options describing the collection to return. </param>
905 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
906 /// <returns> A collection of <see cref="ThreadRun"/>. </returns>
907 public virtual CollectionResult<ThreadRun> GetRuns(
908 string threadId,
909 RunCollectionOptions options = default,
910 CancellationToken cancellationToken = default)
911 {
912 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
913
914 CollectionResult result = GetRuns(threadId, options?.PageSizeLimit, options?.Order?.ToString(), options?.AfterId, options?.BeforeId, cancellationToken.ToRequestOptions());
915
916 if (result is not CollectionResult<ThreadRun> collection)
917 {
918 throw new InvalidOperationException("Failed to cast protocol return type to expected collection type 'CollectionResult<ThreadRun>'.");
919 }
920
921 return collection;
922 }
923
924 /// <summary>
925 /// Rehydrates a page collection holding <see cref="ThreadRun"/> instances from a page token.
926 /// </summary>
927 /// <param name="firstPageToken"> Page token corresponding to the first page of the collection to rehydrate. </param>
928 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
929 /// <returns> A collection of <see cref="ThreadRun"/>. </returns>
930 public virtual CollectionResult<ThreadRun> GetRuns(
931 ContinuationToken firstPageToken,
932 CancellationToken cancellationToken = default)
933 {
934 Argument.AssertNotNull(firstPageToken, nameof(firstPageToken));
935
936 RunCollectionPageToken pageToken = RunCollectionPageToken.FromToken(firstPageToken);
937 CollectionResult result = GetRuns(pageToken?.ThreadId, pageToken?.Limit, pageToken?.Order, pageToken?.After, pageToken?.Before, cancellationToken.ToRequestOptions());
938
939 if (result is not CollectionResult<ThreadRun> collection)
940 {
941 throw new InvalidOperationException("Failed to cast protocol return type to expected collection type 'CollectionResult<ThreadRun>'.");
942 }
943
944 return collection;
945 }
946
947 /// <summary>
948 /// Gets an existing <see cref="ThreadRun"/> from a known <see cref="AssistantThread"/>.
949 /// </summary>
950 /// <param name="threadId"> The ID of the thread to retrieve the run from. </param>
951 /// <param name="runId"> The ID of the run to retrieve. </param>
952 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
953 /// <returns> The existing <see cref="ThreadRun"/> instance. </returns>
954 public virtual async Task<ClientResult<ThreadRun>> GetRunAsync(string threadId, string runId, CancellationToken cancellationToken = default)
955 {
956 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
957 Argument.AssertNotNullOrEmpty(runId, nameof(runId));
958
959 ClientResult protocolResult = await GetRunAsync(threadId, runId, cancellationToken.ToRequestOptions()).ConfigureAwait(false);
960 return ClientResult.FromValue(ThreadRun.FromClientResult(protocolResult), protocolResult.GetRawResponse());
961 }
962
963 /// <summary>
964 /// Gets an existing <see cref="ThreadRun"/> from a known <see cref="AssistantThread"/>.
965 /// </summary>
966 /// <param name="threadId"> The ID of the thread to retrieve the run from. </param>
967 /// <param name="runId"> The ID of the run to retrieve. </param>
968 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
969 /// <returns> The existing <see cref="ThreadRun"/> instance. </returns>
970 public virtual ClientResult<ThreadRun> GetRun(string threadId, string runId, CancellationToken cancellationToken = default)
971 {
972 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
973 Argument.AssertNotNullOrEmpty(runId, nameof(runId));
974
975 ClientResult protocolResult = GetRun(threadId, runId, cancellationToken.ToRequestOptions());
976 return ClientResult.FromValue(ThreadRun.FromClientResult(protocolResult), protocolResult.GetRawResponse());
977 }
978
979 /// <summary>
980 /// Submits a collection of required tool call outputs to a run and resumes the run.
981 /// </summary>
982 /// <param name="threadId"> The thread ID of the thread being run. </param>
983 /// <param name="runId"> The ID of the run that reached a <c>requires_action</c> status. </param>
984 /// <param name="toolOutputs">
985 /// The tool outputs, corresponding to <see cref="InternalRequiredToolCall"/> instances from the run.
986 /// </param>
987 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
988 /// <returns> The <see cref="ThreadRun"/>, updated after the submission was processed. </returns>
989 public virtual async Task<ClientResult<ThreadRun>> SubmitToolOutputsToRunAsync(
990 string threadId,
991 string runId,
992 IEnumerable<ToolOutput> toolOutputs,
993 CancellationToken cancellationToken = default)
994 {
995 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
996 Argument.AssertNotNullOrEmpty(runId, nameof(runId));
997
998 var submitToolOutputsRunRequest = new InternalSubmitToolOutputsRunRequest(toolOutputs);
999 using BinaryContent content = BinaryContent.Create(submitToolOutputsRunRequest, ModelSerializationExtensions.WireOptions);
1000 ClientResult protocolResult = await SubmitToolOutputsToRunAsync(threadId, runId, content, cancellationToken.ToRequestOptions())
1001 .ConfigureAwait(false);
1002 return ClientResult.FromValue(ThreadRun.FromClientResult(protocolResult), protocolResult.GetRawResponse());
1003 }
1004
1005 /// <summary>
1006 /// Submits a collection of required tool call outputs to a run and resumes the run.
1007 /// </summary>
1008 /// <param name="threadId"> The thread ID of the thread being run. </param>
1009 /// <param name="runId"> The ID of the run that reached a <c>requires_action</c> status. </param>
1010 /// <param name="toolOutputs">
1011 /// The tool outputs, corresponding to <see cref="InternalRequiredToolCall"/> instances from the run.
1012 /// </param>
1013 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
1014 /// <returns> The <see cref="ThreadRun"/>, updated after the submission was processed. </returns>
1015 public virtual ClientResult<ThreadRun> SubmitToolOutputsToRun(
1016 string threadId,
1017 string runId,
1018 IEnumerable<ToolOutput> toolOutputs,
1019 CancellationToken cancellationToken = default)
1020 {
1021 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
1022 Argument.AssertNotNullOrEmpty(runId, nameof(runId));
1023
1024 var submitToolOutputsRunRequest = new InternalSubmitToolOutputsRunRequest(toolOutputs);
1025 using BinaryContent content = BinaryContent.Create(submitToolOutputsRunRequest, ModelSerializationExtensions.WireOptions);
1026 ClientResult protocolResult = SubmitToolOutputsToRun(threadId, runId, content, cancellationToken.ToRequestOptions());
1027 return ClientResult.FromValue(ThreadRun.FromClientResult(protocolResult), protocolResult.GetRawResponse());
1028 }
1029
1030 /// <summary>
1031 /// Submits a collection of required tool call outputs to a run and resumes the run with streaming enabled.
1032 /// </summary>
1033 /// <param name="threadId"> The thread ID of the thread being run. </param>
1034 /// <param name="runId"> The ID of the run that reached a <c>requires_action</c> status. </param>
1035 /// <param name="toolOutputs">
1036 /// The tool outputs, corresponding to <see cref="InternalRequiredToolCall"/> instances from the run.
1037 /// </param>
1038 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
1039 public virtual AsyncCollectionResult<StreamingUpdate> SubmitToolOutputsToRunStreamingAsync(
1040 string threadId,
1041 string runId,
1042 IEnumerable<ToolOutput> toolOutputs,
1043 CancellationToken cancellationToken = default)
1044 {
1045 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
1046 Argument.AssertNotNullOrEmpty(runId, nameof(runId));
1047
1048 var submitToolOutputsRunRequest = new InternalSubmitToolOutputsRunRequest(toolOutputs.ToList(), stream: true, null);
1049 using BinaryContent content = BinaryContent.Create(submitToolOutputsRunRequest, ModelSerializationExtensions.WireOptions);
1050
1051 return new AsyncSseUpdateCollection<StreamingUpdate>(
1052 async () => await SubmitToolOutputsToRunAsync(threadId, runId, content, cancellationToken.ToRequestOptions(streaming: true)).ConfigureAwait(false),
1053 StreamingUpdate.FromSseItem,
1054 cancellationToken);
1055 }
1056
1057 /// <summary>
1058 /// Submits a collection of required tool call outputs to a run and resumes the run with streaming enabled.
1059 /// </summary>
1060 /// <param name="threadId"> The thread ID of the thread being run. </param>
1061 /// <param name="runId"> The ID of the run that reached a <c>requires_action</c> status. </param>
1062 /// <param name="toolOutputs">
1063 /// The tool outputs, corresponding to <see cref="InternalRequiredToolCall"/> instances from the run.
1064 /// </param>
1065 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
1066 public virtual CollectionResult<StreamingUpdate> SubmitToolOutputsToRunStreaming(
1067 string threadId,
1068 string runId,
1069 IEnumerable<ToolOutput> toolOutputs,
1070 CancellationToken cancellationToken = default)
1071 {
1072 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
1073 Argument.AssertNotNullOrEmpty(runId, nameof(runId));
1074
1075 var submitToolOutputsRunRequest = new InternalSubmitToolOutputsRunRequest(toolOutputs.ToList(), stream: true, null);
1076 using BinaryContent content = BinaryContent.Create(submitToolOutputsRunRequest, ModelSerializationExtensions.WireOptions);
1077
1078 return new SseUpdateCollection<StreamingUpdate>(
1079 () => SubmitToolOutputsToRun(threadId, runId, content, cancellationToken.ToRequestOptions(streaming: true)),
1080 StreamingUpdate.FromSseItem,
1081 cancellationToken);
1082 }
1083
1084 /// <summary>
1085 /// Cancels an in-progress <see cref="ThreadRun"/>.
1086 /// </summary>
1087 /// <param name="threadId"> The ID of the thread associated with the run. </param>
1088 /// <param name="runId"> The ID of the run to cancel. </param>
1089 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
1090 /// <returns> An updated <see cref="ThreadRun"/> instance, reflecting the new status of the run. </returns>
1091 public virtual async Task<ClientResult<ThreadRun>> CancelRunAsync(string threadId, string runId, CancellationToken cancellationToken = default)
1092 {
1093 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
1094 Argument.AssertNotNullOrEmpty(runId, nameof(runId));
1095
1096 ClientResult protocolResult = await CancelRunAsync(threadId, runId, cancellationToken.ToRequestOptions()).ConfigureAwait(false);
1097 return ClientResult.FromValue(ThreadRun.FromClientResult(protocolResult), protocolResult.GetRawResponse());
1098 }
1099
1100 /// <summary>
1101 /// Cancels an in-progress <see cref="ThreadRun"/>.
1102 /// </summary>
1103 /// <param name="threadId"> The ID of the thread associated with the run. </param>
1104 /// <param name="runId"> The ID of the run to cancel. </param>
1105 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
1106 /// <returns> An updated <see cref="ThreadRun"/> instance, reflecting the new status of the run. </returns>
1107 public virtual ClientResult<ThreadRun> CancelRun(string threadId, string runId, CancellationToken cancellationToken = default)
1108 {
1109 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
1110 Argument.AssertNotNullOrEmpty(runId, nameof(runId));
1111
1112 ClientResult protocolResult = CancelRun(threadId, runId, cancellationToken.ToRequestOptions());
1113 return ClientResult.FromValue(ThreadRun.FromClientResult(protocolResult), protocolResult.GetRawResponse());
1114 }
1115
1116 /// <summary>
1117 /// Gets a page collection holding <see cref="RunStep"/> instances associated with a <see cref="ThreadRun"/>.
1118 /// </summary>
1119 /// <param name="threadId"> The ID of the thread associated with the run. </param>
1120 /// <param name="runId"> The ID of the run to list run steps from. </param>
1121 /// <param name="options"></param>
1122 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
1123 /// <returns> A collection of <see cref="RunStep"/>. </returns>
1124 public virtual AsyncCollectionResult<RunStep> GetRunStepsAsync(
1125 string threadId,
1126 string runId,
1127 RunStepCollectionOptions options = default,
1128 CancellationToken cancellationToken = default)
1129 {
1130 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
1131 Argument.AssertNotNullOrEmpty(runId, nameof(runId));
1132
1133 return GetRunStepsAsync(threadId, runId, options?.PageSizeLimit, options?.Order?.ToString(), options?.AfterId, options?.BeforeId, cancellationToken.ToRequestOptions())
1134 as AsyncCollectionResult<RunStep>;
1135 }
1136
1137 /// <summary>
1138 /// Gets a page collection holding <see cref="RunStep"/> instances associated with a <see cref="ThreadRun"/>.
1139 /// </summary>
1140 /// <param name="threadId"> The ID of the thread associated with the run. </param>
1141 /// <param name="runId"> The ID of the run to list run steps from. </param>
1142 /// <param name="options"></param>
1143 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
1144 /// <returns> A collection of <see cref="RunStep"/>. </returns>
1145 public virtual CollectionResult<RunStep> GetRunSteps(
1146 string threadId,
1147 string runId,
1148 RunStepCollectionOptions options = default,
1149 CancellationToken cancellationToken = default)
1150 {
1151 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
1152 Argument.AssertNotNullOrEmpty(runId, nameof(runId));
1153
1154 CollectionResult result = GetRunSteps(threadId, runId, options?.PageSizeLimit, options?.Order?.ToString(), options?.AfterId, options?.BeforeId, cancellationToken.ToRequestOptions());
1155
1156 if (result is not CollectionResult<RunStep> collection)
1157 {
1158 throw new InvalidOperationException("Failed to cast protocol return type to expected collection type 'CollectionResult<RunStep>'.");
1159 }
1160
1161 return collection;
1162 }
1163
1164 /// <summary>
1165 /// Rehydrates a page collection holding <see cref="RunStep"/> instances from a page token.
1166 /// </summary>
1167 /// <param name="firstPageToken"> Page token corresponding to the first page of the collection to rehydrate. </param>
1168 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
1169 /// <returns> A collection of <see cref="RunStep"/>. </returns>
1170 public virtual AsyncCollectionResult<RunStep> GetRunStepsAsync(
1171 ContinuationToken firstPageToken,
1172 CancellationToken cancellationToken = default)
1173 {
1174 Argument.AssertNotNull(firstPageToken, nameof(firstPageToken));
1175
1176 RunStepCollectionPageToken pageToken = RunStepCollectionPageToken.FromToken(firstPageToken);
1177 AsyncCollectionResult result = GetRunStepsAsync(pageToken?.ThreadId, pageToken?.RunId, pageToken?.Limit, pageToken?.Order, pageToken?.After, pageToken?.Before, cancellationToken.ToRequestOptions());
1178
1179 if (result is not AsyncCollectionResult<RunStep> collection)
1180 {
1181 throw new InvalidOperationException("Failed to cast protocol return type to expected collection type 'AsyncCollectionResult<RunStep>'.");
1182 }
1183
1184 return collection;
1185 }
1186
1187 /// <summary>
1188 /// Rehydrates a page collection holding <see cref="RunStep"/> instances from a page token.
1189 /// </summary>
1190 /// <param name="firstPageToken"> Page token corresponding to the first page of the collection to rehydrate. </param>
1191 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
1192 /// <returns> A collection of <see cref="RunStep"/>. </returns>
1193 public virtual CollectionResult<RunStep> GetRunSteps(
1194 ContinuationToken firstPageToken,
1195 CancellationToken cancellationToken = default)
1196 {
1197 Argument.AssertNotNull(firstPageToken, nameof(firstPageToken));
1198
1199 RunStepCollectionPageToken pageToken = RunStepCollectionPageToken.FromToken(firstPageToken);
1200 CollectionResult result = GetRunSteps(pageToken?.ThreadId, pageToken?.RunId, pageToken?.Limit, pageToken?.Order, pageToken?.After, pageToken?.Before, cancellationToken.ToRequestOptions());
1201
1202 if (result is not CollectionResult<RunStep> collection)
1203 {
1204 throw new InvalidOperationException("Failed to cast protocol return type to expected collection type 'CollectionResult<RunStep>'.");
1205 }
1206
1207 return collection;
1208 }
1209
1210 /// <summary>
1211 /// Gets a single run step from a run.
1212 /// </summary>
1213 /// <param name="threadId"> The ID of the thread associated with the run. </param>
1214 /// <param name="runId"> The ID of the run. </param>
1215 /// <param name="stepId"> The ID of the run step. </param>
1216 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
1217 /// <returns> A <see cref="RunStep"/> instance corresponding to the specified step. </returns>
1218 public virtual async Task<ClientResult<RunStep>> GetRunStepAsync(string threadId, string runId, string stepId, CancellationToken cancellationToken = default)
1219 {
1220 ClientResult protocolResult = await GetRunStepAsync(threadId, runId, stepId, cancellationToken.ToRequestOptions()).ConfigureAwait(false);
1221 return ClientResult.FromValue(RunStep.FromClientResult(protocolResult), protocolResult.GetRawResponse());
1222 }
1223
1224 /// <summary>
1225 /// Gets a single run step from a run.
1226 /// </summary>
1227 /// <param name="threadId"> The ID of the thread associated with the run. </param>
1228 /// <param name="runId"> The ID of the run. </param>
1229 /// <param name="stepId"> The ID of the run step. </param>
1230 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
1231 /// <returns> A <see cref="RunStep"/> instance corresponding to the specified step. </returns>
1232 public virtual ClientResult<RunStep> GetRunStep(string threadId, string runId, string stepId, CancellationToken cancellationToken = default)
1233 {
1234 ClientResult protocolResult = GetRunStep(threadId, runId, stepId, cancellationToken.ToRequestOptions());
1235 return ClientResult.FromValue(RunStep.FromClientResult(protocolResult), protocolResult.GetRawResponse());
1236 }
1237
1238 private static BinaryContent CreateThreadAndRunProtocolContent(
1239 string assistantId,
1240 ThreadCreationOptions threadOptions,
1241 RunCreationOptions runOptions)
1242 {
1243 Argument.AssertNotNullOrEmpty(assistantId, nameof(assistantId));
1244 InternalCreateThreadAndRunRequest internalRequest = new(
1245 assistantId,
1246 threadOptions,
1247 runOptions.InstructionsOverride,
1248 runOptions.ToolsOverride,
1249 runOptions.Metadata,
1250 runOptions.Temperature,
1251 // TODO: reconcile exposure of the the two different tool_resources, if needed
1252 runOptions.NucleusSamplingFactor,
1253 runOptions.Stream,
1254 runOptions.MaxInputTokenCount,
1255 runOptions.MaxOutputTokenCount,
1256 runOptions.TruncationStrategy,
1257 runOptions.AllowParallelToolCalls,
1258 runOptions.ModelOverride,
1259 threadOptions.ToolResources,
1260 runOptions.ResponseFormat,
1261 runOptions.ToolConstraint,
1262 additionalBinaryDataProperties: null);
1263 return BinaryContent.Create(internalRequest, ModelSerializationExtensions.WireOptions);
1264 }
1265
1266 [MethodImpl(MethodImplOptions.AggressiveInlining)]
1267 private static ClientResult<T> CreateResultFromProtocol<T>(ClientResult protocolResult, Func<PipelineResponse, T> responseDeserializer)
1268 {
1269 PipelineResponse pipelineResponse = protocolResult?.GetRawResponse();
1270 T deserializedResultValue = responseDeserializer.Invoke(pipelineResponse);
1271 return ClientResult.FromValue(deserializedResultValue, pipelineResponse);
1272 }
1273}
1274