|
2 | 2 |
|
3 | 3 | using System; |
4 | 4 | using System.Collections.Concurrent; |
| 5 | +using System.Collections.Generic; |
5 | 6 | using System.Linq; |
6 | 7 | using System.Text.Json; |
7 | 8 | using System.Threading; |
@@ -855,6 +856,54 @@ public void ItShouldSerializeFunctionResultsWithStringProperties() |
855 | 856 | Assert.Equal("{\"Text\":\"テスト\"}", result); |
856 | 857 | } |
857 | 858 |
|
| 859 | + [Fact] |
| 860 | + public async Task ItShouldPropagateFunctionResultMetadataToChatHistoryAsync() |
| 861 | + { |
| 862 | + // Arrange |
| 863 | + var expectedMetadata = new Dictionary<string, object?> |
| 864 | + { |
| 865 | + ["key1"] = "value1", |
| 866 | + ["key2"] = 42 |
| 867 | + }; |
| 868 | + |
| 869 | + var function1 = KernelFunctionFactory.CreateFromMethod((string parameter) => parameter, "Function1"); |
| 870 | + var plugin = KernelPluginFactory.CreateFromFunctions("MyPlugin", [function1]); |
| 871 | + |
| 872 | + var kernel = CreateKernel(plugin, async (context, next) => |
| 873 | + { |
| 874 | + await next(context); |
| 875 | + |
| 876 | + // Filter sets metadata on the FunctionResult |
| 877 | + context.Result = new FunctionResult(context.Function, context.Result.GetValue<object>(), context.Result.Culture, expectedMetadata); |
| 878 | + }); |
| 879 | + |
| 880 | + var chatMessageContent = new ChatMessageContent(); |
| 881 | + chatMessageContent.Items.Add(new FunctionCallContent("Function1", "MyPlugin", arguments: new KernelArguments() { ["parameter"] = "function1-result" })); |
| 882 | + |
| 883 | + var chatHistory = new ChatHistory(); |
| 884 | + |
| 885 | + // Act |
| 886 | + await this._sut.ProcessFunctionCallsAsync( |
| 887 | + chatMessageContent: chatMessageContent, |
| 888 | + executionSettings: this._promptExecutionSettings, |
| 889 | + chatHistory: chatHistory, |
| 890 | + requestIndex: 0, |
| 891 | + checkIfFunctionAdvertised: (_) => true, |
| 892 | + options: this._functionChoiceBehaviorOptions, |
| 893 | + kernel: kernel!, |
| 894 | + isStreaming: false, |
| 895 | + cancellationToken: CancellationToken.None); |
| 896 | + |
| 897 | + // Assert |
| 898 | + Assert.Equal(2, chatHistory.Count); |
| 899 | + |
| 900 | + var toolMessage = chatHistory[1]; // First is the assistant message, second is the tool result |
| 901 | + Assert.Equal(AuthorRole.Tool, toolMessage.Role); |
| 902 | + Assert.NotNull(toolMessage.Metadata); |
| 903 | + Assert.Equal("value1", toolMessage.Metadata["key1"]); |
| 904 | + Assert.Equal(42, toolMessage.Metadata["key2"]); |
| 905 | + } |
| 906 | + |
858 | 907 | [Fact] |
859 | 908 | public async Task ItShouldPassPromptExecutionSettingsToAutoFunctionInvocationFilterAsync() |
860 | 909 | { |
|
0 commit comments