Skip to content

Commit a8f71fd

Browse files
authored
Fix AIFunctionFactory functions to fail for missing required parameters (#6135)
1 parent 15adb0b commit a8f71fd

File tree

3 files changed

+24
-7
lines changed

3 files changed

+24
-7
lines changed

src/Libraries/Microsoft.Extensions.AI/Functions/AIFunctionFactory.cs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -374,15 +374,14 @@ static bool IsAsyncMethod(MethodInfo method)
374374
}
375375
}
376376

377-
// There was no argument for the parameter in the dictionary.
378-
// Does it have a default value?
379-
if (parameter.HasDefaultValue)
377+
// If the parameter is required and there's no argument specified for it, throw.
378+
if (!parameter.HasDefaultValue)
380379
{
381-
return parameter.DefaultValue;
380+
Throw.ArgumentException(nameof(arguments), $"Missing required parameter '{parameter.Name}' for method '{parameter.Member.Name}'.");
382381
}
383382

384-
// Leave it empty.
385-
return null;
383+
// Otherwise, use the optional parameter's default value.
384+
return parameter.DefaultValue;
386385
};
387386
}
388387

test/Libraries/Microsoft.Extensions.AI.Tests/ChatCompletion/FunctionInvokingChatClientTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ public async Task SupportsMultipleFunctionCallsPerRequestAsync(bool concurrentIn
7878
{
7979
Tools =
8080
[
81-
AIFunctionFactory.Create((int i) => "Result 1", "Func1"),
81+
AIFunctionFactory.Create((int? i = 42) => "Result 1", "Func1"),
8282
AIFunctionFactory.Create((int i) => $"Result 2: {i}", "Func2"),
8383
]
8484
};

test/Libraries/Microsoft.Extensions.AI.Tests/Functions/AIFunctionFactoryTest.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,24 @@ public async Task Parameters_DefaultValuesAreUsedButOverridable_Async()
4747
AssertExtensions.EqualFunctionCallResults("hello hello", await func.InvokeAsync([new KeyValuePair<string, object?>("a", "hello")]));
4848
}
4949

50+
[Fact]
51+
public async Task Parameters_MissingRequiredParametersFail_Async()
52+
{
53+
AIFunction[] funcs =
54+
[
55+
AIFunctionFactory.Create((string theParam) => theParam + " " + theParam),
56+
AIFunctionFactory.Create((string? theParam) => theParam + " " + theParam),
57+
AIFunctionFactory.Create((int theParam) => theParam * 2),
58+
AIFunctionFactory.Create((int? theParam) => theParam * 2),
59+
];
60+
61+
foreach (AIFunction f in funcs)
62+
{
63+
Exception e = await Assert.ThrowsAsync<ArgumentException>(() => f.InvokeAsync());
64+
Assert.Contains("'theParam'", e.Message);
65+
}
66+
}
67+
5068
[Fact]
5169
public async Task Parameters_MappedByType_Async()
5270
{

0 commit comments

Comments
 (0)