Closed
Description
I'm trying to figure out the cleanest way to figure out what tools were invoked in a call. Here is what I've come up with but there has to be a better way?
using System.ComponentModel;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
var kernel = Kernel
.CreateBuilder()
.AddAzureOpenAIChatCompletion(
deploymentName: "gpt-4o",
endpoint: "",
apiKey: ""
)
.Build();
kernel.Plugins.AddFromType<WeatherPlugin>();
var chatHistory = new ChatHistory();
chatHistory.AddUserMessage("whats the weather");
var promptExecutionSettings = new PromptExecutionSettings
{
FunctionChoiceBehavior = FunctionChoiceBehavior.Auto(),
};
var chatService = kernel.GetRequiredService<IChatCompletionService>();
var result = await chatService.GetChatMessageContentAsync(
chatHistory,
promptExecutionSettings,
kernel
);
Console.WriteLine(result.Content);
var plugins = GetPluginsUsed(chatHistory);
foreach (var plugin in plugins)
{
Console.WriteLine(plugin);
}
Console.ReadLine();
static List<string> GetPluginsUsed(ChatHistory chatHistory)
{
// Find the index of the most recent user message
int lastUserMessageIndex = -1;
for (int i = chatHistory.Count - 1; i >= 0; i--)
{
if (chatHistory[i].Role == AuthorRole.User)
{
lastUserMessageIndex = i;
break;
}
}
// Extract only tool messages that appear AFTER the last user message
var toolMessages = chatHistory
.Skip(lastUserMessageIndex + 1) // Start from the message after the user's last input
.Where(msg => msg.Role == AuthorRole.Tool)
.SelectMany(toolMsg =>
toolMsg
.Items.OfType<FunctionResultContent>()
.Select(x => $"({x.PluginName}: {x.FunctionName})")
)
.ToList();
return toolMessages;
}
public class WeatherPlugin
{
// Hard coded weather data
private readonly string[] weatherData =
[
"Sunny, 15°C",
"Cloudy, 12°C",
"Rainy, 10°C",
"Snowy, -2°C",
];
private readonly Random random = new();
[KernelFunction, Description("Get weather information")]
public string GetWeather()
{
// Get random weather data
int index = random.Next(weatherData.Length);
return weatherData[index];
}
}
Metadata
Metadata
Assignees
Type
Projects
Status
Sprint: Done