Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

.Net: Bug: complex function parameter passed as stringified JSON rather than deserialized objects #10713

Closed
adv12 opened this issue Feb 27, 2025 · 1 comment
Labels
bug Something isn't working .NET Issue or Pull requests regarding .NET code triage

Comments

@adv12
Copy link

adv12 commented Feb 27, 2025

Describe the bug
Semantic Kernel attempts to call a native function with a typed array for a parameter with the stringified JSON of its content rather than the deserialized array. This only seems to happen if the array type has an enum property.

To Reproduce

Create a Semantic Kernel project with the following Program.cs:

using System.ComponentModel;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
using Microsoft.SemanticKernel.Connectors.OpenAI;

string model = "gpt-4o";

Console.Write("Enter your OpenAI API key: ");
string apiKey = Console.ReadLine();
Console.Write("Enter your OpenAI OrgId: ");
string orgId = Console.ReadLine();

IKernelBuilder builder = Kernel.CreateBuilder();
builder.AddOpenAIChatCompletion(model, apiKey, orgId, null, new HttpClient(new LoggingHttpClientHandler()));
Kernel kernel = builder.Build();

kernel.ImportPluginFromType<MyPlugin>();

OpenAIPromptExecutionSettings settings =
   new() { FunctionChoiceBehavior = FunctionChoiceBehavior.Auto() };

IChatCompletionService chatCompletionService =
   kernel.GetRequiredService<IChatCompletionService>();

ChatHistory chatHistory = [];

chatHistory.AddUserMessage("Set Item1 to 5.");

foreach (var content in await chatCompletionService.GetChatMessageContentsAsync(chatHistory, settings, kernel))
{
   Console.WriteLine(content.Content);
}

enum ItemName
{
   Item1,
   Item2,
   Item3
}

class Item
{
   [Description("The name.")]
   public ItemName Name { get; set; }
   [Description("The value.")]
   public int Value { get; set; }
}

class MyPlugin
{
   [KernelFunction]
   [Description("Sets the values of the specified items.")]
   public Task SetItemValues(Kernel kernel, Item[] items)
   {
      foreach (Item item in items)
      {
         Console.WriteLine($"Setting {item.Name} to {item.Value}!");
      }
      return Task.CompletedTask;
   }
}

class LoggingHttpClientHandler : HttpClientHandler
{
   protected override async Task<HttpResponseMessage> SendAsync(
      HttpRequestMessage request, CancellationToken cancellationToken)
   {
      string content;
      if (request.Content is not null)
      {
         content = await request.Content.ReadAsStringAsync(cancellationToken);
         Console.WriteLine(content);
      }

      HttpResponseMessage response = await base.SendAsync(request, cancellationToken);
      MemoryStream responseStream = new(await response.Content.ReadAsByteArrayAsync(cancellationToken));
      Console.WriteLine(new StreamReader(responseStream).ReadToEnd());
      responseStream.Position = 0;
      response.Content = new StreamContent(responseStream);
      return response;
   }
}

When you run this program, observe that the function parameters from OpenAI are properly formed, but Semantic Kernel tries to call SetItemValues with a stringified version of the JSON rather than the deserialized Item list.

Expected behavior
MyPlugin.SetItemValues gets called with an array of 1 Item

Platform

  • Language: C#
  • Source: NuGet package version 1.39.0
  • AI model: OpenAI:GPT-4o
  • IDE: Visual Studio
  • OS: Windows, Mac
@adv12 adv12 added the bug Something isn't working label Feb 27, 2025
@markwallace-microsoft markwallace-microsoft added .NET Issue or Pull requests regarding .NET code triage labels Feb 27, 2025
@github-actions github-actions bot changed the title Bug: complex function parameter passed as stringified JSON rather than deserialized objects .Net: Bug: complex function parameter passed as stringified JSON rather than deserialized objects Feb 27, 2025
@adv12
Copy link
Author

adv12 commented Feb 27, 2025

Found my answer here: https://devblogs.microsoft.com/semantic-kernel/how-to-get-started-using-semantic-kernel-net/

"To be able to fully use this with an AI Model the Enums need to be annotated with a JsonDeserialization converter."

@adv12 adv12 closed this as completed Feb 27, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working .NET Issue or Pull requests regarding .NET code triage
Projects
None yet
Development

No branches or pull requests

2 participants