Skip to content

Commit b592a4a

Browse files
authored
.Net: Moved IChatHistoryReducer from Agents to SK packages (#10285)
### Motivation and Context <!-- Thank you for your contribution to the semantic-kernel repo! Please help reviewers and future users, providing the following information: 1. Why is this change required? 2. What problem does it solve? 3. What scenario does it contribute to? 4. If it fixes an open issue, please link to the issue here. --> Resolves: #10203 This PR: - Moves `IChatHistoryReducer` from `Agents.Core` to `Microsoft.SemanticKernel.Abstractions` package. - Moves implementations `ChatHistorySummarizationReducer` and `ChatHistoryTruncationReducer` from `Agents.Core` to `Microsoft.SemanticKernel.Core` package. The functionality is marked as experimental. ### Contribution Checklist <!-- Before submitting this PR, please make sure: --> - [x] The code builds clean without any errors or warnings - [x] The PR follows the [SK Contribution Guidelines](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md) and the [pre-submission formatting script](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md#development-scripts) raises no violations - [x] All unit tests pass, and I have added new tests where possible - [x] I didn't break anyone 😄
1 parent 5098ba3 commit b592a4a

26 files changed

+240
-491
lines changed

dotnet/samples/Concepts/Agents/ChatCompletion_HistoryReducer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright (c) Microsoft. All rights reserved.
2+
23
using Microsoft.SemanticKernel;
34
using Microsoft.SemanticKernel.Agents;
4-
using Microsoft.SemanticKernel.Agents.History;
55
using Microsoft.SemanticKernel.ChatCompletion;
66

77
namespace Agents;

dotnet/samples/Concepts/ChatCompletion/ChatHistoryReducers/ChatHistoryExtensions.cs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ internal static class ChatHistoryExtensions
1919
/// <remarks>
2020
/// For simplicity only a single system message is supported in these examples.
2121
/// </remarks>
22-
internal static ChatMessageContent? GetSystemMessage(this ChatHistory chatHistory)
22+
internal static ChatMessageContent? GetSystemMessage(this IReadOnlyList<ChatMessageContent> chatHistory)
2323
{
2424
return chatHistory.FirstOrDefault(m => m.Role == AuthorRole.System);
2525
}
@@ -34,7 +34,9 @@ internal static class ChatHistoryExtensions
3434
/// <param name="summaryMessage">An optional summary messageContent to include</param>
3535
/// <param name="messageFilter">An optional message filter</param>
3636
public static IEnumerable<ChatMessageContent> Extract(
37-
this ChatHistory chatHistory, int startIndex, int? endIndex = null,
37+
this IReadOnlyList<ChatMessageContent> chatHistory,
38+
int startIndex,
39+
int? endIndex = null,
3840
ChatMessageContent? systemMessage = null,
3941
ChatMessageContent? summaryMessage = null,
4042
Func<ChatMessageContent, bool>? messageFilter = null)
@@ -71,11 +73,11 @@ public static IEnumerable<ChatMessageContent> Extract(
7173
/// <summary>
7274
/// Compute the index truncation where truncation should begin using the current truncation threshold.
7375
/// </summary>
74-
/// <param name="chatHistory">ChatHistory instance to be truncated</param>
75-
/// <param name="truncatedSize"></param>
76-
/// <param name="truncationThreshold"></param>
76+
/// <param name="chatHistory">The source history.</param>
77+
/// <param name="truncatedSize">Truncated size.</param>
78+
/// <param name="truncationThreshold">Truncation threshold.</param>
7779
/// <param name="hasSystemMessage">Flag indicating whether or not the chat history contains a system messageContent</param>
78-
public static int ComputeTruncationIndex(this ChatHistory chatHistory, int truncatedSize, int truncationThreshold, bool hasSystemMessage)
80+
public static int ComputeTruncationIndex(this IReadOnlyList<ChatMessageContent> chatHistory, int truncatedSize, int truncationThreshold, bool hasSystemMessage)
7981
{
8082
if (chatHistory.Count <= truncationThreshold)
8183
{

dotnet/samples/Concepts/ChatCompletion/ChatHistoryReducers/MaxTokensChatHistoryReducer.cs renamed to dotnet/samples/Concepts/ChatCompletion/ChatHistoryReducers/ChatHistoryMaxTokensReducer.cs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,15 @@ namespace ChatCompletion;
1111
/// <remarks>
1212
/// This reducer requires that the ChatMessageContent.MetaData contains a TokenCount property.
1313
/// </remarks>
14-
public sealed class MaxTokensChatHistoryReducer : IChatHistoryReducer
14+
public sealed class ChatHistoryMaxTokensReducer : IChatHistoryReducer
1515
{
1616
private readonly int _maxTokenCount;
1717

1818
/// <summary>
19-
/// Creates a new instance of <see cref="MaxTokensChatHistoryReducer"/>.
19+
/// Creates a new instance of <see cref="ChatHistoryMaxTokensReducer"/>.
2020
/// </summary>
2121
/// <param name="maxTokenCount">Max token count to send to the model.</param>
22-
public MaxTokensChatHistoryReducer(int maxTokenCount)
22+
public ChatHistoryMaxTokensReducer(int maxTokenCount)
2323
{
2424
if (maxTokenCount <= 0)
2525
{
@@ -30,7 +30,7 @@ public MaxTokensChatHistoryReducer(int maxTokenCount)
3030
}
3131

3232
/// <inheritdoc/>
33-
public Task<IEnumerable<ChatMessageContent>?> ReduceAsync(ChatHistory chatHistory, CancellationToken cancellationToken = default)
33+
public Task<IEnumerable<ChatMessageContent>?> ReduceAsync(IReadOnlyList<ChatMessageContent> chatHistory, CancellationToken cancellationToken = default)
3434
{
3535
var systemMessage = chatHistory.GetSystemMessage();
3636

@@ -47,12 +47,13 @@ public MaxTokensChatHistoryReducer(int maxTokenCount)
4747
}
4848

4949
#region private
50+
5051
/// <summary>
5152
/// Compute the index truncation where truncation should begin using the current truncation threshold.
5253
/// </summary>
53-
/// <param name="chatHistory">ChatHistory instance to be truncated</param>
54+
/// <param name="chatHistory">Chat history to be truncated.</param>
5455
/// <param name="systemMessage">The system message</param>
55-
private int ComputeTruncationIndex(ChatHistory chatHistory, ChatMessageContent? systemMessage)
56+
private int ComputeTruncationIndex(IReadOnlyList<ChatMessageContent> chatHistory, ChatMessageContent? systemMessage)
5657
{
5758
var truncationIndex = -1;
5859

@@ -83,5 +84,6 @@ private int ComputeTruncationIndex(ChatHistory chatHistory, ChatMessageContent?
8384

8485
return truncationIndex;
8586
}
87+
8688
#endregion
8789
}

dotnet/samples/Concepts/ChatCompletion/ChatHistoryReducers/ChatHistoryReducerTests.cs

Lines changed: 1 addition & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -11,31 +11,6 @@ namespace ChatCompletion;
1111
/// </summary>
1212
public class ChatHistoryReducerTests(ITestOutputHelper output) : BaseTest(output)
1313
{
14-
[Theory]
15-
[InlineData(3, null, null, 5, 0)]
16-
[InlineData(2, null, null, 1, 1)]
17-
[InlineData(2, "SystemMessage", null, 2, 2)]
18-
[InlineData(10, null, null, 3, 3)]
19-
[InlineData(10, "SystemMessage", null, 3, 3)]
20-
[InlineData(9, null, null, 5, 5)]
21-
[InlineData(11, null, null, 5, 5)]
22-
[InlineData(8, "SystemMessage", null, 5, 5)]
23-
[InlineData(10, "SystemMessage", null, 5, 5)]
24-
[InlineData(3, null, new int[] { 0 }, 3, 2)]
25-
[InlineData(3, "SystemMessage", new int[] { 0 }, 4, 3)]
26-
public async Task VerifyTruncatingChatHistoryReducerAsync(int messageCount, string? systemMessage, int[]? functionCallIndexes, int truncatedSize, int expectedSize)
27-
{
28-
// Arrange
29-
var chatHistory = CreateHistoryWithUserInput(messageCount, systemMessage, functionCallIndexes);
30-
var reducer = new TruncatingChatHistoryReducer(truncatedSize);
31-
32-
// Act
33-
var reducedHistory = await reducer.ReduceAsync(chatHistory);
34-
35-
// Assert
36-
VerifyReducedHistory(reducedHistory, ComputeExpectedMessages(chatHistory, expectedSize));
37-
}
38-
3914
[Theory]
4015
[InlineData(3, null, null, 100, 0)]
4116
[InlineData(3, "SystemMessage", null, 100, 0)]
@@ -47,30 +22,7 @@ public async Task VerifyMaxTokensChatHistoryReducerAsync(int messageCount, strin
4722
{
4823
// Arrange
4924
var chatHistory = CreateHistoryWithUserInput(messageCount, systemMessage, functionCallIndexes, true);
50-
var reducer = new MaxTokensChatHistoryReducer(maxTokens);
51-
52-
// Act
53-
var reducedHistory = await reducer.ReduceAsync(chatHistory);
54-
55-
// Assert
56-
VerifyReducedHistory(reducedHistory, ComputeExpectedMessages(chatHistory, expectedSize));
57-
}
58-
59-
[Theory]
60-
[InlineData(3, null, null, 5, 10, 0)]
61-
[InlineData(10, null, null, 5, 10, 6)]
62-
[InlineData(10, "SystemMessage", null, 5, 10, 6)]
63-
[InlineData(10, null, new int[] { 1 }, 5, 10, 6)]
64-
[InlineData(10, "SystemMessage", new int[] { 2 }, 5, 10, 6)]
65-
public async Task VerifySummarizingChatHistoryReducerAsync(int messageCount, string? systemMessage, int[]? functionCallIndexes, int truncatedSize, int truncationThreshold, int expectedSize)
66-
{
67-
// Arrange
68-
Assert.NotNull(TestConfiguration.OpenAI.ChatModelId);
69-
Assert.NotNull(TestConfiguration.OpenAI.ApiKey);
70-
IChatCompletionService chatClient = new FakeChatCompletionService("The dialog consists of repetitive interaction where both the user and assistant exchange identical phrases in Latin.");
71-
72-
var chatHistory = CreateHistoryWithUserInput(messageCount, systemMessage, functionCallIndexes, true);
73-
var reducer = new SummarizingChatHistoryReducer(chatClient, truncatedSize, truncationThreshold);
25+
var reducer = new ChatHistoryMaxTokensReducer(maxTokens);
7426

7527
// Act
7628
var reducedHistory = await reducer.ReduceAsync(chatHistory);

dotnet/samples/Concepts/ChatCompletion/ChatHistoryReducers/IChatHistoryReducer.cs

Lines changed: 0 additions & 20 deletions
This file was deleted.

dotnet/samples/Concepts/ChatCompletion/ChatHistoryReducers/SummarizingChatHistoryReducer.cs

Lines changed: 0 additions & 140 deletions
This file was deleted.

0 commit comments

Comments
 (0)