Treat empty json string in tool call as having 'no' arguments.#173
Treat empty json string in tool call as having 'no' arguments.#173mstancombe wants to merge 1 commit intoanthropics:nextfrom
Conversation
|
Would you be able to rebase this? |
| json => | ||
| (Dictionary<string, object?>?) | ||
| json => json.Length == 0 | ||
| ? null |
There was a problem hiding this comment.
@stephentoub Does null make sense here or should re be returning an empty dictionary?
There was a problem hiding this comment.
Just to expand on my reasoning, as I did look into this a bit before deciding on null, the 'Arguments' on FunctionCallContext class in MEAI looks like this:
/// <summary>
/// Gets or sets the arguments requested to be provided to the function.
/// </summary>
public IDictionary<string, object?>? Arguments { get; set; }
Which doesn't explicitly state when this should be null, but given that it is nullable, I think an llm passing no arguments probably should be interpreted as nothing.
Additionally, the debug view for FunctionCallContext does this:
/// <summary>Gets a string representing this instance to display in the debugger.</summary>
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private string DebuggerDisplay
{
get
{
string display = "FunctionCall = ";
if (CallId is not null)
{
display += $"{CallId}, ";
}
display += Arguments is not null ?
$"{Name}({string.Join(", ", Arguments)})" :
$"{Name}()";
return display;
}
}
If arguments was an empty dict, this would show as 'MyTool()' vs 'MyTool' when it's null. Again, this doesn't prove what the intention was, but I'm guessing (hoping :P) that @stephentoub was expecting a null to represent 'no args'.
There was a problem hiding this comment.
ah, disregard the final point, it would still show MyTool() with no args.. it just would skip the string.join over the empty dictionary, but no output difference.
2db41e1 to
162ad5b
Compare
|
Rebased to latest next. |
If a non-server tool has no arguments, it's currently still run through the json deserializer, which raises a JsonException.
This doesn't stop the chat client from working, CreateFromParsedArguments just seems to log the exception in the created FunctionCallContent, but it does mean a noisy exception, and the created FunctionCallContent doesn't reflect the true state of play.
This PR handles an empty string as meaning there was no arguments given, which I think is how we should handle this.