semantic-kernel
semantic-kernel copied to clipboard
.Net: HandlebarsPlanner JsonException
Describe the bug When invoking CreatePlanAsync of the HandlebarsPlanner I get an exception
System.Text.Json.JsonException: 'The JSON value could not be converted to System.String. Path: $ | LineNumber: 0 | BytePositionInLine: 1.'
InvalidOperationException: Cannot get the value of a token type 'StartArray' as a string.
To Reproduce Create an empty console app. Add Microsoft.SemanticKernel v1.9.0 nuget package Add Microsoft.SemanticKernel .Planners.OpenAI v 1.9.0-preview nugetpackage
var _kernel = Kernel.CreateBuilder().AddOpenAIChatCompletion("gpt-3.5-turbo", openAiApiKey, openAiOrg).Build();
_kernel.Plugins.AddFromType<CinemaPlugin>();
var planner = new HandlebarsPlanner(new HandlebarsPlannerOptions() { AllowLoops = false });
var plan = await planner.CreatePlanAsync(_kernel, "How to make a movie reservation");
CinemaPlugin
public class CinemaPlugin
{
[KernelFunction]
public async Task<string> MakeAMoviewReservation(DateTime? date)
{
return "Done";
}
}
Expected behavior The plan should be created
Screenshots If applicable, add screenshots to help explain your problem.
Platform
- OS: Windows
- IDE: Visual Studio
- Language: C#
Additional context
It works If I leave out the plugin registration. (If I comment this line _kernel.Plugins.AddFromType<CinemaPlugin>();)
Hi @rborosak , can you provide a sample plan and the prompt the Planner used?
You can get both from the HandlebarsPlan object:
- CreatePlanprompt:
plan.Prompt
- Plan template:
plan.toString()
@teresaqhoang No, beacuse planner.CreatePlanAsync throws an exception.
@rborosak ah I see. The Planner should throw a PlanCreationException
, so you should be able to wrap the Planner call in a try catch block and get the details that way.
try
{
await planner.CreatePlanAsync(kernel, "goal")
}
catch (PlanCreationException e)
{
Console.WriteLine(e.Message);
Console.WriteLine(e.InnerException?.Message);
// Invalid Plan object
Console.WriteLine(exception?.ModelResults?.Content);
// Prompt
Console.WriteLine(exception?.CreatePlanPrompt);
}
Same for me, after update to latest:
Cannot get the value of a token type 'StartArray' as a string.
The exception from a wrap of CreatePlanAsync
is {System.Text.Json.JsonException}
Found it, @rborosak , @teresaqhoang
In here:
public static KernelParameterMetadata ParseJsonSchema(this KernelParameterMetadata parameter)
{
var schema = parameter.Schema!;
var type = "object";
if (schema.RootElement.TryGetProperty("type", out var typeNode))
{
type = typeNode.Deserialize<string>()!;
}
if (IsPrimitiveOrStringType(type) || type == "null")
{
return new(parameter)
{
ParameterType = GetTypeFromSchema(type),
Schema = null,
};
}
return parameter;
}
Throws on type = typeNode.Deserialize<string>()!;
because typeNode has a ValueKind: array
:
My Schema is:
{
"type": [
"integer",
"null"
],
"description": "The number of the frame"
}
For this plugin definition:
[KernelFunction("ConvertFrameToUri")]
[Description("Provide the Uri when given a frame number")]
public string ConvertFrameToUri([Description("The number of the frame")] long? number1)
{
...
}
As you can see, I am using the nullable long?
.
The above is while debugging with local sources detached at the commit for 1.10.
This is a regression for me, I will attempt to work-around without the nullable types in my plugins.
Edit: Removing nullable types worked around this successfully.
This issue is stale because it has been open for 90 days with no activity.