Skip to content

Commit bc3e294

Browse files
.Net: Use explicit arguments in TextSearch delegates to ensure type conversion (#10151)
### Motivation and Context Use explicit arguments in TextSearch delegates to ensure type conversion ### Description <!-- 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: --> - [ ] The code builds clean without any errors or warnings - [ ] 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 - [ ] All unit tests pass, and I have added new tests where possible - [ ] I didn't break anyone 😄 --------- Co-authored-by: SergeyMenshykh <[email protected]>
1 parent d06d230 commit bc3e294

File tree

2 files changed

+19
-43
lines changed

2 files changed

+19
-43
lines changed

dotnet/samples/Concepts/Search/Bing_FunctionCallingWithTextSearch.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public async Task FunctionCallingWithBingTextSearchAsync()
3636
// Invoke prompt and use text search plugin to provide grounding information
3737
OpenAIPromptExecutionSettings settings = new() { ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions };
3838
KernelArguments arguments = new(settings);
39-
Console.WriteLine(await kernel.InvokePromptAsync("What is the Semantic Kernel?", arguments));
39+
Console.WriteLine(await kernel.InvokePromptAsync("What is the Semantic Kernel? Search for 5 references.", arguments));
4040
}
4141

4242
/// <summary>

dotnet/src/SemanticKernel.Core/Data/TextSearch/TextSearchExtensions.cs

