-
Notifications
You must be signed in to change notification settings - Fork 3.6k
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
.Net: Missing CancellationToken
in InvokePromptAsync<T>(...)
#4573
Comments
I’m eager to take on this issue and make my first contribution to SK. |
Ugh, that's an oversight, it should have had one. @matthewbolanos, @markwallace-microsoft, here's a small test of our non-breaking-change will: it's a binary breaking change to add a CancellationToken argument to the existing method, even as an optional parameter (it's not source breaking because existing callers would successfully recompile and just get the optional default value, but existing binaries calling the old method would start getting MethodNotFoundExceptions when targeting a newer version that only includes the new signature). So the right answer if we do care about that, which I think we do, is to add a new overload, even though it looks inconsistent. And adding new overloads of methods with optional parameters is a little tricky, because if you just add another identical method but with an extra optional parameter, it's source breaking because existing callers will start to get ambiguity errors, with the compiler not knowing which method to pick if there's not an exact match (i.e. if you were passing all arguments). The answer is basically change the existing method to not have any optional arguments (removing the default value from all parameters), and then add a new overload with everything that was optional still optional plus the new optional method. @bartonjs, do we have the canonical steps for this written down somewhere? |
CancellationToken
in InvokePromptAsync<T>(...)
CancellationToken
in InvokePromptAsync<T>(...)
@mehrandvd We would be very happy for you to take this. Please link your PR to this issue and I'll look out for it. Thanks. |
@stephentoub As I understood, this task is not simply adding a public static Task<T?> InvokePromptAsync<T>(
this Kernel kernel,
string promptTemplate,
KernelArguments? arguments,
string? templateFormat,
IPromptTemplateFactory? promptTemplateFactory) and then add a new overload with everything optional still optional plus the new optional method like: public static Task<T?> InvokePromptAsync<T>(
this Kernel kernel,
string promptTemplate,
KernelArguments? arguments = null,
string? templateFormat = null,
IPromptTemplateFactory? promptTemplateFactory = null,
CancellationToken cancellationToken = default) Am I right? |
That's correct, with the existing method then delegating to the new one that has the implementation. |
Framework Design Guidelines 3rd edition, section 5.1.1, p147 in the print edition, under: "DO move all default parameters to the new, longer overload when adding optional parameters to an existing method." But I think y'all have the gist here; the only thing missing is to consider adding With all of our guidelines stacked up, I'd expect public static Task<T?> InvokePromptAsync<T>(
this Kernel kernel,
string promptTemplate,
CancellationToken cancellationToken = default)
{
// feel free to specify them all, but this's enough to latch to the final one.
return InvokePromptAsync(kernel, promptTemplate, arguments: default, cancellationToken: cancellationToken);
}
[EditorBrowsable(EditorBrowsableState.Never)]
public static Task<T?> InvokePromptAsync<T>(
this Kernel kernel,
string promptTemplate,
KernelArguments? arguments,
string? templateFormat,
IPromptTemplateFactory? promptTemplateFactory)
{
return InvokePromptAsync(
kernel,
promptTemplate,
arguments,
templateFormat,
promptTemplateFactory,
default(CancellationToken));
}
public static Task<T?> InvokePromptAsync<T>(
this Kernel kernel,
string promptTemplate,
KernelArguments? arguments = null,
string? templateFormat = null,
IPromptTemplateFactory? promptTemplateFactory = null,
CancellationToken cancellationToken = default) { ... } and if there was already a (kernel, promptTemplate) overload for it to also get EB-Never'd in favor of the (kernel, promptTemplate, cancellationToken) one. |
@bartonjs Just to confirm, since there isn't a |
The first one comes from
combined with the guidance to always default a CancellationToken. It's not important for the "how do I add a new defaulted parameter without making a breaking change?" question, but it's something that "should" be there in the end. |
…4584) ### Motivation and Context KernelExtensions.InvokePromptAsync<T>(...) doesn't include a CancellationToken parameter mistakenly as described in #4573 Closes #4573 <!-- Thank you for your contribution to the semantic-kernel repo! Please help reviewers and future users, providing the following information: 1. Why is this change required? 2. What problem does it solve? 3. What scenario does it contribute to? 4. If it fixes an open issue, please link to the issue here. --> ### Description As @stephentoub mentioned in #4573, adding just a `cancellationToken` causes a _binary breaking change_. So, this method has two overloads, one with full optional parameters, and a second overload with no optional parameters at all. <!-- Describe your changes, the overall approach, the underlying design. These notes will help understanding how your code works. Thanks! --> ### Contribution Checklist <!-- Before submitting this PR, please make sure: --> - [x] The code builds clean without any errors or warnings - [x] The PR follows the [SK Contribution Guidelines](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md) and the [pre-submission formatting script](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md#development-scripts) raises no violations - [x] All unit tests pass, and I have added new tests where possible - [x] I didn't break anyone 😄
…ft#4573) (microsoft#4584) ### Motivation and Context KernelExtensions.InvokePromptAsync<T>(...) doesn't include a CancellationToken parameter mistakenly as described in microsoft#4573 Closes microsoft#4573 <!-- Thank you for your contribution to the semantic-kernel repo! Please help reviewers and future users, providing the following information: 1. Why is this change required? 2. What problem does it solve? 3. What scenario does it contribute to? 4. If it fixes an open issue, please link to the issue here. --> ### Description As @stephentoub mentioned in microsoft#4573, adding just a `cancellationToken` causes a _binary breaking change_. So, this method has two overloads, one with full optional parameters, and a second overload with no optional parameters at all. <!-- Describe your changes, the overall approach, the underlying design. These notes will help understanding how your code works. Thanks! --> ### Contribution Checklist <!-- Before submitting this PR, please make sure: --> - [x] The code builds clean without any errors or warnings - [x] The PR follows the [SK Contribution Guidelines](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md) and the [pre-submission formatting script](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md#development-scripts) raises no violations - [x] All unit tests pass, and I have added new tests where possible - [x] I didn't break anyone 😄
Describe the bug
In Semantic Kernel 1.0.1,
KernelExtensions.InvokePromptAsync<T>(...)
doesn't include aCancellationToken
parameter.To Reproduce
N/A
Expected behavior
Async methods should allow a
CancellationToken
to be passed in. The other extensions in this class do; it looks like this one was forgotten.The text was updated successfully, but these errors were encountered: