-
Notifications
You must be signed in to change notification settings - Fork 836
add support for background responses #6854
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
678a22a
f2afc33
61c4434
f41d7b2
09db9fc
a5b4967
25e610e
611d704
fba243b
51a4e6c
b1e1a9e
a384e94
30b4c0a
d68b4a4
21b04db
991789e
78eef28
090667e
100f6da
77832ea
b87472a
8cdd78f
0d6af71
da996e8
5d3b6d3
57ca6fd
8c931a4
8829e8d
c2fcc5a
f0543fd
3f4188d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
using System.Diagnostics.CodeAnalysis; | ||
|
||
namespace Microsoft.Extensions.AI; | ||
|
||
/// <summary>Options for configuring background responses.</summary> | ||
[Experimental("MEAI001")] | ||
public sealed class BackgroundResponsesOptions | ||
{ | ||
/// <summary>Gets or sets a value indicating whether the background responses are allowed.</summary> | ||
/// <remarks> | ||
/// <para> | ||
/// Background responses allow running long-running operations or tasks asynchronously in the background that can be resumed by streaming APIs | ||
/// and polled for completion by non-streaming APIs. | ||
/// </para> | ||
/// <para> | ||
/// When this property is set to true, non-streaming APIs start a background operation and return an initial | ||
/// response with a continuation token. Subsequent calls to the same API should be made in a polling manner with | ||
/// the continuation token to get the final result of the operation. | ||
/// </para> | ||
/// <para> | ||
/// When this property is set to true, streaming APIs also start a background operation and begin streaming | ||
/// response updates until the operation is completed. If the streaming connection is interrupted, the | ||
/// continuation token obtained from the last update should be supplied to a subsequent call to the same streaming API | ||
/// to resume the stream from the point of interruption and continue receiving updates until the operation is completed. | ||
/// </para> | ||
/// <para> | ||
/// This property only takes effect if the API it's used with supports background responses. | ||
/// If the API does not support background responses, this property will be ignored. | ||
/// </para> | ||
/// </remarks> | ||
SergeyMenshykh marked this conversation as resolved.
Show resolved
Hide resolved
|
||
public bool? Allow { get; set; } | ||
stephentoub marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} |
Original file line number | Diff line number | Diff line change | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -5,6 +5,11 @@ | |||||||||||
- Added protected copy constructors to options types (e.g. `ChatOptions`). | ||||||||||||
- Fixed `EmbeddingGeneratorOptions`/`SpeechToTextOptions` `Clone` methods to correctly copy all properties. | ||||||||||||
- Fixed `ToChatResponse` to not overwrite `ChatMessage/ChatResponse.CreatedAt` with older timestamps during coalescing. | ||||||||||||
- Added `[Experimental]` `ResponseContinuationToken` to represent a base class for continuation tokens. | ||||||||||||
- Added `[Experimental]` `BackgroundResponsesOptions` to represent options for background responses. | ||||||||||||
- Added `[Experimental]` `ChatOptions.BackgroundResponsesOptions` and `ChatOptions.ContinuationToken` properties to accept options for background responses and continuation token. | ||||||||||||
- Added `[Experimental]` `ChatResponse.ContinuationToken` and `ChatResponseUpdate.ContinuationToken` to return continuation token for background responses. | ||||||||||||
Comment on lines
+8
to
+11
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||
- Added `[Experimental]` `GetResponseAsync` and `GetStreamingResponseAsync` extension methods for `IChatClient` to continue background responses. | ||||||||||||
|
||||||||||||
## 9.9.1 | ||||||||||||
|
||||||||||||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -3,6 +3,7 @@ | |||||
|
||||||
using System; | ||||||
using System.Collections.Generic; | ||||||
using System.Diagnostics.CodeAnalysis; | ||||||
using System.Threading; | ||||||
using System.Threading.Tasks; | ||||||
using Microsoft.Shared.Diagnostics; | ||||||
|
@@ -120,6 +121,34 @@ public static Task<ChatResponse> GetResponseAsync( | |||||
return client.GetResponseAsync([chatMessage], options, cancellationToken); | ||||||
} | ||||||
|
||||||
/// <summary>Gets a background response identified by the specified continuation token.</summary> | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
/// <param name="client">The chat client.</param> | ||||||
/// <param name="continuationToken">The continuation token.</param> | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
/// <param name="options">The chat options to configure the request.</param> | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param> | ||||||
/// <returns>The background response.</returns> | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you elaborate on what "background response" means? And is it necessarily a "background" response? Does the abstraction contract say that a continuation token is only ever provided if AllowBackground is true? |
||||||
/// <remarks> | ||||||
/// The options provided should be the same as those used to start the background operation. | ||||||
/// Using different options is not supported and may lead to unexpected results. | ||||||
/// </remarks> | ||||||
/// <exception cref="ArgumentNullException"><paramref name="client"/> is <see langword="null"/>.</exception> | ||||||
/// <exception cref="ArgumentNullException"><paramref name="continuationToken"/> is <see langword="null"/>.</exception> | ||||||
[Experimental("MEAI001")] | ||||||
public static Task<ChatResponse> GetResponseAsync( | ||||||
this IChatClient client, | ||||||
ResponseContinuationToken continuationToken, | ||||||
ChatOptions? options = null, | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is the purpose of the options being accepted here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good question. We need to supply functions for subsequent calls if they were advertised in the initial call; otherwise, the called tools won't be found by FICC. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we add some remarks here to warn users that the options should match the original options, otherwise you may have unexpected results and any such action is not supported? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good idea - added. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The remarks should be more explicit about this. Even after reading the remarks, I didn't understand why this was necessary. |
||||||
CancellationToken cancellationToken = default) | ||||||
{ | ||||||
_ = Throw.IfNull(client); | ||||||
_ = Throw.IfNull(continuationToken); | ||||||
|
||||||
ChatOptions chatOptions = options?.Clone() ?? new(); | ||||||
chatOptions.ContinuationToken = continuationToken; | ||||||
SergeyMenshykh marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
||||||
return client.GetResponseAsync([], chatOptions, cancellationToken); | ||||||
} | ||||||
|
||||||
/// <summary>Sends a user chat text message and streams the response messages.</summary> | ||||||
/// <param name="client">The chat client.</param> | ||||||
/// <param name="chatMessage">The text content for the chat message to send.</param> | ||||||
|
@@ -159,4 +188,28 @@ public static IAsyncEnumerable<ChatResponseUpdate> GetStreamingResponseAsync( | |||||
|
||||||
return client.GetStreamingResponseAsync([chatMessage], options, cancellationToken); | ||||||
} | ||||||
|
||||||
/// <summary>Gets a background streamed response identified by the specified continuation token and streams its messages.</summary> | ||||||
/// <param name="client">The chat client.</param> | ||||||
/// <param name="continuationToken">The continuation token.</param> | ||||||
/// <param name="options">The chat options to configure the request.</param> | ||||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param> | ||||||
/// <returns>The background response messages.</returns> | ||||||
/// <exception cref="ArgumentNullException"><paramref name="client"/> is <see langword="null"/>.</exception> | ||||||
/// <exception cref="ArgumentNullException"><paramref name="continuationToken"/> is <see langword="null"/>.</exception> | ||||||
[Experimental("MEAI001")] | ||||||
public static IAsyncEnumerable<ChatResponseUpdate> GetStreamingResponseAsync( | ||||||
this IChatClient client, | ||||||
ResponseContinuationToken continuationToken, | ||||||
ChatOptions? options = null, | ||||||
CancellationToken cancellationToken = default) | ||||||
{ | ||||||
_ = Throw.IfNull(client); | ||||||
_ = Throw.IfNull(continuationToken); | ||||||
|
||||||
ChatOptions chatOptions = options?.Clone() ?? new(); | ||||||
chatOptions.ContinuationToken = continuationToken; | ||||||
|
||||||
return client.GetStreamingResponseAsync([], chatOptions, cancellationToken); | ||||||
} | ||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What were the other options again that we were thinking we may need to add here in future to justify a separate options object?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One that I can think of at the moment would be settings for polling if we ever decide to do internal polling. However, if we agree to offload polling responsibility to consumers, and if there are no other options we can think of, we can remove the class and go with the
bool? ChatOptions.AllowBackgroundResponses
property instead. That would simplify the API a little bit from:to
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's do that.