-
Notifications
You must be signed in to change notification settings - Fork 850
Description
Description
When an LLM returns a tool call with null argument values (e.g., {"methodName": null}), the FunctionCallContent.Arguments dictionary contains the literal string "null" instead of actual null.
Reproduction Steps
- Use
Microsoft.Extensions.AI.OpenAIpackage (tested with version 9.4.0-preview.1.25207.5) - Define a tool with optional parameters
- Have the LLM call the tool with
nullfor an optional parameter - Inspect
FunctionCallContent.Argumentsdictionary
Expected Behavior
When JSON contains {"methodName": null}, the Arguments dictionary should have:
Arguments["methodName"]isnull(actual null)- Or the key should not be present
Actual Behavior
Arguments["methodName"]is the string"null"(4 characters: n, u, l, l)
Root Cause Analysis
The issue appears to be in OpenAIClientExtensions.ParseCallContent:
internal static FunctionCallContent ParseCallContent(string json, string callId, string name) =>
FunctionCallContent.CreateFromParsedArguments(json, callId, name,
static json => JsonSerializer.Deserialize(json, OpenAIJsonContext.Default.IDictionaryStringObject)!);When System.Text.Json deserializes JSON to IDictionary<string, object>, null values are not properly preserved. The OpenAIJsonContext.Default.IDictionaryStringObject serializer context appears to convert JSON null to the string "null".
Workaround
We're currently working around this by checking for the literal string "null" when extracting values:
if (obj is string strValue && strValue == "null")
{
value = default!;
return false;
}Environment
- Microsoft.Extensions.AI.OpenAI: 9.4.0-preview.1.25207.5
- .NET 9.0
- Using OpenAI-compatible endpoint (LiteLLM proxy to Claude)
Additional Context
This issue affects any code that relies on checking for null values in tool call arguments, which is common for optional parameters.