openai/openai-dotnet

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
mailinhphan/clientOptions

Branches

Tags

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

Clone

HTTPS

Download ZIP

OpenAI/src/Custom/Assistants/AssistantClient.cs

996lines · modecode

1using Microsoft.TypeSpec.Generator.Customizations;
2using System;
3using System.ClientModel;
4using System.ClientModel.Primitives;
5using System.Collections.Generic;
6using System.Diagnostics.CodeAnalysis;
7using System.Linq;
8using System.Runtime.CompilerServices;
9using System.Threading;
10using System.Threading.Tasks;
11
12namespace OpenAI.Assistants;
13
14/// <summary> The service client for OpenAI assistants operations. </summary>
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))]
25public partial class AssistantClient
26{
27 private readonly InternalAssistantMessageClient _messageSubClient;
28 private readonly InternalAssistantRunClient _runSubClient;
29 private readonly InternalAssistantThreadClient _threadSubClient;
30
31 // CUSTOM: Added as a convenience.
32 /// <summary> Initializes a new instance of <see cref="AssistantClient"/>. </summary>
33 /// <param name="apiKey"> The API key to authenticate with the service. </param>
34 /// <exception cref="ArgumentNullException"> <paramref name="apiKey"/> is null. </exception>
35 public AssistantClient(string apiKey) : this(new ApiKeyCredential(apiKey), new AssistantClientOptions())
36 {
37 }
38
39 // CUSTOM:
40 // - Used a custom pipeline.
41 // - Demoted the endpoint parameter to be a property in the options class.
42 /// <summary> Initializes a new instance of <see cref="AssistantClient"/>. </summary>
43 /// <param name="credential"> The <see cref="ApiKeyCredential"/> to authenticate with the service. </param>
44 /// <exception cref="ArgumentNullException"> <paramref name="credential"/> is null. </exception>
45 public AssistantClient(ApiKeyCredential credential) : this(credential, new AssistantClientOptions())
46 {
47 }
48
49 // CUSTOM:
50 // - Used a custom pipeline.
51 // - Demoted the endpoint parameter to be a property in the options class.
52 /// <summary> Initializes a new instance of <see cref="AssistantClient"/>. </summary>
53 /// <param name="credential"> The <see cref="ApiKeyCredential"/> to authenticate with the service. </param>
54 /// <param name="options"> The options to configure the client. </param>
55 /// <exception cref="ArgumentNullException"> <paramref name="credential"/> is null. </exception>
56 public AssistantClient(ApiKeyCredential credential, AssistantClientOptions options) : this(OpenAIClient.CreateApiKeyAuthenticationPolicy(credential), options)
57 {
58 }
59
60 // CUSTOM: Added as a convenience.
61 /// <summary> Initializes a new instance of <see cref="AssistantClient"/>. </summary>
62 /// <param name="authenticationPolicy"> The authentication policy used to authenticate with the service. </param>
63 /// <exception cref="ArgumentNullException"> <paramref name="authenticationPolicy"/> is null. </exception>
64 public AssistantClient(AuthenticationPolicy authenticationPolicy) : this(authenticationPolicy, new AssistantClientOptions())
65 {
66 }
67
68 // CUSTOM: Added as a convenience.
69 /// <summary> Initializes a new instance of <see cref="AssistantClient"/>. </summary>
70 /// <param name="authenticationPolicy"> The authentication policy used to authenticate with the service. </param>
71 /// <param name="options"> The options to configure the client. </param>
72 /// <exception cref="ArgumentNullException"> <paramref name="authenticationPolicy"/> is null. </exception>
73 public AssistantClient(AuthenticationPolicy authenticationPolicy, AssistantClientOptions options)
74 {
75 Argument.AssertNotNull(authenticationPolicy, nameof(authenticationPolicy));
76 options ??= new AssistantClientOptions();
77
78 Pipeline = OpenAIClientUtilities.CreatePipeline(authenticationPolicy, options, options.UserAgentApplicationId, options.OrganizationId, options.ProjectId);
79 _endpoint = OpenAIClientUtilities.GetEndpoint(options.Endpoint);
80 _messageSubClient = new(Pipeline, options);
81 _runSubClient = new(Pipeline, options);
82 _threadSubClient = new(Pipeline, options);
83 }
84
85 [Experimental("SCME0002")]
86 public AssistantClient(AssistantClientSettings settings)
87 : this(AuthenticationPolicy.Create(settings), settings?.Options)
88 {
89 }
90
91 /// <summary>
92 /// Gets the endpoint URI for the service.
93 /// </summary>
94 [Experimental("OPENAI001")]
95 public Uri Endpoint => _endpoint;
96
97
98 // CUSTOM:
99 // - Used a custom pipeline.
100 // - Demoted the endpoint parameter to be a property in the options class.
101 // - Made protected.
102 /// <summary> Initializes a new instance of <see cref="AssistantClient"/>. </summary>
103 /// <param name="pipeline"> The HTTP pipeline to send and receive REST requests and responses. </param>
104 /// <param name="options"> The options to configure the client. </param>
105 /// <exception cref="ArgumentNullException"> <paramref name="pipeline"/> is null. </exception>
106 protected internal AssistantClient(ClientPipeline pipeline, AssistantClientOptions options)
107 {
108 Argument.AssertNotNull(pipeline, nameof(pipeline));
109 options ??= new AssistantClientOptions();
110
111 Pipeline = pipeline;
112 _endpoint = OpenAIClientUtilities.GetEndpoint(options.Endpoint);
113 _messageSubClient = new(Pipeline, options);
114 _runSubClient = new(Pipeline, options);
115 _threadSubClient = new(Pipeline, options);
116 }
117
118 /// <summary> Creates a new assistant. </summary>
119 /// <param name="model"> The default model that the assistant should use. </param>
120 /// <param name="options"> The additional <see cref="AssistantCreationOptions"/> to use. </param>
121 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
122 /// <exception cref="ArgumentException"> <paramref name="model"/> is null or empty. </exception>
123 public virtual async Task<ClientResult<Assistant>> CreateAssistantAsync(string model, AssistantCreationOptions options = null, CancellationToken cancellationToken = default)
124 {
125 Argument.AssertNotNullOrEmpty(model, nameof(model));
126 options ??= new();
127 options.Model = model;
128
129 ClientResult protocolResult = await CreateAssistantAsync(options?.ToBinaryContent(), cancellationToken.ToRequestOptions()).ConfigureAwait(false);
130 return ClientResult.FromValue((Assistant)protocolResult, protocolResult.GetRawResponse());
131 }
132
133 /// <summary> Creates a new assistant. </summary>
134 /// <param name="model"> The default model that the assistant should use. </param>
135 /// <param name="options"> The additional <see cref="AssistantCreationOptions"/> to use. </param>
136 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
137 /// <exception cref="ArgumentException"> <paramref name="model"/> is null or empty. </exception>
138 public virtual ClientResult<Assistant> CreateAssistant(string model, AssistantCreationOptions options = null, CancellationToken cancellationToken = default)
139 {
140 Argument.AssertNotNullOrEmpty(model, nameof(model));
141 options ??= new();
142 options.Model = model;
143
144 ClientResult protocolResult = CreateAssistant(options?.ToBinaryContent(), cancellationToken.ToRequestOptions());
145 return ClientResult.FromValue((Assistant)protocolResult, protocolResult.GetRawResponse());
146 }
147
148 /// <summary>
149 /// Gets an instance representing an existing <see cref="Assistant"/> based on its ID.
150 /// </summary>
151 /// <param name="assistantId"> The ID of the Assistant to retrieve. </param>
152 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
153 /// <returns>An <see cref="Assistant"/> instance representing the state of the Assistant with the provided ID.</returns>
154 public virtual async Task<ClientResult<Assistant>> GetAssistantAsync(string assistantId, CancellationToken cancellationToken = default)
155 {
156 Argument.AssertNotNullOrEmpty(assistantId, nameof(assistantId));
157
158 ClientResult protocolResult = await GetAssistantAsync(assistantId, cancellationToken.ToRequestOptions()).ConfigureAwait(false);
159 return ClientResult.FromValue((Assistant)protocolResult, protocolResult.GetRawResponse());
160 }
161
162 /// <summary>
163 /// Gets an instance representing an existing <see cref="Assistant"/> based on its ID.
164 /// </summary>
165 /// <param name="assistantId"> The ID of the Assistant to retrieve. </param>
166 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
167 /// <returns>An <see cref="Assistant"/> instance representing the state of the Assistant with the provided ID.</returns>
168 public virtual ClientResult<Assistant> GetAssistant(string assistantId, CancellationToken cancellationToken = default)
169 {
170 Argument.AssertNotNullOrEmpty(assistantId, nameof(assistantId));
171
172 ClientResult protocolResult = GetAssistant(assistantId, cancellationToken.ToRequestOptions());
173 return ClientResult.FromValue((Assistant)protocolResult, protocolResult.GetRawResponse());
174 }
175
176 /// <summary>
177 /// Modifies an existing <see cref="Assistant"/>.
178 /// </summary>
179 /// <param name="assistantId"> The ID of the Assistant to retrieve. </param>
180 /// <param name="options"> The new options to apply to the existing Assistant. </param>
181 /// <param name="cancellationToken"> A token that can be used to cancel this method call. </param>
182 /// <returns> An updated <see cref="Assistant"/> instance representing the state of the Assistant with the provided ID. </returns>
183 public virtual async Task<ClientResult<Assistant>> ModifyAssistantAsync(string assistantId, AssistantModificationOptions options, CancellationToken cancellationToken = default)
184 {
185 Argument.AssertNotNullOrEmpty(assistantId, nameof(assistantId));
186 Argument.AssertNotNull(options, nameof(options));
187
188 using BinaryContent content = options?.ToBinaryContent();
189 ClientResult protocolResult
190 = await ModifyAssistantAsync(assistantId, content, cancellationToken.ToRequestOptions()).ConfigureAwait(false);
191 return ClientResult.FromValue((Assistant)protocolResult, protocolResult.GetRawResponse());
192 }
193
194 /// <summary>
195 /// Modifies an existing <see cref="Assistant"/>.
196 /// </summary>
197 /// <param name="assistantId"> The ID of the Assistant to retrieve. </param>
198 /// <param name="options"> The new options to apply to the existing Assistant. </param>
199 /// <param name="cancellationToken"> A token that can be used to cancel this method call. </param>
200 /// <returns> An updated <see cref="Assistant"/> instance representing the state of the Assistant with the provided ID. </returns>
201 public virtual ClientResult<Assistant> ModifyAssistant(string assistantId, AssistantModificationOptions options, CancellationToken cancellationToken = default)
202 {
203 Argument.AssertNotNullOrEmpty(assistantId, nameof(assistantId));
204 Argument.AssertNotNull(options, nameof(options));
205
206 using BinaryContent content = options?.ToBinaryContent();
207 ClientResult protocolResult = ModifyAssistant(assistantId, content, null);
208 return ClientResult.FromValue((Assistant)protocolResult, protocolResult.GetRawResponse());
209 }
210
211 /// <summary>
212 /// Deletes an existing <see cref="Assistant"/>.
213 /// </summary>
214 /// <param name="assistantId"> The ID of the assistant to delete. </param>
215 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
216 /// <returns> A <see cref="AssistantDeletionResult"/> instance. </returns>
217 public virtual async Task<ClientResult<AssistantDeletionResult>> DeleteAssistantAsync(string assistantId, CancellationToken cancellationToken = default)
218 {
219 Argument.AssertNotNullOrEmpty(assistantId, nameof(assistantId));
220
221 ClientResult protocolResult = await DeleteAssistantAsync(assistantId, cancellationToken.ToRequestOptions()).ConfigureAwait(false);
222 return ClientResult.FromValue((AssistantDeletionResult)protocolResult, protocolResult.GetRawResponse());
223 }
224
225 /// <summary>
226 /// Deletes an existing <see cref="Assistant"/>.
227 /// </summary>
228 /// <param name="assistantId"> The ID of the assistant to delete. </param>
229 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
230 /// <returns> A <see cref="AssistantDeletionResult"/> instance. </returns>
231 public virtual ClientResult<AssistantDeletionResult> DeleteAssistant(string assistantId, CancellationToken cancellationToken = default)
232 {
233 Argument.AssertNotNullOrEmpty(assistantId, nameof(assistantId));
234
235 ClientResult protocolResult = DeleteAssistant(assistantId, cancellationToken.ToRequestOptions());
236 return ClientResult.FromValue((AssistantDeletionResult)protocolResult, protocolResult.GetRawResponse());
237 }
238
239 /// <summary>
240 /// Creates a new <see cref="AssistantThread"/>.
241 /// </summary>
242 /// <param name="options"> Additional options to use when creating the thread. </param>
243 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
244 /// <returns> A new thread. </returns>
245 public virtual async Task<ClientResult<AssistantThread>> CreateThreadAsync(ThreadCreationOptions options = null, CancellationToken cancellationToken = default)
246 {
247 ClientResult protocolResult = await CreateThreadAsync(options?.ToBinaryContent(), cancellationToken.ToRequestOptions()).ConfigureAwait(false);
248 return ClientResult.FromValue((AssistantThread)protocolResult, protocolResult.GetRawResponse());
249 }
250
251 /// <summary>
252 /// Creates a new <see cref="AssistantThread"/>.
253 /// </summary>
254 /// <param name="options"> Additional options to use when creating the thread. </param>
255 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
256 /// <returns> A new thread. </returns>
257 public virtual ClientResult<AssistantThread> CreateThread(ThreadCreationOptions options = null, CancellationToken cancellationToken = default)
258 {
259 ClientResult protocolResult = CreateThread(options?.ToBinaryContent(), cancellationToken.ToRequestOptions());
260 return ClientResult.FromValue((AssistantThread)protocolResult, protocolResult.GetRawResponse());
261 }
262
263 /// <summary>
264 /// Gets an existing <see cref="AssistantThread"/>, retrieved via a known ID.
265 /// </summary>
266 /// <param name="threadId"> The ID of the thread to retrieve. </param>
267 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
268 /// <returns> The existing thread instance. </returns>
269 public virtual async Task<ClientResult<AssistantThread>> GetThreadAsync(string threadId, CancellationToken cancellationToken = default)
270 {
271 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
272
273 ClientResult protocolResult = await GetThreadAsync(threadId, cancellationToken.ToRequestOptions()).ConfigureAwait(false);
274 return ClientResult.FromValue((AssistantThread)protocolResult, protocolResult.GetRawResponse());
275 }
276
277 /// <summary>
278 /// Gets an existing <see cref="AssistantThread"/>, retrieved via a known ID.
279 /// </summary>
280 /// <param name="threadId"> The ID of the thread to retrieve. </param>
281 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
282 /// <returns> The existing thread instance. </returns>
283 public virtual ClientResult<AssistantThread> GetThread(string threadId, CancellationToken cancellationToken = default)
284 {
285 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
286
287 ClientResult protocolResult = GetThread(threadId, cancellationToken.ToRequestOptions());
288 return ClientResult.FromValue((AssistantThread)protocolResult, protocolResult.GetRawResponse());
289 }
290
291 /// <summary>
292 /// Modifies an existing <see cref="AssistantThread"/>.
293 /// </summary>
294 /// <param name="threadId"> The ID of the thread to modify. </param>
295 /// <param name="options"> The modifications to apply to the thread. </param>
296 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
297 /// <returns> The updated <see cref="AssistantThread"/> instance. </returns>
298 public virtual async Task<ClientResult<AssistantThread>> ModifyThreadAsync(string threadId, ThreadModificationOptions options, CancellationToken cancellationToken = default)
299 {
300 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
301 Argument.AssertNotNull(options, nameof(options));
302
303 ClientResult protocolResult = await ModifyThreadAsync(threadId, options?.ToBinaryContent(), cancellationToken.ToRequestOptions()).ConfigureAwait(false);
304 return ClientResult.FromValue((AssistantThread)protocolResult, protocolResult.GetRawResponse());
305 }
306
307 /// <summary>
308 /// Modifies an existing <see cref="AssistantThread"/>.
309 /// </summary>
310 /// <param name="threadId"> The ID of the thread to modify. </param>
311 /// <param name="options"> The modifications to apply to the thread. </param>
312 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
313 /// <returns> The updated <see cref="AssistantThread"/> instance. </returns>
314 public virtual ClientResult<AssistantThread> ModifyThread(string threadId, ThreadModificationOptions options, CancellationToken cancellationToken = default)
315 {
316 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
317 Argument.AssertNotNull(options, nameof(options));
318
319 ClientResult protocolResult = ModifyThread(threadId, options?.ToBinaryContent(), cancellationToken.ToRequestOptions());
320 return ClientResult.FromValue((AssistantThread)protocolResult, protocolResult.GetRawResponse());
321 }
322
323 /// <summary>
324 /// Deletes an existing <see cref="AssistantThread"/>.
325 /// </summary>
326 /// <param name="threadId"> The ID of the thread to delete. </param>
327 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
328 /// <returns> A <see cref="ThreadDeletionResult"/> instance. </returns>
329 public virtual async Task<ClientResult<ThreadDeletionResult>> DeleteThreadAsync(string threadId, CancellationToken cancellationToken = default)
330 {
331 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
332
333 ClientResult protocolResult = await DeleteThreadAsync(threadId, cancellationToken.ToRequestOptions()).ConfigureAwait(false);
334 return ClientResult.FromValue((ThreadDeletionResult)protocolResult, protocolResult.GetRawResponse());
335 }
336
337 /// <summary>
338 /// Deletes an existing <see cref="AssistantThread"/>.
339 /// </summary>
340 /// <param name="threadId"> The ID of the thread to delete. </param>
341 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
342 /// <returns> A <see cref="ThreadDeletionResult"/> instance. </returns>
343 public virtual ClientResult<ThreadDeletionResult> DeleteThread(string threadId, CancellationToken cancellationToken = default)
344 {
345 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
346
347 ClientResult protocolResult = DeleteThread(threadId, cancellationToken.ToRequestOptions());
348 return ClientResult.FromValue((ThreadDeletionResult)protocolResult, protocolResult.GetRawResponse());
349 }
350
351 /// <summary>
352 /// Creates a new <see cref="ThreadMessage"/> on an existing <see cref="AssistantThread"/>.
353 /// </summary>
354 /// <param name="threadId"> The ID of the thread to associate the new message with. </param>
355 /// <param name="role"> The role to associate with the new message. </param>
356 /// <param name="content"> The collection of <see cref="MessageContent"/> items for the message. </param>
357 /// <param name="options"> Additional options to apply to the new message. </param>
358 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
359 /// <returns> A new <see cref="ThreadMessage"/>. </returns>
360 public virtual async Task<ClientResult<ThreadMessage>> CreateMessageAsync(
361 string threadId,
362 MessageRole role,
363 IEnumerable<MessageContent> content,
364 MessageCreationOptions options = null,
365 CancellationToken cancellationToken = default)
366 {
367 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
368 options ??= new();
369 options.Role = role;
370 options.Content.Clear();
371 foreach (MessageContent contentItem in content)
372 {
373 options.Content.Add(contentItem);
374 }
375
376 ClientResult protocolResult = await CreateMessageAsync(threadId, options?.ToBinaryContent(), cancellationToken.ToRequestOptions())
377 .ConfigureAwait(false);
378 return ClientResult.FromValue((ThreadMessage)protocolResult, protocolResult.GetRawResponse());
379 }
380
381 /// <summary>
382 /// Creates a new <see cref="ThreadMessage"/> on an existing <see cref="AssistantThread"/>.
383 /// </summary>
384 /// <param name="threadId"> The ID of the thread to associate the new message with. </param>
385 /// <param name="role"> The role to associate with the new message. </param>
386 /// <param name="content"> The collection of <see cref="MessageContent"/> items for the message. </param>
387 /// <param name="options"> Additional options to apply to the new message. </param>
388 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
389 /// <returns> A new <see cref="ThreadMessage"/>. </returns>
390 public virtual ClientResult<ThreadMessage> CreateMessage(
391 string threadId,
392 MessageRole role,
393 IEnumerable<MessageContent> content,
394 MessageCreationOptions options = null,
395 CancellationToken cancellationToken = default)
396 {
397 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
398 options ??= new();
399 options.Role = role;
400 options.Content.Clear();
401 foreach (MessageContent contentItem in content)
402 {
403 options.Content.Add(contentItem);
404 }
405
406 ClientResult protocolResult = CreateMessage(threadId, options?.ToBinaryContent(), cancellationToken.ToRequestOptions());
407 return ClientResult.FromValue((ThreadMessage)protocolResult, protocolResult.GetRawResponse());
408 }
409
410 /// <summary>
411 /// Gets a page collection of <see cref="ThreadMessage"/> instances from an existing <see cref="AssistantThread"/>.
412 /// </summary>
413 /// <param name="threadId"> The ID of the thread to list messages from. </param>
414 /// <param name="options"> Options describing the collection to return. </param>
415 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
416 /// <returns> A collection of <see cref="ThreadMessage"/>. </returns>
417 public virtual AsyncCollectionResult<ThreadMessage> GetMessagesAsync(
418 string threadId,
419 MessageCollectionOptions options = default,
420 CancellationToken cancellationToken = default)
421 => _messageSubClient.GetMessagesAsync(threadId, options, cancellationToken);
422
423 /// <summary>
424 /// Gets a page collection holding <see cref="ThreadMessage"/> instances from an existing <see cref="AssistantThread"/>.
425 /// </summary>
426 /// <param name="threadId"> The ID of the thread to list messages from. </param>
427 /// <param name="options"> Options describing the collection to return. </param>
428 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
429 /// <returns> A collection of <see cref="ThreadMessage"/>. </returns>
430 public virtual CollectionResult<ThreadMessage> GetMessages(
431 string threadId,
432 MessageCollectionOptions options = default,
433 CancellationToken cancellationToken = default)
434 => _messageSubClient.GetMessages(threadId, options, cancellationToken);
435
436 /// <summary>
437 /// Gets an existing <see cref="ThreadMessage"/> from a known <see cref="AssistantThread"/>.
438 /// </summary>
439 /// <param name="threadId"> The ID of the thread to retrieve the message from. </param>
440 /// <param name="messageId"> The ID of the message to retrieve. </param>
441 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
442 /// <returns> The existing <see cref="ThreadMessage"/> instance. </returns>
443 public virtual async Task<ClientResult<ThreadMessage>> GetMessageAsync(string threadId, string messageId, CancellationToken cancellationToken = default)
444 {
445 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
446 Argument.AssertNotNullOrEmpty(messageId, nameof(messageId));
447
448 ClientResult protocolResult = await GetMessageAsync(threadId, messageId, cancellationToken.ToRequestOptions()).ConfigureAwait(false);
449 return ClientResult.FromValue((ThreadMessage)protocolResult, protocolResult.GetRawResponse());
450 }
451
452 /// <summary>
453 /// Gets an existing <see cref="ThreadMessage"/> from a known <see cref="AssistantThread"/>.
454 /// </summary>
455 /// <param name="threadId"> The ID of the thread to retrieve the message from. </param>
456 /// <param name="messageId"> The ID of the message to retrieve. </param>
457 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
458 /// <returns> The existing <see cref="ThreadMessage"/> instance. </returns>
459 public virtual ClientResult<ThreadMessage> GetMessage(string threadId, string messageId, CancellationToken cancellationToken = default)
460 {
461 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
462 Argument.AssertNotNullOrEmpty(messageId, nameof(messageId));
463
464 ClientResult protocolResult = GetMessage(threadId, messageId, cancellationToken.ToRequestOptions());
465 return ClientResult.FromValue((ThreadMessage)protocolResult, protocolResult.GetRawResponse());
466 }
467
468 /// <summary>
469 /// Modifies an existing <see cref="ThreadMessage"/>.
470 /// </summary>
471 /// <param name="threadId"> The ID of the thread associated with the message to modify. </param>
472 /// <param name="messageId"> The ID of the message to modify. </param>
473 /// <param name="options"> The changes to apply to the message. </param>
474 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
475 /// <returns> The updated <see cref="ThreadMessage"/>. </returns>
476 public virtual async Task<ClientResult<ThreadMessage>> ModifyMessageAsync(string threadId, string messageId, MessageModificationOptions options, CancellationToken cancellationToken = default)
477 {
478 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
479 Argument.AssertNotNullOrEmpty(messageId, nameof(messageId));
480 Argument.AssertNotNull(options, nameof(options));
481
482 ClientResult protocolResult = await ModifyMessageAsync(threadId, messageId, options?.ToBinaryContent(), cancellationToken.ToRequestOptions())
483 .ConfigureAwait(false);
484 return ClientResult.FromValue((ThreadMessage)protocolResult, protocolResult.GetRawResponse());
485 }
486
487 /// <summary>
488 /// Modifies an existing <see cref="ThreadMessage"/>.
489 /// </summary>
490 /// <param name="threadId"> The ID of the thread associated with the message to modify. </param>
491 /// <param name="messageId"> The ID of the message to modify. </param>
492 /// <param name="options"> The changes to apply to the message. </param>
493 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
494 /// <returns> The updated <see cref="ThreadMessage"/>. </returns>
495 public virtual ClientResult<ThreadMessage> ModifyMessage(string threadId, string messageId, MessageModificationOptions options, CancellationToken cancellationToken = default)
496 {
497 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
498 Argument.AssertNotNullOrEmpty(messageId, nameof(messageId));
499 Argument.AssertNotNull(options, nameof(options));
500
501 ClientResult protocolResult = ModifyMessage(threadId, messageId, options?.ToBinaryContent(), cancellationToken.ToRequestOptions());
502 return ClientResult.FromValue((ThreadMessage)protocolResult, protocolResult.GetRawResponse());
503 }
504
505 /// <summary>
506 /// Deletes an existing <see cref="ThreadMessage"/>.
507 /// </summary>
508 /// <param name="threadId"> The ID of the thread associated with the message. </param>
509 /// <param name="messageId"> The ID of the message. </param>
510 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
511 /// <returns> A <see cref="MessageDeletionResult"/> instance. </returns>
512 public virtual async Task<ClientResult<MessageDeletionResult>> DeleteMessageAsync(string threadId, string messageId, CancellationToken cancellationToken = default)
513 {
514 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
515 Argument.AssertNotNullOrEmpty(messageId, nameof(messageId));
516
517 ClientResult protocolResult = await DeleteMessageAsync(threadId, messageId, cancellationToken.ToRequestOptions()).ConfigureAwait(false);
518 return ClientResult.FromValue((MessageDeletionResult)protocolResult, protocolResult.GetRawResponse());
519 }
520
521 /// <summary>
522 /// Deletes an existing <see cref="ThreadMessage"/>.
523 /// </summary>
524 /// <param name="threadId"> The ID of the thread associated with the message. </param>
525 /// <param name="messageId"> The ID of the message. </param>
526 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
527 /// <returns> A <see cref="MessageDeletionResult"/> instance. </returns>
528 public virtual ClientResult<MessageDeletionResult> DeleteMessage(string threadId, string messageId, CancellationToken cancellationToken = default)
529 {
530 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
531 Argument.AssertNotNullOrEmpty(messageId, nameof(messageId));
532
533 ClientResult protocolResult = DeleteMessage(threadId, messageId, cancellationToken.ToRequestOptions());
534 return ClientResult.FromValue((MessageDeletionResult)protocolResult, protocolResult.GetRawResponse());
535 }
536
537 /// <summary>
538 /// Begins a new <see cref="ThreadRun"/> that evaluates a <see cref="AssistantThread"/> using a specified
539 /// <see cref="Assistant"/>.
540 /// </summary>
541 /// <param name="threadId"> The ID of the thread that the run should evaluate. </param>
542 /// <param name="assistantId"> The ID of the assistant that should be used when evaluating the thread. </param>
543 /// <param name="options"> Additional options for the run. </param>
544 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
545 /// <returns> A new <see cref="ThreadRun"/> instance. </returns>
546 public virtual async Task<ClientResult<ThreadRun>> CreateRunAsync(string threadId, string assistantId, RunCreationOptions options = null, CancellationToken cancellationToken = default)
547 {
548 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
549 Argument.AssertNotNullOrEmpty(assistantId, nameof(assistantId));
550 options ??= new();
551 options.AssistantId = assistantId;
552 options.Stream = null;
553
554 ClientResult protocolResult = await CreateRunAsync(threadId, options?.ToBinaryContent(), cancellationToken.ToRequestOptions())
555 .ConfigureAwait(false);
556 return ClientResult.FromValue((ThreadRun)protocolResult, protocolResult.GetRawResponse());
557 }
558
559 /// <summary>
560 /// Begins a new <see cref="ThreadRun"/> that evaluates a <see cref="AssistantThread"/> using a specified
561 /// <see cref="Assistant"/>.
562 /// </summary>
563 /// <param name="threadId"> The ID of the thread that the run should evaluate. </param>
564 /// <param name="assistantId"> The ID of the assistant that should be used when evaluating the thread. </param>
565 /// <param name="options"> Additional options for the run. </param>
566 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
567 /// <returns> A new <see cref="ThreadRun"/> instance. </returns>
568 public virtual ClientResult<ThreadRun> CreateRun(string threadId, string assistantId, RunCreationOptions options = null, CancellationToken cancellationToken = default)
569 {
570 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
571 Argument.AssertNotNullOrEmpty(assistantId, nameof(assistantId));
572 options ??= new();
573 options.AssistantId = assistantId;
574 options.Stream = null;
575
576 ClientResult protocolResult = CreateRun(threadId, options?.ToBinaryContent(), cancellationToken.ToRequestOptions());
577 return ClientResult.FromValue((ThreadRun)protocolResult, protocolResult.GetRawResponse());
578 }
579
580 /// <summary>
581 /// Begins a new streaming <see cref="ThreadRun"/> that evaluates a <see cref="AssistantThread"/> using a specified
582 /// <see cref="Assistant"/>.
583 /// </summary>
584 /// <param name="threadId"> The ID of the thread that the run should evaluate. </param>
585 /// <param name="assistantId"> The ID of the assistant that should be used when evaluating the thread. </param>
586 /// <param name="options"> Additional options for the run. </param>
587 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
588 public virtual AsyncCollectionResult<StreamingUpdate> CreateRunStreamingAsync(
589 string threadId,
590 string assistantId,
591 RunCreationOptions options = null,
592 CancellationToken cancellationToken = default)
593 {
594 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
595 Argument.AssertNotNullOrEmpty(assistantId, nameof(assistantId));
596
597 options ??= new();
598 options.AssistantId = assistantId;
599 options.Stream = true;
600
601 return new AsyncSseUpdateCollection<StreamingUpdate>(
602 async () => await CreateRunAsync(threadId, options?.ToBinaryContent(), cancellationToken.ToRequestOptions(streaming: true)).ConfigureAwait(false),
603 StreamingUpdate.FromSseItem,
604 cancellationToken);
605 }
606
607 /// <summary>
608 /// Begins a new streaming <see cref="ThreadRun"/> that evaluates a <see cref="AssistantThread"/> using a specified
609 /// <see cref="Assistant"/>.
610 /// </summary>
611 /// <param name="threadId"> The ID of the thread that the run should evaluate. </param>
612 /// <param name="assistantId"> The ID of the assistant that should be used when evaluating the thread. </param>
613 /// <param name="options"> Additional options for the run. </param>
614 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
615 public virtual CollectionResult<StreamingUpdate> CreateRunStreaming(
616 string threadId,
617 string assistantId,
618 RunCreationOptions options = null,
619 CancellationToken cancellationToken = default)
620 {
621 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
622 Argument.AssertNotNullOrEmpty(assistantId, nameof(assistantId));
623
624 options ??= new();
625 options.AssistantId = assistantId;
626 options.Stream = true;
627
628 return new SseUpdateCollection<StreamingUpdate>(
629 () => CreateRun(threadId, options?.ToBinaryContent(), cancellationToken.ToRequestOptions(streaming: true)),
630 StreamingUpdate.FromSseItem,
631 cancellationToken);
632 }
633
634 /// <summary>
635 /// Creates a new thread and immediately begins a run against it using the specified <see cref="Assistant"/>.
636 /// </summary>
637 /// <param name="assistantId"> The ID of the assistant that the new run should use. </param>
638 /// <param name="threadOptions"> Options for the new thread that will be created. </param>
639 /// <param name="runOptions"> Additional options to apply to the run that will begin. </param>
640 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
641 /// <returns> A new <see cref="ThreadRun"/>. </returns>
642 public virtual async Task<ClientResult<ThreadRun>> CreateThreadAndRunAsync(
643 string assistantId,
644 ThreadCreationOptions threadOptions = null,
645 RunCreationOptions runOptions = null,
646 CancellationToken cancellationToken = default)
647 {
648 runOptions ??= new();
649 runOptions.Stream = null;
650 BinaryContent protocolContent = CreateThreadAndRunProtocolContent(assistantId, threadOptions, runOptions);
651 ClientResult protocolResult = await CreateThreadAndRunAsync(protocolContent, cancellationToken.ToRequestOptions()).ConfigureAwait(false);
652 return ClientResult.FromValue((ThreadRun)protocolResult, protocolResult.GetRawResponse());
653 }
654
655 /// <summary>
656 /// Creates a new thread and immediately begins a run against it using the specified <see cref="Assistant"/>.
657 /// </summary>
658 /// <param name="assistantId"> The ID of the assistant that the new run should use. </param>
659 /// <param name="threadOptions"> Options for the new thread that will be created. </param>
660 /// <param name="runOptions"> Additional options to apply to the run that will begin. </param>
661 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
662 /// <returns> A new <see cref="ThreadRun"/>. </returns>
663 public virtual ClientResult<ThreadRun> CreateThreadAndRun(
664 string assistantId,
665 ThreadCreationOptions threadOptions = null,
666 RunCreationOptions runOptions = null,
667 CancellationToken cancellationToken = default)
668 {
669 runOptions ??= new();
670 runOptions.Stream = null;
671 BinaryContent protocolContent = CreateThreadAndRunProtocolContent(assistantId, threadOptions, runOptions);
672 ClientResult protocolResult = CreateThreadAndRun(protocolContent, cancellationToken.ToRequestOptions());
673 return ClientResult.FromValue((ThreadRun)protocolResult, protocolResult.GetRawResponse());
674 }
675
676 /// <summary>
677 /// Creates a new thread and immediately begins a streaming run against it using the specified <see cref="Assistant"/>.
678 /// </summary>
679 /// <param name="assistantId"> The ID of the assistant that the new run should use. </param>
680 /// <param name="threadOptions"> Options for the new thread that will be created. </param>
681 /// <param name="runOptions"> Additional options to apply to the run that will begin. </param>
682 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
683 public virtual AsyncCollectionResult<StreamingUpdate> CreateThreadAndRunStreamingAsync(
684 string assistantId,
685 ThreadCreationOptions threadOptions = null,
686 RunCreationOptions runOptions = null,
687 CancellationToken cancellationToken = default)
688 {
689 Argument.AssertNotNullOrEmpty(assistantId, nameof(assistantId));
690
691 runOptions ??= new();
692 runOptions.Stream = true;
693 BinaryContent protocolContent = CreateThreadAndRunProtocolContent(assistantId, threadOptions, runOptions);
694
695 return new AsyncSseUpdateCollection<StreamingUpdate>(
696 async () => await CreateThreadAndRunAsync(protocolContent, cancellationToken.ToRequestOptions(streaming: true)).ConfigureAwait(false),
697 StreamingUpdate.FromSseItem,
698 cancellationToken);
699 }
700
701 /// <summary>
702 /// Creates a new thread and immediately begins a streaming run against it using the specified <see cref="Assistant"/>.
703 /// </summary>
704 /// <param name="assistantId"> The ID of the assistant that the new run should use. </param>
705 /// <param name="threadOptions"> Options for the new thread that will be created. </param>
706 /// <param name="runOptions"> Additional options to apply to the run that will begin. </param>
707 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
708 public virtual CollectionResult<StreamingUpdate> CreateThreadAndRunStreaming(
709 string assistantId,
710 ThreadCreationOptions threadOptions = null,
711 RunCreationOptions runOptions = null,
712 CancellationToken cancellationToken = default)
713 {
714 Argument.AssertNotNullOrEmpty(assistantId, nameof(assistantId));
715
716 runOptions ??= new();
717 runOptions.Stream = true;
718 BinaryContent protocolContent = CreateThreadAndRunProtocolContent(assistantId, threadOptions, runOptions);
719
720 return new SseUpdateCollection<StreamingUpdate>(
721 () => CreateThreadAndRun(protocolContent, cancellationToken.ToRequestOptions(streaming: true)),
722 StreamingUpdate.FromSseItem,
723 cancellationToken);
724 }
725
726 /// <summary>
727 /// Gets a page collection holding <see cref="ThreadRun"/> instances associated with an existing <see cref="AssistantThread"/>.
728 /// </summary>
729 /// <param name="threadId"> The ID of the thread that runs in the list should be associated with. </param>
730 /// <param name="options"> Options describing the collection to return. </param>
731 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
732 /// <returns> A collection of <see cref="ThreadRun"/>. </returns>
733 public virtual AsyncCollectionResult<ThreadRun> GetRunsAsync(
734 string threadId,
735 RunCollectionOptions options = default,
736 CancellationToken cancellationToken = default)
737 => _runSubClient.GetRunsAsync(threadId, options, cancellationToken);
738
739 /// <summary>
740 /// Gets a page collection holding <see cref="ThreadRun"/> instances associated with an existing <see cref="AssistantThread"/>.
741 /// </summary>
742 /// <param name="threadId"> The ID of the thread that runs in the list should be associated with. </param>
743 /// <param name="options"> Options describing the collection to return. </param>
744 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
745 /// <returns> A collection of <see cref="ThreadRun"/>. </returns>
746 public virtual CollectionResult<ThreadRun> GetRuns(
747 string threadId,
748 RunCollectionOptions options = default,
749 CancellationToken cancellationToken = default)
750 => _runSubClient.GetRuns(threadId, options, cancellationToken);
751
752 /// <summary>
753 /// Gets an existing <see cref="ThreadRun"/> from a known <see cref="AssistantThread"/>.
754 /// </summary>
755 /// <param name="threadId"> The ID of the thread to retrieve the run from. </param>
756 /// <param name="runId"> The ID of the run to retrieve. </param>
757 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
758 /// <returns> The existing <see cref="ThreadRun"/> instance. </returns>
759 public virtual async Task<ClientResult<ThreadRun>> GetRunAsync(string threadId, string runId, CancellationToken cancellationToken = default)
760 => await _runSubClient.GetRunAsync(threadId, runId, cancellationToken);
761
762 /// <summary>
763 /// Gets an existing <see cref="ThreadRun"/> from a known <see cref="AssistantThread"/>.
764 /// </summary>
765 /// <param name="threadId"> The ID of the thread to retrieve the run from. </param>
766 /// <param name="runId"> The ID of the run to retrieve. </param>
767 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
768 /// <returns> The existing <see cref="ThreadRun"/> instance. </returns>
769 public virtual ClientResult<ThreadRun> GetRun(string threadId, string runId, CancellationToken cancellationToken = default)
770 => _runSubClient.GetRun(threadId, runId, cancellationToken);
771
772 /// <summary>
773 /// Submits a collection of required tool call outputs to a run and resumes the run.
774 /// </summary>
775 /// <param name="threadId"> The thread ID of the thread being run. </param>
776 /// <param name="runId"> The ID of the run that reached a <c>requires_action</c> status. </param>
777 /// <param name="toolOutputs">
778 /// The tool outputs, corresponding to <see cref="InternalRequiredToolCall"/> instances from the run.
779 /// </param>
780 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
781 /// <returns> The <see cref="ThreadRun"/>, updated after the submission was processed. </returns>
782 public virtual async Task<ClientResult<ThreadRun>> SubmitToolOutputsToRunAsync(
783 string threadId,
784 string runId,
785 IEnumerable<ToolOutput> toolOutputs,
786 CancellationToken cancellationToken = default)
787 {
788 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
789 Argument.AssertNotNullOrEmpty(runId, nameof(runId));
790
791 var submitToolOutputsRunRequest = new InternalSubmitToolOutputsRunRequest(toolOutputs);
792 using BinaryContent content = BinaryContent.Create(submitToolOutputsRunRequest, ModelSerializationExtensions.WireOptions);
793 ClientResult protocolResult = await SubmitToolOutputsToRunAsync(threadId, runId, content, cancellationToken.ToRequestOptions())
794 .ConfigureAwait(false);
795 return ClientResult.FromValue((ThreadRun)protocolResult, protocolResult.GetRawResponse());
796 }
797
798 /// <summary>
799 /// Submits a collection of required tool call outputs to a run and resumes the run.
800 /// </summary>
801 /// <param name="threadId"> The thread ID of the thread being run. </param>
802 /// <param name="runId"> The ID of the run that reached a <c>requires_action</c> status. </param>
803 /// <param name="toolOutputs">
804 /// The tool outputs, corresponding to <see cref="InternalRequiredToolCall"/> instances from the run.
805 /// </param>
806 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
807 /// <returns> The <see cref="ThreadRun"/>, updated after the submission was processed. </returns>
808 public virtual ClientResult<ThreadRun> SubmitToolOutputsToRun(
809 string threadId,
810 string runId,
811 IEnumerable<ToolOutput> toolOutputs,
812 CancellationToken cancellationToken = default)
813 {
814 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
815 Argument.AssertNotNullOrEmpty(runId, nameof(runId));
816
817 var submitToolOutputsRunRequest = new InternalSubmitToolOutputsRunRequest(toolOutputs);
818 using BinaryContent content = BinaryContent.Create(submitToolOutputsRunRequest, ModelSerializationExtensions.WireOptions);
819 ClientResult protocolResult = SubmitToolOutputsToRun(threadId, runId, content, cancellationToken.ToRequestOptions());
820 return ClientResult.FromValue((ThreadRun)protocolResult, protocolResult.GetRawResponse());
821 }
822
823 /// <summary>
824 /// Submits a collection of required tool call outputs to a run and resumes the run with streaming enabled.
825 /// </summary>
826 /// <param name="threadId"> The thread ID of the thread being run. </param>
827 /// <param name="runId"> The ID of the run that reached a <c>requires_action</c> status. </param>
828 /// <param name="toolOutputs">
829 /// The tool outputs, corresponding to <see cref="InternalRequiredToolCall"/> instances from the run.
830 /// </param>
831 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
832 public virtual AsyncCollectionResult<StreamingUpdate> SubmitToolOutputsToRunStreamingAsync(
833 string threadId,
834 string runId,
835 IEnumerable<ToolOutput> toolOutputs,
836 CancellationToken cancellationToken = default)
837 {
838 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
839 Argument.AssertNotNullOrEmpty(runId, nameof(runId));
840
841 var submitToolOutputsRunRequest = new InternalSubmitToolOutputsRunRequest(toolOutputs.ToList(), stream: true, null);
842 using BinaryContent content = BinaryContent.Create(submitToolOutputsRunRequest, ModelSerializationExtensions.WireOptions);
843
844 return new AsyncSseUpdateCollection<StreamingUpdate>(
845 async () => await SubmitToolOutputsToRunAsync(threadId, runId, content, cancellationToken.ToRequestOptions(streaming: true)).ConfigureAwait(false),
846 StreamingUpdate.FromSseItem,
847 cancellationToken);
848 }
849
850 /// <summary>
851 /// Submits a collection of required tool call outputs to a run and resumes the run with streaming enabled.
852 /// </summary>
853 /// <param name="threadId"> The thread ID of the thread being run. </param>
854 /// <param name="runId"> The ID of the run that reached a <c>requires_action</c> status. </param>
855 /// <param name="toolOutputs">
856 /// The tool outputs, corresponding to <see cref="InternalRequiredToolCall"/> instances from the run.
857 /// </param>
858 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
859 public virtual CollectionResult<StreamingUpdate> SubmitToolOutputsToRunStreaming(
860 string threadId,
861 string runId,
862 IEnumerable<ToolOutput> toolOutputs,
863 CancellationToken cancellationToken = default)
864 {
865 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
866 Argument.AssertNotNullOrEmpty(runId, nameof(runId));
867
868 var submitToolOutputsRunRequest = new InternalSubmitToolOutputsRunRequest(toolOutputs.ToList(), stream: true, null);
869 using BinaryContent content = BinaryContent.Create(submitToolOutputsRunRequest, ModelSerializationExtensions.WireOptions);
870
871 return new SseUpdateCollection<StreamingUpdate>(
872 () => SubmitToolOutputsToRun(threadId, runId, content, cancellationToken.ToRequestOptions(streaming: true)),
873 StreamingUpdate.FromSseItem,
874 cancellationToken);
875 }
876
877 /// <summary>
878 /// Cancels an in-progress <see cref="ThreadRun"/>.
879 /// </summary>
880 /// <param name="threadId"> The ID of the thread associated with the run. </param>
881 /// <param name="runId"> The ID of the run to cancel. </param>
882 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
883 /// <returns> An updated <see cref="ThreadRun"/> instance, reflecting the new status of the run. </returns>
884 public virtual async Task<ClientResult<ThreadRun>> CancelRunAsync(string threadId, string runId, CancellationToken cancellationToken = default)
885 {
886 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
887 Argument.AssertNotNullOrEmpty(runId, nameof(runId));
888
889 ClientResult protocolResult = await CancelRunAsync(threadId, runId, cancellationToken.ToRequestOptions()).ConfigureAwait(false);
890 return ClientResult.FromValue((ThreadRun)protocolResult, protocolResult.GetRawResponse());
891 }
892
893 /// <summary>
894 /// Cancels an in-progress <see cref="ThreadRun"/>.
895 /// </summary>
896 /// <param name="threadId"> The ID of the thread associated with the run. </param>
897 /// <param name="runId"> The ID of the run to cancel. </param>
898 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
899 /// <returns> An updated <see cref="ThreadRun"/> instance, reflecting the new status of the run. </returns>
900 public virtual ClientResult<ThreadRun> CancelRun(string threadId, string runId, CancellationToken cancellationToken = default)
901 {
902 Argument.AssertNotNullOrEmpty(threadId, nameof(threadId));
903 Argument.AssertNotNullOrEmpty(runId, nameof(runId));
904
905 ClientResult protocolResult = CancelRun(threadId, runId, cancellationToken.ToRequestOptions());
906 return ClientResult.FromValue((ThreadRun)protocolResult, protocolResult.GetRawResponse());
907 }
908
909 /// <summary>
910 /// Gets a page collection holding <see cref="RunStep"/> instances associated with a <see cref="ThreadRun"/>.
911 /// </summary>
912 /// <param name="threadId"> The ID of the thread associated with the run. </param>
913 /// <param name="runId"> The ID of the run to list run steps from. </param>
914 /// <param name="options"></param>
915 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
916 /// <returns> A collection of <see cref="RunStep"/>. </returns>
917 public virtual AsyncCollectionResult<RunStep> GetRunStepsAsync(
918 string threadId,
919 string runId,
920 RunStepCollectionOptions options = default,
921 CancellationToken cancellationToken = default)
922 => _runSubClient.GetRunStepsAsync(threadId, runId, options, [InternalIncludedRunStepProperty.FileSearchResultContent], cancellationToken);
923
924 /// <summary>
925 /// Gets a page collection holding <see cref="RunStep"/> instances associated with a <see cref="ThreadRun"/>.
926 /// </summary>
927 /// <param name="threadId"> The ID of the thread associated with the run. </param>
928 /// <param name="runId"> The ID of the run to list run steps from. </param>
929 /// <param name="options"></param>
930 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
931 /// <returns> A collection of <see cref="RunStep"/>. </returns>
932 public virtual CollectionResult<RunStep> GetRunSteps(
933 string threadId,
934 string runId,
935 RunStepCollectionOptions options = default,
936 CancellationToken cancellationToken = default)
937 => _runSubClient.GetRunSteps(threadId, runId, options, [InternalIncludedRunStepProperty.FileSearchResultContent], cancellationToken);
938
939 /// <summary>
940 /// Gets a single run step from a run.
941 /// </summary>
942 /// <param name="threadId"> The ID of the thread associated with the run. </param>
943 /// <param name="runId"> The ID of the run. </param>
944 /// <param name="stepId"> The ID of the run step. </param>
945 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
946 /// <returns> A <see cref="RunStep"/> instance corresponding to the specified step. </returns>
947 public virtual async Task<ClientResult<RunStep>> GetRunStepAsync(string threadId, string runId, string stepId, CancellationToken cancellationToken = default)
948 => await _runSubClient.GetRunStepAsync(threadId, runId, stepId, [InternalIncludedRunStepProperty.FileSearchResultContent], cancellationToken).ConfigureAwait(false);
949
950 /// <summary>
951 /// Gets a single run step from a run.
952 /// </summary>
953 /// <param name="threadId"> The ID of the thread associated with the run. </param>
954 /// <param name="runId"> The ID of the run. </param>
955 /// <param name="stepId"> The ID of the run step. </param>
956 /// <param name="cancellationToken">A token that can be used to cancel this method call.</param>
957 /// <returns> A <see cref="RunStep"/> instance corresponding to the specified step. </returns>
958 public virtual ClientResult<RunStep> GetRunStep(string threadId, string runId, string stepId, CancellationToken cancellationToken = default)
959 => _runSubClient.GetRunStep(threadId, runId, stepId, [InternalIncludedRunStepProperty.FileSearchResultContent], cancellationToken);
960
961 private static BinaryContent CreateThreadAndRunProtocolContent(
962 string assistantId,
963 ThreadCreationOptions threadOptions,
964 RunCreationOptions runOptions)
965 {
966 Argument.AssertNotNullOrEmpty(assistantId, nameof(assistantId));
967 InternalCreateThreadAndRunRequest internalRequest = new(
968 assistantId: assistantId,
969 thread: threadOptions,
970 instructions: runOptions.InstructionsOverride,
971 tools: runOptions.ToolsOverride,
972 metadata: runOptions.Metadata,
973 temperature: runOptions.Temperature,
974 // TODO: reconcile exposure of the two different tool_resources, if needed
975 topP: runOptions.NucleusSamplingFactor,
976 stream: runOptions.Stream,
977 maxPromptTokens: runOptions.MaxInputTokenCount,
978 maxCompletionTokens: runOptions.MaxOutputTokenCount,
979 truncationStrategy: runOptions.TruncationStrategy,
980 parallelToolCalls: runOptions.AllowParallelToolCalls,
981 model: runOptions.ModelOverride,
982 toolResources: threadOptions.ToolResources,
983 responseFormat: runOptions.ResponseFormat,
984 toolChoice: runOptions.ToolConstraint,
985 additionalBinaryDataProperties: null);
986 return BinaryContent.Create(internalRequest, ModelSerializationExtensions.WireOptions);
987 }
988
989 [MethodImpl(MethodImplOptions.AggressiveInlining)]
990 private static ClientResult<T> CreateResultFromProtocol<T>(ClientResult protocolResult, Func<PipelineResponse, T> responseDeserializer)
991 {
992 PipelineResponse pipelineResponse = protocolResult?.GetRawResponse();
993 T deserializedResultValue = responseDeserializer.Invoke(pipelineResponse);
994 return ClientResult.FromValue(deserializedResultValue, pipelineResponse);
995 }
996}
997