Lines changed: 18 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ public static KernelPlugin CreateWithGetSearchResults(this ITextSearch textSearc
155155
[RequiresDynamicCode("Uses reflection to handle various aspects of the function creation and invocation, making it incompatible with AOT scenarios.")]
156156
public static KernelFunction CreateSearch(this ITextSearch textSearch, KernelFunctionFromMethodOptions? options = null, TextSearchOptions? searchOptions = null)
157157
{
158-
async Task<IEnumerable<string>> SearchAsync(Kernel kernel, KernelFunction function, KernelArguments arguments, CancellationToken cancellationToken)
158+
async Task<IEnumerable<string>> SearchAsync(Kernel kernel, KernelFunction function, KernelArguments arguments, CancellationToken cancellationToken, int count = 2, int skip = 0)
159159
{
160160
arguments.TryGetValue("query", out var query);
161161
if (string.IsNullOrEmpty(query?.ToString()))
@@ -167,8 +167,8 @@ async Task<IEnumerable<string>> SearchAsync(Kernel kernel, KernelFunction functi
167167

168168
searchOptions ??= new()
169169
{
170-
Top = GetArgumentValue(arguments, parameters, "count", 2),
171-
Skip = GetArgumentValue(arguments, parameters, "skip", 0),
170+
Top = count,
171+
Skip = skip,
172172
Filter = CreateBasicFilter(options, arguments)
173173
};
174174

@@ -194,7 +194,7 @@ async Task<IEnumerable<string>> SearchAsync(Kernel kernel, KernelFunction functi
194194
[Experimental("SKEXP0120")]
195195
public static KernelFunction CreateSearch(this ITextSearch textSearch, JsonSerializerOptions jsonSerializerOptions, KernelFunctionFromMethodOptions? options = null, TextSearchOptions? searchOptions = null)
196196
{
197-
async Task<IEnumerable<string>> SearchAsync(Kernel kernel, KernelFunction function, KernelArguments arguments, CancellationToken cancellationToken)
197+
async Task<IEnumerable<string>> SearchAsync(Kernel kernel, KernelFunction function, KernelArguments arguments, CancellationToken cancellationToken, int count = 2, int skip = 0)
198198
{
199199
arguments.TryGetValue("query", out var query);
200200
if (string.IsNullOrEmpty(query?.ToString()))
@@ -206,8 +206,8 @@ async Task<IEnumerable<string>> SearchAsync(Kernel kernel, KernelFunction functi
206206

207207
searchOptions ??= new()
208208
{
209-
Top = GetArgumentValue(arguments, parameters, "count", 2),
210-
Skip = GetArgumentValue(arguments, parameters, "skip", 0),
209+
Top = count,
210+
Skip = skip,
211211
Filter = CreateBasicFilter(options, arguments)
212212
};
213213

@@ -234,7 +234,7 @@ async Task<IEnumerable<string>> SearchAsync(Kernel kernel, KernelFunction functi
234234
[RequiresDynamicCode("Uses reflection to handle various aspects of the function creation and invocation, making it incompatible with AOT scenarios.")]
235235
public static KernelFunction CreateGetTextSearchResults(this ITextSearch textSearch, KernelFunctionFromMethodOptions? options = null, TextSearchOptions? searchOptions = null)
236236
{
237-
async Task<IEnumerable<TextSearchResult>> GetTextSearchResultAsync(Kernel kernel, KernelFunction function, KernelArguments arguments, CancellationToken cancellationToken)
237+
async Task<IEnumerable<TextSearchResult>> GetTextSearchResultAsync(Kernel kernel, KernelFunction function, KernelArguments arguments, CancellationToken cancellationToken, int count = 2, int skip = 0)
238238
{
239239
arguments.TryGetValue("query", out var query);
240240
if (string.IsNullOrEmpty(query?.ToString()))
@@ -246,8 +246,8 @@ async Task<IEnumerable<TextSearchResult>> GetTextSearchResultAsync(Kernel kernel
246246

247247
searchOptions ??= new()
248248
{
249-
Top = GetArgumentValue(arguments, parameters, "count", 2),
250-
Skip = GetArgumentValue(arguments, parameters, "skip", 0),
249+
Top = count,
250+
Skip = skip,
251251
Filter = CreateBasicFilter(options, arguments)
252252
};
253253

@@ -272,7 +272,7 @@ async Task<IEnumerable<TextSearchResult>> GetTextSearchResultAsync(Kernel kernel
272272
[Experimental("SKEXP0120")]
273273
public static KernelFunction CreateGetTextSearchResults(this ITextSearch textSearch, JsonSerializerOptions jsonSerializerOptions, KernelFunctionFromMethodOptions? options = null, TextSearchOptions? searchOptions = null)
274274
{
275-
async Task<IEnumerable<TextSearchResult>> GetTextSearchResultAsync(Kernel kernel, KernelFunction function, KernelArguments arguments, CancellationToken cancellationToken)
275+
async Task<IEnumerable<TextSearchResult>> GetTextSearchResultAsync(Kernel kernel, KernelFunction function, KernelArguments arguments, CancellationToken cancellationToken, int count = 2, int skip = 0)
276276
{
277277
arguments.TryGetValue("query", out var query);
278278
if (string.IsNullOrEmpty(query?.ToString()))
@@ -284,8 +284,8 @@ async Task<IEnumerable<TextSearchResult>> GetTextSearchResultAsync(Kernel kernel
284284

285285
searchOptions ??= new()
286286
{
287-
Top = GetArgumentValue(arguments, parameters, "count", 2),
288-
Skip = GetArgumentValue(arguments, parameters, "skip", 0),
287+
Top = count,
288+
Skip = skip,
289289
Filter = CreateBasicFilter(options, arguments)
290290
};
291291

@@ -311,7 +311,7 @@ async Task<IEnumerable<TextSearchResult>> GetTextSearchResultAsync(Kernel kernel
311311
[RequiresDynamicCode("Uses reflection to handle various aspects of the function creation and invocation, making it incompatible with AOT scenarios.")]
312312
public static KernelFunction CreateGetSearchResults(this ITextSearch textSearch, KernelFunctionFromMethodOptions? options = null, TextSearchOptions? searchOptions = null)
313313
{
314-
async Task<IEnumerable<object>> GetSearchResultAsync(Kernel kernel, KernelFunction function, KernelArguments arguments, CancellationToken cancellationToken)
314+
async Task<IEnumerable<object>> GetSearchResultAsync(Kernel kernel, KernelFunction function, KernelArguments arguments, CancellationToken cancellationToken, int count = 2, int skip = 0)
315315
{
316316
arguments.TryGetValue("query", out var query);
317317
if (string.IsNullOrEmpty(query?.ToString()))
@@ -323,8 +323,8 @@ async Task<IEnumerable<object>> GetSearchResultAsync(Kernel kernel, KernelFuncti
323323

324324
searchOptions ??= new()
325325
{
326-
Top = GetArgumentValue(arguments, parameters, "count", 2),
327-
Skip = GetArgumentValue(arguments, parameters, "skip", 0),
326+
Top = count,
327+
Skip = skip,
328328
Filter = CreateBasicFilter(options, arguments)
329329
};
330330

@@ -349,7 +349,7 @@ async Task<IEnumerable<object>> GetSearchResultAsync(Kernel kernel, KernelFuncti
349349
[Experimental("SKEXP0120")]
350350
public static KernelFunction CreateGetSearchResults(this ITextSearch textSearch, JsonSerializerOptions jsonSerializerOptions, KernelFunctionFromMethodOptions? options = null, TextSearchOptions? searchOptions = null)
351351
{
352-
async Task<IEnumerable<object>> GetSearchResultAsync(Kernel kernel, KernelFunction function, KernelArguments arguments, CancellationToken cancellationToken)
352+
async Task<IEnumerable<object>> GetSearchResultAsync(Kernel kernel, KernelFunction function, KernelArguments arguments, CancellationToken cancellationToken, int count = 2, int skip = 0)
353353
{
354354
arguments.TryGetValue("query", out var query);
355355
if (string.IsNullOrEmpty(query?.ToString()))
@@ -361,8 +361,8 @@ async Task<IEnumerable<object>> GetSearchResultAsync(Kernel kernel, KernelFuncti
361361

362362
searchOptions ??= new()
363363
{
364-
Top = GetArgumentValue(arguments, parameters, "count", 2),
365-
Skip = GetArgumentValue(arguments, parameters, "skip", 0),
364+
Top = count,
365+
Skip = skip,
366366
Filter = CreateBasicFilter(options, arguments)
367367
};
368368

@@ -380,30 +380,6 @@ async Task<IEnumerable<object>> GetSearchResultAsync(Kernel kernel, KernelFuncti
380380
#endregion
381381

382382
#region private
383-
/// <summary>
384-
/// Get the argument value from <see cref="KernelArguments"/> or users default value from
385-
/// <see cref="KernelReturnParameterMetadata"/> or default to the provided value.
386-
/// </summary>
387-
/// <param name="arguments">KernelArguments instance.</param>
388-
/// <param name="parameters">List of KernelReturnParameterMetadata.</param>
389-
/// <param name="name">Name of the argument.</param>
390-
/// <param name="defaultValue">Default value of the argument.</param>
391-
private static int GetArgumentValue(KernelArguments arguments, IReadOnlyList<KernelParameterMetadata> parameters, string name, int defaultValue)
392-
{
393-
if (arguments.TryGetValue(name, out var value) && value is int argument)
394-
{
395-
return argument;
396-
}
397-
398-
value = parameters.FirstOrDefault(parameter => parameter.Name == name)?.DefaultValue;
399-
if (value is int metadataDefault)
400-
{
401-
return metadataDefault;
402-
}
403-
404-
return defaultValue;
405-
}
406-
407383
/// <summary>
408384
/// Create the default <see cref="KernelFunctionFromMethodOptions"/> for <see cref="ITextSearch.SearchAsync(string, TextSearchOptions?, CancellationToken)"/>.
409385
/// </summary>

0 commit comments

Comments
 (0)