openai/openai-dotnet

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
OpenAI_2.3.0

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/Custom/Assistants/AssistantClient.cs

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