diff --git a/src/Libraries/Microsoft.Extensions.AI.Abstractions/Contents/FunctionCallContent.cs b/src/Libraries/Microsoft.Extensions.AI.Abstractions/Contents/FunctionCallContent.cs index f106d9b615c..ea3458fb5b6 100644 --- a/src/Libraries/Microsoft.Extensions.AI.Abstractions/Contents/FunctionCallContent.cs +++ b/src/Libraries/Microsoft.Extensions.AI.Abstractions/Contents/FunctionCallContent.cs @@ -64,14 +64,12 @@ public FunctionCallContent(string callId, string name, IDictionaryThe function call ID. /// The function name. /// The parsing implementation converting the encoding to a dictionary of arguments. - /// Filters potential parsing exceptions that should be caught and included in the result. /// A new instance of containing the parse result. public static FunctionCallContent CreateFromParsedArguments( TEncoding encodedArguments, string callId, string name, - Func?> argumentParser, - Func? exceptionFilter = null) + Func?> argumentParser) { _ = Throw.IfNull(callId); _ = Throw.IfNull(name); @@ -81,14 +79,16 @@ public static FunctionCallContent CreateFromParsedArguments( IDictionary? arguments = null; Exception? parsingException = null; +#pragma warning disable CA1031 // Do not catch general exception types try { arguments = argumentParser(encodedArguments); } - catch (Exception ex) when (exceptionFilter is null || exceptionFilter(ex)) + catch (Exception ex) { parsingException = new InvalidOperationException("Error parsing function call arguments.", ex); } +#pragma warning restore CA1031 // Do not catch general exception types return new FunctionCallContent(callId, name, arguments) { diff --git a/src/Libraries/Microsoft.Extensions.AI.AzureAIInference/AzureAIInferenceChatClient.cs b/src/Libraries/Microsoft.Extensions.AI.AzureAIInference/AzureAIInferenceChatClient.cs index 93c467618c3..c422e622065 100644 --- a/src/Libraries/Microsoft.Extensions.AI.AzureAIInference/AzureAIInferenceChatClient.cs +++ b/src/Libraries/Microsoft.Extensions.AI.AzureAIInference/AzureAIInferenceChatClient.cs @@ -492,8 +492,7 @@ private IEnumerable ToAzureAIInferenceChatMessages(IEnumerab private static FunctionCallContent ParseCallContentFromJsonString(string json, string callId, string name) => FunctionCallContent.CreateFromParsedArguments(json, callId, name, - argumentParser: static json => JsonSerializer.Deserialize(json, JsonContext.Default.IDictionaryStringObject), - exceptionFilter: static ex => ex is JsonException); + argumentParser: static json => JsonSerializer.Deserialize(json, JsonContext.Default.IDictionaryStringObject)); /// Source-generated JSON type information. [JsonSerializable(typeof(AzureAIChatToolJson))] diff --git a/src/Libraries/Microsoft.Extensions.AI.OpenAI/OpenAIChatClient.cs b/src/Libraries/Microsoft.Extensions.AI.OpenAI/OpenAIChatClient.cs index b00e4b52d7f..647c5aaf6ca 100644 --- a/src/Libraries/Microsoft.Extensions.AI.OpenAI/OpenAIChatClient.cs +++ b/src/Libraries/Microsoft.Extensions.AI.OpenAI/OpenAIChatClient.cs @@ -655,13 +655,11 @@ private sealed class OpenAIChatToolJson private static FunctionCallContent ParseCallContentFromJsonString(string json, string callId, string name) => FunctionCallContent.CreateFromParsedArguments(json, callId, name, - argumentParser: static json => JsonSerializer.Deserialize(json, JsonContext.Default.IDictionaryStringObject), - exceptionFilter: static ex => ex is JsonException); + argumentParser: static json => JsonSerializer.Deserialize(json, JsonContext.Default.IDictionaryStringObject)); private static FunctionCallContent ParseCallContentFromBinaryData(BinaryData ut8Json, string callId, string name) => FunctionCallContent.CreateFromParsedArguments(ut8Json, callId, name, - argumentParser: static json => JsonSerializer.Deserialize(json, JsonContext.Default.IDictionaryStringObject), - exceptionFilter: static ex => ex is JsonException); + argumentParser: static json => JsonSerializer.Deserialize(json, JsonContext.Default.IDictionaryStringObject)); /// Source-generated JSON type information. [JsonSerializable(typeof(OpenAIChatToolJson))] diff --git a/src/Libraries/Microsoft.Extensions.AI/Utilities/AIJsonUtilities.Schema.cs b/src/Libraries/Microsoft.Extensions.AI/Utilities/AIJsonUtilities.Schema.cs index 932267fe7cf..4ad0603d311 100644 --- a/src/Libraries/Microsoft.Extensions.AI/Utilities/AIJsonUtilities.Schema.cs +++ b/src/Libraries/Microsoft.Extensions.AI/Utilities/AIJsonUtilities.Schema.cs @@ -55,7 +55,7 @@ public static partial class AIJsonUtilities /// The options used to extract the schema from the specified type. /// The options controlling schema inference. /// A JSON schema document encoded as a . - public static JsonElement ResolveParameterSchema( + public static JsonElement ResolveParameterJsonSchema( AIFunctionParameterMetadata parameterMetadata, AIFunctionMetadata functionMetadata, JsonSerializerOptions? serializerOptions = null, diff --git a/test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/AIJsonUtilitiesTests.cs b/test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/AIJsonUtilitiesTests.cs index c4ce6a86014..266f7ec45e9 100644 --- a/test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/AIJsonUtilitiesTests.cs +++ b/test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/AIJsonUtilitiesTests.cs @@ -115,7 +115,7 @@ public static void CreateJsonSchema_OverriddenParameters_GeneratesExpectedJsonSc } [Fact] - public static void ResolveJsonSchema_ReturnsExpectedValue() + public static void ResolveParameterJsonSchema_ReturnsExpectedValue() { JsonSerializerOptions options = new(JsonSerializerOptions.Default); AIFunction func = AIFunctionFactory.Create((int x, int y) => x + y, serializerOptions: options); @@ -125,11 +125,11 @@ public static void ResolveJsonSchema_ReturnsExpectedValue() JsonElement generatedSchema = Assert.IsType(param.Schema); JsonElement resolvedSchema; - resolvedSchema = AIJsonUtilities.ResolveParameterSchema(param, metadata, options); + resolvedSchema = AIJsonUtilities.ResolveParameterJsonSchema(param, metadata, options); Assert.True(JsonElement.DeepEquals(generatedSchema, resolvedSchema)); options = new(options) { NumberHandling = JsonNumberHandling.AllowReadingFromString }; - resolvedSchema = AIJsonUtilities.ResolveParameterSchema(param, metadata, options); + resolvedSchema = AIJsonUtilities.ResolveParameterJsonSchema(param, metadata, options); Assert.False(JsonElement.DeepEquals(generatedSchema, resolvedSchema)); } diff --git a/test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/Contents/FunctionCallContentTests..cs b/test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/Contents/FunctionCallContentTests..cs index 5cfc0711f13..50ca205197d 100644 --- a/test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/Contents/FunctionCallContentTests..cs +++ b/test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/Contents/FunctionCallContentTests..cs @@ -316,30 +316,22 @@ public static void CreateFromParsedArguments_ObjectJsonInput_ReturnsElementArgum }); } - [Fact] - public static void CreateFromParsedArguments_ParseException_HasExpectedHandling() + [Theory] + [InlineData(typeof(JsonException))] + [InlineData(typeof(InvalidOperationException))] + [InlineData(typeof(NotSupportedException))] + public static void CreateFromParsedArguments_ParseException_HasExpectedHandling(Type exceptionType) { - FunctionCallContent content; - JsonException exc = new(); + Exception exc = (Exception)Activator.CreateInstance(exceptionType)!; + FunctionCallContent content = FunctionCallContent.CreateFromParsedArguments(exc, "callId", "functionName", ThrowingParser); - content = FunctionCallContent.CreateFromParsedArguments(exc, "callId", "functionName", ThrowingParser); + Assert.Equal("functionName", content.Name); + Assert.Equal("callId", content.CallId); Assert.Null(content.Arguments); Assert.IsType(content.Exception); Assert.Same(exc, content.Exception.InnerException); - content = FunctionCallContent.CreateFromParsedArguments(exc, "callId", "functionName", ThrowingParser, exceptionFilter: IsJsonException); - Assert.Null(content.Arguments); - Assert.IsType(content.Exception); - Assert.Same(exc, content.Exception.InnerException); - - NotSupportedException otherExc = new(); - NotSupportedException thrownEx = Assert.Throws(() => - FunctionCallContent.CreateFromParsedArguments(otherExc, "callId", "functionName", ThrowingParser, exceptionFilter: IsJsonException)); - - Assert.Same(otherExc, thrownEx); - static Dictionary ThrowingParser(Exception ex) => throw ex; - static bool IsJsonException(Exception ex) => ex is JsonException; } [Fact]