mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
Checkpoint
This commit is contained in:
+228
-227
@@ -1,268 +1,269 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Agents.AI.Compaction;
|
||||
using Microsoft.Extensions.AI;
|
||||
using Moq;
|
||||
// %%% SAVE - RE-ANALYZE
|
||||
//using System.Collections.Generic;
|
||||
//using System.Threading;
|
||||
//using System.Threading.Tasks;
|
||||
//using Microsoft.Agents.AI.Compaction;
|
||||
//using Microsoft.Extensions.AI;
|
||||
//using Moq;
|
||||
|
||||
namespace Microsoft.Agents.AI.Abstractions.UnitTests.Compaction;
|
||||
//namespace Microsoft.Agents.AI.Abstractions.UnitTests.Compaction;
|
||||
|
||||
/// <summary>
|
||||
/// Contains tests for the compaction integration with <see cref="InMemoryChatHistoryProvider"/>.
|
||||
/// </summary>
|
||||
public class InMemoryChatHistoryProviderCompactionTests
|
||||
{
|
||||
private static readonly AIAgent s_mockAgent = new Mock<AIAgent>().Object;
|
||||
///// <summary>
|
||||
///// Contains tests for the compaction integration with <see cref="InMemoryChatHistoryProvider"/>.
|
||||
///// </summary>
|
||||
//public class InMemoryChatHistoryProviderCompactionTests
|
||||
//{
|
||||
// private static readonly AIAgent s_mockAgent = new Mock<AIAgent>().Object;
|
||||
|
||||
private static AgentSession CreateMockSession() => new Mock<AgentSession>().Object;
|
||||
// private static AgentSession CreateMockSession() => new Mock<AgentSession>().Object;
|
||||
|
||||
[Fact]
|
||||
public void Constructor_SetsCompactionStrategy_FromOptions()
|
||||
{
|
||||
// Arrange
|
||||
Mock<ICompactionStrategy> strategy = new();
|
||||
// [Fact]
|
||||
// public void Constructor_SetsCompactionStrategy_FromOptions()
|
||||
// {
|
||||
// // Arrange
|
||||
// Mock<ICompactionStrategy> strategy = new();
|
||||
|
||||
// Act
|
||||
InMemoryChatHistoryProvider provider = new(new InMemoryChatHistoryProviderOptions
|
||||
{
|
||||
CompactionStrategy = strategy.Object,
|
||||
});
|
||||
// // Act
|
||||
// InMemoryChatHistoryProvider provider = new(new InMemoryChatHistoryProviderOptions
|
||||
// {
|
||||
// CompactionStrategy = strategy.Object,
|
||||
// });
|
||||
|
||||
// Assert
|
||||
Assert.Same(strategy.Object, provider.CompactionStrategy);
|
||||
}
|
||||
// // Assert
|
||||
// Assert.Same(strategy.Object, provider.CompactionStrategy);
|
||||
// }
|
||||
|
||||
[Fact]
|
||||
public void Constructor_CompactionStrategyIsNull_ByDefault()
|
||||
{
|
||||
// Arrange & Act
|
||||
InMemoryChatHistoryProvider provider = new();
|
||||
// [Fact]
|
||||
// public void Constructor_CompactionStrategyIsNull_ByDefault()
|
||||
// {
|
||||
// // Arrange & Act
|
||||
// InMemoryChatHistoryProvider provider = new();
|
||||
|
||||
// Assert
|
||||
Assert.Null(provider.CompactionStrategy);
|
||||
}
|
||||
// // Assert
|
||||
// Assert.Null(provider.CompactionStrategy);
|
||||
// }
|
||||
|
||||
[Fact]
|
||||
public async Task StoreChatHistoryAsync_AppliesCompaction_WhenStrategyConfiguredAsync()
|
||||
{
|
||||
// Arrange — mock strategy that excludes the first included non-system group
|
||||
Mock<ICompactionStrategy> mockStrategy = new();
|
||||
mockStrategy.Setup(s => s.CompactAsync(It.IsAny<MessageGroups>(), It.IsAny<CancellationToken>()))
|
||||
.Callback<MessageGroups, CancellationToken>((groups, _) =>
|
||||
{
|
||||
foreach (MessageGroup group in groups.Groups)
|
||||
{
|
||||
if (!group.IsExcluded && group.Kind != MessageGroupKind.System)
|
||||
{
|
||||
group.IsExcluded = true;
|
||||
group.ExcludeReason = "Mock compaction";
|
||||
break;
|
||||
}
|
||||
}
|
||||
})
|
||||
.ReturnsAsync(true);
|
||||
// [Fact]
|
||||
// public async Task StoreChatHistoryAsync_AppliesCompaction_WhenStrategyConfiguredAsync()
|
||||
// {
|
||||
// // Arrange — mock strategy that excludes the first included non-system group
|
||||
// Mock<ICompactionStrategy> mockStrategy = new();
|
||||
// mockStrategy.Setup(s => s.CompactAsync(It.IsAny<MessageIndex>(), It.IsAny<CancellationToken>()))
|
||||
// .Callback<MessageIndex, CancellationToken>((groups, _) =>
|
||||
// {
|
||||
// foreach (MessageGroup group in groups.Groups)
|
||||
// {
|
||||
// if (!group.IsExcluded && group.Kind != MessageGroupKind.System)
|
||||
// {
|
||||
// group.IsExcluded = true;
|
||||
// group.ExcludeReason = "Mock compaction";
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
// .ReturnsAsync(true);
|
||||
|
||||
InMemoryChatHistoryProvider provider = new(new InMemoryChatHistoryProviderOptions
|
||||
{
|
||||
CompactionStrategy = mockStrategy.Object,
|
||||
});
|
||||
// InMemoryChatHistoryProvider provider = new(new InMemoryChatHistoryProviderOptions
|
||||
// {
|
||||
// CompactionStrategy = mockStrategy.Object,
|
||||
// });
|
||||
|
||||
AgentSession session = CreateMockSession();
|
||||
// AgentSession session = CreateMockSession();
|
||||
|
||||
// Pre-populate with some messages
|
||||
List<ChatMessage> existingMessages =
|
||||
[
|
||||
new ChatMessage(ChatRole.User, "First"),
|
||||
new ChatMessage(ChatRole.Assistant, "Response 1"),
|
||||
];
|
||||
provider.SetMessages(session, existingMessages);
|
||||
// // Pre-populate with some messages
|
||||
// List<ChatMessage> existingMessages =
|
||||
// [
|
||||
// new ChatMessage(ChatRole.User, "First"),
|
||||
// new ChatMessage(ChatRole.Assistant, "Response 1"),
|
||||
// ];
|
||||
// provider.SetMessages(session, existingMessages);
|
||||
|
||||
// Invoke the store flow with additional messages
|
||||
List<ChatMessage> requestMessages =
|
||||
[
|
||||
new ChatMessage(ChatRole.User, "Second"),
|
||||
];
|
||||
List<ChatMessage> responseMessages =
|
||||
[
|
||||
new ChatMessage(ChatRole.Assistant, "Response 2"),
|
||||
];
|
||||
// // Invoke the store flow with additional messages
|
||||
// List<ChatMessage> requestMessages =
|
||||
// [
|
||||
// new ChatMessage(ChatRole.User, "Second"),
|
||||
// ];
|
||||
// List<ChatMessage> responseMessages =
|
||||
// [
|
||||
// new ChatMessage(ChatRole.Assistant, "Response 2"),
|
||||
// ];
|
||||
|
||||
ChatHistoryProvider.InvokedContext context = new(s_mockAgent, session, requestMessages, responseMessages);
|
||||
// ChatHistoryProvider.InvokedContext context = new(s_mockAgent, session, requestMessages, responseMessages);
|
||||
|
||||
// Act
|
||||
await provider.InvokedAsync(context);
|
||||
// // Act
|
||||
// await provider.InvokedAsync(context);
|
||||
|
||||
// Assert - compaction should have removed one group
|
||||
List<ChatMessage> storedMessages = provider.GetMessages(session);
|
||||
Assert.Equal(3, storedMessages.Count);
|
||||
mockStrategy.Verify(s => s.CompactAsync(It.IsAny<MessageGroups>(), It.IsAny<CancellationToken>()), Times.Once);
|
||||
}
|
||||
// // Assert - compaction should have removed one group
|
||||
// List<ChatMessage> storedMessages = provider.GetMessages(session);
|
||||
// Assert.Equal(3, storedMessages.Count);
|
||||
// mockStrategy.Verify(s => s.CompactAsync(It.IsAny<MessageIndex>(), It.IsAny<CancellationToken>()), Times.Once);
|
||||
// }
|
||||
|
||||
[Fact]
|
||||
public async Task StoreChatHistoryAsync_DoesNotCompact_WhenNoStrategyAsync()
|
||||
{
|
||||
// Arrange
|
||||
InMemoryChatHistoryProvider provider = new();
|
||||
AgentSession session = CreateMockSession();
|
||||
// [Fact]
|
||||
// public async Task StoreChatHistoryAsync_DoesNotCompact_WhenNoStrategyAsync()
|
||||
// {
|
||||
// // Arrange
|
||||
// InMemoryChatHistoryProvider provider = new();
|
||||
// AgentSession session = CreateMockSession();
|
||||
|
||||
List<ChatMessage> requestMessages =
|
||||
[
|
||||
new ChatMessage(ChatRole.User, "Hello"),
|
||||
];
|
||||
List<ChatMessage> responseMessages =
|
||||
[
|
||||
new ChatMessage(ChatRole.Assistant, "Hi!"),
|
||||
];
|
||||
// List<ChatMessage> requestMessages =
|
||||
// [
|
||||
// new ChatMessage(ChatRole.User, "Hello"),
|
||||
// ];
|
||||
// List<ChatMessage> responseMessages =
|
||||
// [
|
||||
// new ChatMessage(ChatRole.Assistant, "Hi!"),
|
||||
// ];
|
||||
|
||||
ChatHistoryProvider.InvokedContext context = new(s_mockAgent, session, requestMessages, responseMessages);
|
||||
// ChatHistoryProvider.InvokedContext context = new(s_mockAgent, session, requestMessages, responseMessages);
|
||||
|
||||
// Act
|
||||
await provider.InvokedAsync(context);
|
||||
// // Act
|
||||
// await provider.InvokedAsync(context);
|
||||
|
||||
// Assert - all messages should be stored
|
||||
List<ChatMessage> storedMessages = provider.GetMessages(session);
|
||||
Assert.Equal(2, storedMessages.Count);
|
||||
}
|
||||
// // Assert - all messages should be stored
|
||||
// List<ChatMessage> storedMessages = provider.GetMessages(session);
|
||||
// Assert.Equal(2, storedMessages.Count);
|
||||
// }
|
||||
|
||||
[Fact]
|
||||
public async Task CompactStorageAsync_CompactsStoredMessagesAsync()
|
||||
{
|
||||
// Arrange — mock strategy that excludes the two oldest non-system groups
|
||||
Mock<ICompactionStrategy> mockStrategy = new();
|
||||
mockStrategy.Setup(s => s.CompactAsync(It.IsAny<MessageGroups>(), It.IsAny<CancellationToken>()))
|
||||
.Callback<MessageGroups, CancellationToken>((groups, _) =>
|
||||
{
|
||||
int excluded = 0;
|
||||
foreach (MessageGroup group in groups.Groups)
|
||||
{
|
||||
if (!group.IsExcluded && group.Kind != MessageGroupKind.System && excluded < 2)
|
||||
{
|
||||
group.IsExcluded = true;
|
||||
excluded++;
|
||||
}
|
||||
}
|
||||
})
|
||||
.ReturnsAsync(true);
|
||||
// [Fact]
|
||||
// public async Task CompactStorageAsync_CompactsStoredMessagesAsync()
|
||||
// {
|
||||
// // Arrange — mock strategy that excludes the two oldest non-system groups
|
||||
// Mock<ICompactionStrategy> mockStrategy = new();
|
||||
// mockStrategy.Setup(s => s.CompactAsync(It.IsAny<MessageIndex>(), It.IsAny<CancellationToken>()))
|
||||
// .Callback<MessageIndex, CancellationToken>((groups, _) =>
|
||||
// {
|
||||
// int excluded = 0;
|
||||
// foreach (MessageGroup group in groups.Groups)
|
||||
// {
|
||||
// if (!group.IsExcluded && group.Kind != MessageGroupKind.System && excluded < 2)
|
||||
// {
|
||||
// group.IsExcluded = true;
|
||||
// excluded++;
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
// .ReturnsAsync(true);
|
||||
|
||||
InMemoryChatHistoryProvider provider = new(new InMemoryChatHistoryProviderOptions
|
||||
{
|
||||
CompactionStrategy = mockStrategy.Object,
|
||||
});
|
||||
// InMemoryChatHistoryProvider provider = new(new InMemoryChatHistoryProviderOptions
|
||||
// {
|
||||
// CompactionStrategy = mockStrategy.Object,
|
||||
// });
|
||||
|
||||
AgentSession session = CreateMockSession();
|
||||
provider.SetMessages(session,
|
||||
[
|
||||
new ChatMessage(ChatRole.User, "First"),
|
||||
new ChatMessage(ChatRole.Assistant, "Response 1"),
|
||||
new ChatMessage(ChatRole.User, "Second"),
|
||||
new ChatMessage(ChatRole.Assistant, "Response 2"),
|
||||
]);
|
||||
// AgentSession session = CreateMockSession();
|
||||
// provider.SetMessages(session,
|
||||
// [
|
||||
// new ChatMessage(ChatRole.User, "First"),
|
||||
// new ChatMessage(ChatRole.Assistant, "Response 1"),
|
||||
// new ChatMessage(ChatRole.User, "Second"),
|
||||
// new ChatMessage(ChatRole.Assistant, "Response 2"),
|
||||
// ]);
|
||||
|
||||
// Act
|
||||
bool result = await provider.CompactStorageAsync(session);
|
||||
// // Act
|
||||
// bool result = await provider.CompactStorageAsync(session);
|
||||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
List<ChatMessage> messages = provider.GetMessages(session);
|
||||
Assert.Equal(2, messages.Count);
|
||||
mockStrategy.Verify(s => s.CompactAsync(It.IsAny<MessageGroups>(), It.IsAny<CancellationToken>()), Times.Once);
|
||||
}
|
||||
// // Assert
|
||||
// Assert.True(result);
|
||||
// List<ChatMessage> messages = provider.GetMessages(session);
|
||||
// Assert.Equal(2, messages.Count);
|
||||
// mockStrategy.Verify(s => s.CompactAsync(It.IsAny<MessageIndex>(), It.IsAny<CancellationToken>()), Times.Once);
|
||||
// }
|
||||
|
||||
[Fact]
|
||||
public async Task CompactStorageAsync_UsesProvidedStrategy_OverDefaultAsync()
|
||||
{
|
||||
// Arrange
|
||||
Mock<ICompactionStrategy> defaultStrategy = new();
|
||||
Mock<ICompactionStrategy> overrideStrategy = new();
|
||||
// [Fact]
|
||||
// public async Task CompactStorageAsync_UsesProvidedStrategy_OverDefaultAsync()
|
||||
// {
|
||||
// // Arrange
|
||||
// Mock<ICompactionStrategy> defaultStrategy = new();
|
||||
// Mock<ICompactionStrategy> overrideStrategy = new();
|
||||
|
||||
overrideStrategy.Setup(s => s.CompactAsync(It.IsAny<MessageGroups>(), It.IsAny<CancellationToken>()))
|
||||
.Callback<MessageGroups, CancellationToken>((groups, _) =>
|
||||
{
|
||||
// Exclude all but the last group
|
||||
for (int i = 0; i < groups.Groups.Count - 1; i++)
|
||||
{
|
||||
groups.Groups[i].IsExcluded = true;
|
||||
}
|
||||
})
|
||||
.ReturnsAsync(true);
|
||||
// overrideStrategy.Setup(s => s.CompactAsync(It.IsAny<MessageIndex>(), It.IsAny<CancellationToken>()))
|
||||
// .Callback<MessageIndex, CancellationToken>((groups, _) =>
|
||||
// {
|
||||
// // Exclude all but the last group
|
||||
// for (int i = 0; i < groups.Groups.Count - 1; i++)
|
||||
// {
|
||||
// groups.Groups[i].IsExcluded = true;
|
||||
// }
|
||||
// })
|
||||
// .ReturnsAsync(true);
|
||||
|
||||
InMemoryChatHistoryProvider provider = new(new InMemoryChatHistoryProviderOptions
|
||||
{
|
||||
CompactionStrategy = defaultStrategy.Object,
|
||||
});
|
||||
// InMemoryChatHistoryProvider provider = new(new InMemoryChatHistoryProviderOptions
|
||||
// {
|
||||
// CompactionStrategy = defaultStrategy.Object,
|
||||
// });
|
||||
|
||||
AgentSession session = CreateMockSession();
|
||||
provider.SetMessages(session,
|
||||
[
|
||||
new ChatMessage(ChatRole.User, "First"),
|
||||
new ChatMessage(ChatRole.User, "Second"),
|
||||
new ChatMessage(ChatRole.User, "Third"),
|
||||
]);
|
||||
// AgentSession session = CreateMockSession();
|
||||
// provider.SetMessages(session,
|
||||
// [
|
||||
// new ChatMessage(ChatRole.User, "First"),
|
||||
// new ChatMessage(ChatRole.User, "Second"),
|
||||
// new ChatMessage(ChatRole.User, "Third"),
|
||||
// ]);
|
||||
|
||||
// Act
|
||||
bool result = await provider.CompactStorageAsync(session, overrideStrategy.Object);
|
||||
// // Act
|
||||
// bool result = await provider.CompactStorageAsync(session, overrideStrategy.Object);
|
||||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
List<ChatMessage> messages = provider.GetMessages(session);
|
||||
Assert.Single(messages);
|
||||
Assert.Equal("Third", messages[0].Text);
|
||||
// // Assert
|
||||
// Assert.True(result);
|
||||
// List<ChatMessage> messages = provider.GetMessages(session);
|
||||
// Assert.Single(messages);
|
||||
// Assert.Equal("Third", messages[0].Text);
|
||||
|
||||
// Verify the override was used, not the default
|
||||
overrideStrategy.Verify(s => s.CompactAsync(It.IsAny<MessageGroups>(), It.IsAny<CancellationToken>()), Times.Once);
|
||||
defaultStrategy.Verify(s => s.CompactAsync(It.IsAny<MessageGroups>(), It.IsAny<CancellationToken>()), Times.Never);
|
||||
}
|
||||
// // Verify the override was used, not the default
|
||||
// overrideStrategy.Verify(s => s.CompactAsync(It.IsAny<MessageIndex>(), It.IsAny<CancellationToken>()), Times.Once);
|
||||
// defaultStrategy.Verify(s => s.CompactAsync(It.IsAny<MessageIndex>(), It.IsAny<CancellationToken>()), Times.Never);
|
||||
// }
|
||||
|
||||
[Fact]
|
||||
public async Task CompactStorageAsync_Throws_WhenNoStrategyAvailableAsync()
|
||||
{
|
||||
// Arrange
|
||||
InMemoryChatHistoryProvider provider = new();
|
||||
AgentSession session = CreateMockSession();
|
||||
// [Fact]
|
||||
// public async Task CompactStorageAsync_Throws_WhenNoStrategyAvailableAsync()
|
||||
// {
|
||||
// // Arrange
|
||||
// InMemoryChatHistoryProvider provider = new();
|
||||
// AgentSession session = CreateMockSession();
|
||||
|
||||
// Act & Assert
|
||||
await Assert.ThrowsAsync<System.InvalidOperationException>(
|
||||
() => provider.CompactStorageAsync(session));
|
||||
}
|
||||
// // Act & Assert
|
||||
// await Assert.ThrowsAsync<System.InvalidOperationException>(
|
||||
// () => provider.CompactStorageAsync(session));
|
||||
// }
|
||||
|
||||
[Fact]
|
||||
public async Task CompactStorageAsync_WithCustomStrategy_AppliesCustomLogicAsync()
|
||||
{
|
||||
// Arrange
|
||||
Mock<ICompactionStrategy> mockStrategy = new();
|
||||
mockStrategy.Setup(s => s.CompactAsync(It.IsAny<MessageGroups>(), It.IsAny<CancellationToken>()))
|
||||
.Callback<MessageGroups, CancellationToken>((groups, _) =>
|
||||
{
|
||||
// Exclude all user groups
|
||||
foreach (MessageGroup group in groups.Groups)
|
||||
{
|
||||
if (group.Kind == MessageGroupKind.User)
|
||||
{
|
||||
group.IsExcluded = true;
|
||||
}
|
||||
}
|
||||
})
|
||||
.ReturnsAsync(true);
|
||||
// [Fact]
|
||||
// public async Task CompactStorageAsync_WithCustomStrategy_AppliesCustomLogicAsync()
|
||||
// {
|
||||
// // Arrange
|
||||
// Mock<ICompactionStrategy> mockStrategy = new();
|
||||
// mockStrategy.Setup(s => s.CompactAsync(It.IsAny<MessageIndex>(), It.IsAny<CancellationToken>()))
|
||||
// .Callback<MessageIndex, CancellationToken>((groups, _) =>
|
||||
// {
|
||||
// // Exclude all user groups
|
||||
// foreach (MessageGroup group in groups.Groups)
|
||||
// {
|
||||
// if (group.Kind == MessageGroupKind.User)
|
||||
// {
|
||||
// group.IsExcluded = true;
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
// .ReturnsAsync(true);
|
||||
|
||||
InMemoryChatHistoryProvider provider = new();
|
||||
AgentSession session = CreateMockSession();
|
||||
provider.SetMessages(session,
|
||||
[
|
||||
new ChatMessage(ChatRole.System, "System"),
|
||||
new ChatMessage(ChatRole.User, "User message"),
|
||||
new ChatMessage(ChatRole.Assistant, "Response"),
|
||||
]);
|
||||
// InMemoryChatHistoryProvider provider = new();
|
||||
// AgentSession session = CreateMockSession();
|
||||
// provider.SetMessages(session,
|
||||
// [
|
||||
// new ChatMessage(ChatRole.System, "System"),
|
||||
// new ChatMessage(ChatRole.User, "User message"),
|
||||
// new ChatMessage(ChatRole.Assistant, "Response"),
|
||||
// ]);
|
||||
|
||||
// Act
|
||||
bool result = await provider.CompactStorageAsync(session, mockStrategy.Object);
|
||||
// // Act
|
||||
// bool result = await provider.CompactStorageAsync(session, mockStrategy.Object);
|
||||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
List<ChatMessage> messages = provider.GetMessages(session);
|
||||
Assert.Equal(2, messages.Count);
|
||||
Assert.Equal(ChatRole.System, messages[0].Role);
|
||||
Assert.Equal(ChatRole.Assistant, messages[1].Role);
|
||||
}
|
||||
}
|
||||
// // Assert
|
||||
// Assert.True(result);
|
||||
// List<ChatMessage> messages = provider.GetMessages(session);
|
||||
// Assert.Equal(2, messages.Count);
|
||||
// Assert.Equal(ChatRole.System, messages[0].Role);
|
||||
// Assert.Equal(ChatRole.Assistant, messages[1].Role);
|
||||
// }
|
||||
//}
|
||||
|
||||
+30
-30
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Agents.AI.Compaction;
|
||||
@@ -7,9 +7,9 @@ using Microsoft.Extensions.AI;
|
||||
namespace Microsoft.Agents.AI.Abstractions.UnitTests.Compaction;
|
||||
|
||||
/// <summary>
|
||||
/// Contains tests for the <see cref="MessageGroups"/> class.
|
||||
/// Contains tests for the <see cref="MessageIndex"/> class.
|
||||
/// </summary>
|
||||
public class MessageGroupsTests
|
||||
public class MessageIndexTests
|
||||
{
|
||||
[Fact]
|
||||
public void Create_EmptyList_ReturnsEmptyGroups()
|
||||
@@ -18,7 +18,7 @@ public class MessageGroupsTests
|
||||
List<ChatMessage> messages = [];
|
||||
|
||||
// Act
|
||||
MessageGroups groups = MessageGroups.Create(messages);
|
||||
MessageIndex groups = MessageIndex.Create(messages);
|
||||
|
||||
// Assert
|
||||
Assert.Empty(groups.Groups);
|
||||
@@ -34,7 +34,7 @@ public class MessageGroupsTests
|
||||
];
|
||||
|
||||
// Act
|
||||
MessageGroups groups = MessageGroups.Create(messages);
|
||||
MessageIndex groups = MessageIndex.Create(messages);
|
||||
|
||||
// Assert
|
||||
Assert.Single(groups.Groups);
|
||||
@@ -52,7 +52,7 @@ public class MessageGroupsTests
|
||||
];
|
||||
|
||||
// Act
|
||||
MessageGroups groups = MessageGroups.Create(messages);
|
||||
MessageIndex groups = MessageIndex.Create(messages);
|
||||
|
||||
// Assert
|
||||
Assert.Single(groups.Groups);
|
||||
@@ -69,7 +69,7 @@ public class MessageGroupsTests
|
||||
];
|
||||
|
||||
// Act
|
||||
MessageGroups groups = MessageGroups.Create(messages);
|
||||
MessageIndex groups = MessageIndex.Create(messages);
|
||||
|
||||
// Assert
|
||||
Assert.Single(groups.Groups);
|
||||
@@ -86,7 +86,7 @@ public class MessageGroupsTests
|
||||
List<ChatMessage> messages = [assistantMessage, toolResult];
|
||||
|
||||
// Act
|
||||
MessageGroups groups = MessageGroups.Create(messages);
|
||||
MessageIndex groups = MessageIndex.Create(messages);
|
||||
|
||||
// Assert
|
||||
Assert.Single(groups.Groups);
|
||||
@@ -109,7 +109,7 @@ public class MessageGroupsTests
|
||||
List<ChatMessage> messages = [systemMsg, userMsg, assistantToolCall, toolResult, assistantText];
|
||||
|
||||
// Act
|
||||
MessageGroups groups = MessageGroups.Create(messages);
|
||||
MessageIndex groups = MessageIndex.Create(messages);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(4, groups.Groups.Count);
|
||||
@@ -134,7 +134,7 @@ public class MessageGroupsTests
|
||||
List<ChatMessage> messages = [assistantToolCall, toolResult1, toolResult2];
|
||||
|
||||
// Act
|
||||
MessageGroups groups = MessageGroups.Create(messages);
|
||||
MessageIndex groups = MessageIndex.Create(messages);
|
||||
|
||||
// Assert
|
||||
Assert.Single(groups.Groups);
|
||||
@@ -150,7 +150,7 @@ public class MessageGroupsTests
|
||||
ChatMessage msg2 = new(ChatRole.Assistant, "Response");
|
||||
ChatMessage msg3 = new(ChatRole.User, "Second");
|
||||
|
||||
MessageGroups groups = MessageGroups.Create([msg1, msg2, msg3]);
|
||||
MessageIndex groups = MessageIndex.Create([msg1, msg2, msg3]);
|
||||
groups.Groups[1].IsExcluded = true;
|
||||
|
||||
// Act
|
||||
@@ -169,7 +169,7 @@ public class MessageGroupsTests
|
||||
ChatMessage msg1 = new(ChatRole.User, "First");
|
||||
ChatMessage msg2 = new(ChatRole.Assistant, "Response");
|
||||
|
||||
MessageGroups groups = MessageGroups.Create([msg1, msg2]);
|
||||
MessageIndex groups = MessageIndex.Create([msg1, msg2]);
|
||||
groups.Groups[0].IsExcluded = true;
|
||||
|
||||
// Act
|
||||
@@ -183,7 +183,7 @@ public class MessageGroupsTests
|
||||
public void IncludedGroupCount_ReflectsExclusions()
|
||||
{
|
||||
// Arrange
|
||||
MessageGroups groups = MessageGroups.Create(
|
||||
MessageIndex groups = MessageIndex.Create(
|
||||
[
|
||||
new ChatMessage(ChatRole.User, "A"),
|
||||
new ChatMessage(ChatRole.Assistant, "B"),
|
||||
@@ -207,7 +207,7 @@ public class MessageGroupsTests
|
||||
List<ChatMessage> messages = [summaryMessage];
|
||||
|
||||
// Act
|
||||
MessageGroups groups = MessageGroups.Create(messages);
|
||||
MessageIndex groups = MessageIndex.Create(messages);
|
||||
|
||||
// Assert
|
||||
Assert.Single(groups.Groups);
|
||||
@@ -227,7 +227,7 @@ public class MessageGroupsTests
|
||||
List<ChatMessage> messages = [systemMsg, summaryMsg, userMsg];
|
||||
|
||||
// Act
|
||||
MessageGroups groups = MessageGroups.Create(messages);
|
||||
MessageIndex groups = MessageIndex.Create(messages);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(3, groups.Groups.Count);
|
||||
@@ -264,7 +264,7 @@ public class MessageGroupsTests
|
||||
public void Create_ComputesByteCount_Utf8()
|
||||
{
|
||||
// Arrange — "Hello" is 5 UTF-8 bytes
|
||||
MessageGroups groups = MessageGroups.Create([new ChatMessage(ChatRole.User, "Hello")]);
|
||||
MessageIndex groups = MessageIndex.Create([new ChatMessage(ChatRole.User, "Hello")]);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(5, groups.Groups[0].ByteCount);
|
||||
@@ -274,7 +274,7 @@ public class MessageGroupsTests
|
||||
public void Create_ComputesByteCount_MultiByteChars()
|
||||
{
|
||||
// Arrange — "café" has a multi-byte 'é' (2 bytes in UTF-8) → 5 bytes total
|
||||
MessageGroups groups = MessageGroups.Create([new ChatMessage(ChatRole.User, "café")]);
|
||||
MessageIndex groups = MessageIndex.Create([new ChatMessage(ChatRole.User, "café")]);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(5, groups.Groups[0].ByteCount);
|
||||
@@ -286,7 +286,7 @@ public class MessageGroupsTests
|
||||
// Arrange — ToolCall group: assistant (tool call, null text) + tool result "OK" (2 bytes)
|
||||
ChatMessage assistantMsg = new(ChatRole.Assistant, [new FunctionCallContent("call1", "fn")]);
|
||||
ChatMessage toolResult = new(ChatRole.Tool, "OK");
|
||||
MessageGroups groups = MessageGroups.Create([assistantMsg, toolResult]);
|
||||
MessageIndex groups = MessageIndex.Create([assistantMsg, toolResult]);
|
||||
|
||||
// Assert — single ToolCall group with 2 messages
|
||||
Assert.Single(groups.Groups);
|
||||
@@ -298,7 +298,7 @@ public class MessageGroupsTests
|
||||
public void Create_DefaultTokenCount_IsHeuristic()
|
||||
{
|
||||
// Arrange — "Hello world test data!" = 22 UTF-8 bytes → 22 / 4 = 5 estimated tokens
|
||||
MessageGroups groups = MessageGroups.Create([new ChatMessage(ChatRole.User, "Hello world test data!")]);
|
||||
MessageIndex groups = MessageIndex.Create([new ChatMessage(ChatRole.User, "Hello world test data!")]);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(22, groups.Groups[0].ByteCount);
|
||||
@@ -311,7 +311,7 @@ public class MessageGroupsTests
|
||||
// Arrange — message with no text (e.g., pure function call)
|
||||
ChatMessage msg = new(ChatRole.Assistant, [new FunctionCallContent("call1", "get_weather")]);
|
||||
ChatMessage tool = new(ChatRole.Tool, string.Empty);
|
||||
MessageGroups groups = MessageGroups.Create([msg, tool]);
|
||||
MessageIndex groups = MessageIndex.Create([msg, tool]);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(2, groups.Groups[0].MessageCount);
|
||||
@@ -323,7 +323,7 @@ public class MessageGroupsTests
|
||||
public void TotalAggregates_SumAllGroups()
|
||||
{
|
||||
// Arrange
|
||||
MessageGroups groups = MessageGroups.Create(
|
||||
MessageIndex groups = MessageIndex.Create(
|
||||
[
|
||||
new ChatMessage(ChatRole.User, "AAAA"), // 4 bytes
|
||||
new ChatMessage(ChatRole.Assistant, "BBBB"), // 4 bytes
|
||||
@@ -342,7 +342,7 @@ public class MessageGroupsTests
|
||||
public void IncludedAggregates_ExcludeMarkedGroups()
|
||||
{
|
||||
// Arrange
|
||||
MessageGroups groups = MessageGroups.Create(
|
||||
MessageIndex groups = MessageIndex.Create(
|
||||
[
|
||||
new ChatMessage(ChatRole.User, "AAAA"), // 4 bytes
|
||||
new ChatMessage(ChatRole.Assistant, "BBBB"), // 4 bytes
|
||||
@@ -369,7 +369,7 @@ public class MessageGroupsTests
|
||||
ChatMessage assistantMsg = new(ChatRole.Assistant, [new FunctionCallContent("call1", "fn")]);
|
||||
ChatMessage toolResult = new(ChatRole.Tool, "OK");
|
||||
|
||||
MessageGroups groups = MessageGroups.Create([assistantMsg, toolResult]);
|
||||
MessageIndex groups = MessageIndex.Create([assistantMsg, toolResult]);
|
||||
|
||||
// Assert — single group with 2 messages
|
||||
Assert.Single(groups.Groups);
|
||||
@@ -383,7 +383,7 @@ public class MessageGroupsTests
|
||||
public void Create_AssignsTurnIndices_SingleTurn()
|
||||
{
|
||||
// Arrange — System (no turn), User + Assistant = turn 1
|
||||
MessageGroups groups = MessageGroups.Create(
|
||||
MessageIndex groups = MessageIndex.Create(
|
||||
[
|
||||
new ChatMessage(ChatRole.System, "You are helpful."),
|
||||
new ChatMessage(ChatRole.User, "Hello"),
|
||||
@@ -402,7 +402,7 @@ public class MessageGroupsTests
|
||||
public void Create_AssignsTurnIndices_MultiTurn()
|
||||
{
|
||||
// Arrange — 3 user turns
|
||||
MessageGroups groups = MessageGroups.Create(
|
||||
MessageIndex groups = MessageIndex.Create(
|
||||
[
|
||||
new ChatMessage(ChatRole.System, "System prompt."),
|
||||
new ChatMessage(ChatRole.User, "Q1"),
|
||||
@@ -429,7 +429,7 @@ public class MessageGroupsTests
|
||||
ChatMessage assistantToolCall = new(ChatRole.Assistant, [new FunctionCallContent("call1", "get_weather")]);
|
||||
ChatMessage toolResult = new(ChatRole.Tool, "Sunny");
|
||||
|
||||
MessageGroups groups = MessageGroups.Create(
|
||||
MessageIndex groups = MessageIndex.Create(
|
||||
[
|
||||
new ChatMessage(ChatRole.User, "What's the weather?"),
|
||||
assistantToolCall,
|
||||
@@ -449,7 +449,7 @@ public class MessageGroupsTests
|
||||
public void GetTurnGroups_ReturnsGroupsForSpecificTurn()
|
||||
{
|
||||
// Arrange
|
||||
MessageGroups groups = MessageGroups.Create(
|
||||
MessageIndex groups = MessageIndex.Create(
|
||||
[
|
||||
new ChatMessage(ChatRole.System, "System."),
|
||||
new ChatMessage(ChatRole.User, "Q1"),
|
||||
@@ -475,7 +475,7 @@ public class MessageGroupsTests
|
||||
public void IncludedTurnCount_ReflectsExclusions()
|
||||
{
|
||||
// Arrange — 2 turns, exclude all groups in turn 1
|
||||
MessageGroups groups = MessageGroups.Create(
|
||||
MessageIndex groups = MessageIndex.Create(
|
||||
[
|
||||
new ChatMessage(ChatRole.User, "Q1"),
|
||||
new ChatMessage(ChatRole.Assistant, "A1"),
|
||||
@@ -495,7 +495,7 @@ public class MessageGroupsTests
|
||||
public void TotalTurnCount_ZeroWhenNoUserMessages()
|
||||
{
|
||||
// Arrange — only system messages
|
||||
MessageGroups groups = MessageGroups.Create(
|
||||
MessageIndex groups = MessageIndex.Create(
|
||||
[
|
||||
new ChatMessage(ChatRole.System, "System."),
|
||||
]);
|
||||
@@ -509,7 +509,7 @@ public class MessageGroupsTests
|
||||
public void IncludedTurnCount_PartialExclusion_StillCountsTurn()
|
||||
{
|
||||
// Arrange — turn 1 has 2 groups, only one excluded
|
||||
MessageGroups groups = MessageGroups.Create(
|
||||
MessageIndex groups = MessageIndex.Create(
|
||||
[
|
||||
new ChatMessage(ChatRole.User, "Q1"),
|
||||
new ChatMessage(ChatRole.Assistant, "A1"),
|
||||
+46
-46
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
@@ -20,17 +20,17 @@ public class PipelineCompactionStrategyTests
|
||||
// Arrange
|
||||
List<string> executionOrder = [];
|
||||
Mock<ICompactionStrategy> strategy1 = new();
|
||||
strategy1.Setup(s => s.CompactAsync(It.IsAny<MessageGroups>(), It.IsAny<CancellationToken>()))
|
||||
strategy1.Setup(s => s.CompactAsync(It.IsAny<MessageIndex>(), It.IsAny<CancellationToken>()))
|
||||
.Callback(() => executionOrder.Add("first"))
|
||||
.ReturnsAsync(false);
|
||||
|
||||
Mock<ICompactionStrategy> strategy2 = new();
|
||||
strategy2.Setup(s => s.CompactAsync(It.IsAny<MessageGroups>(), It.IsAny<CancellationToken>()))
|
||||
strategy2.Setup(s => s.CompactAsync(It.IsAny<MessageIndex>(), It.IsAny<CancellationToken>()))
|
||||
.Callback(() => executionOrder.Add("second"))
|
||||
.ReturnsAsync(false);
|
||||
|
||||
PipelineCompactionStrategy pipeline = new(strategy1.Object, strategy2.Object);
|
||||
MessageGroups groups = MessageGroups.Create([new ChatMessage(ChatRole.User, "Hello")]);
|
||||
PipelineCompactionStrategy pipeline = new([strategy1.Object, strategy2.Object]);
|
||||
MessageIndex groups = MessageIndex.Create([new ChatMessage(ChatRole.User, "Hello")]);
|
||||
|
||||
// Act
|
||||
await pipeline.CompactAsync(groups);
|
||||
@@ -44,11 +44,11 @@ public class PipelineCompactionStrategyTests
|
||||
{
|
||||
// Arrange
|
||||
Mock<ICompactionStrategy> strategy1 = new();
|
||||
strategy1.Setup(s => s.CompactAsync(It.IsAny<MessageGroups>(), It.IsAny<CancellationToken>()))
|
||||
strategy1.Setup(s => s.CompactAsync(It.IsAny<MessageIndex>(), It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync(false);
|
||||
|
||||
PipelineCompactionStrategy pipeline = new(strategy1.Object);
|
||||
MessageGroups groups = MessageGroups.Create([new ChatMessage(ChatRole.User, "Hello")]);
|
||||
PipelineCompactionStrategy pipeline = new([strategy1.Object]);
|
||||
MessageIndex groups = MessageIndex.Create([new ChatMessage(ChatRole.User, "Hello")]);
|
||||
|
||||
// Act
|
||||
bool result = await pipeline.CompactAsync(groups);
|
||||
@@ -62,15 +62,15 @@ public class PipelineCompactionStrategyTests
|
||||
{
|
||||
// Arrange
|
||||
Mock<ICompactionStrategy> strategy1 = new();
|
||||
strategy1.Setup(s => s.CompactAsync(It.IsAny<MessageGroups>(), It.IsAny<CancellationToken>()))
|
||||
strategy1.Setup(s => s.CompactAsync(It.IsAny<MessageIndex>(), It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync(false);
|
||||
|
||||
Mock<ICompactionStrategy> strategy2 = new();
|
||||
strategy2.Setup(s => s.CompactAsync(It.IsAny<MessageGroups>(), It.IsAny<CancellationToken>()))
|
||||
strategy2.Setup(s => s.CompactAsync(It.IsAny<MessageIndex>(), It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync(true);
|
||||
|
||||
PipelineCompactionStrategy pipeline = new(strategy1.Object, strategy2.Object);
|
||||
MessageGroups groups = MessageGroups.Create([new ChatMessage(ChatRole.User, "Hello")]);
|
||||
PipelineCompactionStrategy pipeline = new([strategy1.Object, strategy2.Object]);
|
||||
MessageIndex groups = MessageIndex.Create([new ChatMessage(ChatRole.User, "Hello")]);
|
||||
|
||||
// Act
|
||||
bool result = await pipeline.CompactAsync(groups);
|
||||
@@ -84,22 +84,22 @@ public class PipelineCompactionStrategyTests
|
||||
{
|
||||
// Arrange
|
||||
Mock<ICompactionStrategy> strategy1 = new();
|
||||
strategy1.Setup(s => s.CompactAsync(It.IsAny<MessageGroups>(), It.IsAny<CancellationToken>()))
|
||||
strategy1.Setup(s => s.CompactAsync(It.IsAny<MessageIndex>(), It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync(true);
|
||||
|
||||
Mock<ICompactionStrategy> strategy2 = new();
|
||||
strategy2.Setup(s => s.CompactAsync(It.IsAny<MessageGroups>(), It.IsAny<CancellationToken>()))
|
||||
strategy2.Setup(s => s.CompactAsync(It.IsAny<MessageIndex>(), It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync(false);
|
||||
|
||||
PipelineCompactionStrategy pipeline = new(strategy1.Object, strategy2.Object);
|
||||
MessageGroups groups = MessageGroups.Create([new ChatMessage(ChatRole.User, "Hello")]);
|
||||
PipelineCompactionStrategy pipeline = new([strategy1.Object, strategy2.Object]);
|
||||
MessageIndex groups = MessageIndex.Create([new ChatMessage(ChatRole.User, "Hello")]);
|
||||
|
||||
// Act
|
||||
await pipeline.CompactAsync(groups);
|
||||
|
||||
// Assert — both strategies were called
|
||||
strategy1.Verify(s => s.CompactAsync(It.IsAny<MessageGroups>(), It.IsAny<CancellationToken>()), Times.Once);
|
||||
strategy2.Verify(s => s.CompactAsync(It.IsAny<MessageGroups>(), It.IsAny<CancellationToken>()), Times.Once);
|
||||
strategy1.Verify(s => s.CompactAsync(It.IsAny<MessageIndex>(), It.IsAny<CancellationToken>()), Times.Once);
|
||||
strategy2.Verify(s => s.CompactAsync(It.IsAny<MessageIndex>(), It.IsAny<CancellationToken>()), Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -107,8 +107,8 @@ public class PipelineCompactionStrategyTests
|
||||
{
|
||||
// Arrange — first strategy reduces to target
|
||||
Mock<ICompactionStrategy> strategy1 = new();
|
||||
strategy1.Setup(s => s.CompactAsync(It.IsAny<MessageGroups>(), It.IsAny<CancellationToken>()))
|
||||
.Callback<MessageGroups, CancellationToken>((groups, _) =>
|
||||
strategy1.Setup(s => s.CompactAsync(It.IsAny<MessageIndex>(), It.IsAny<CancellationToken>()))
|
||||
.Callback<MessageIndex, CancellationToken>((groups, _) =>
|
||||
{
|
||||
// Exclude the first group to bring count down
|
||||
groups.Groups[0].IsExcluded = true;
|
||||
@@ -116,16 +116,16 @@ public class PipelineCompactionStrategyTests
|
||||
.ReturnsAsync(true);
|
||||
|
||||
Mock<ICompactionStrategy> strategy2 = new();
|
||||
strategy2.Setup(s => s.CompactAsync(It.IsAny<MessageGroups>(), It.IsAny<CancellationToken>()))
|
||||
strategy2.Setup(s => s.CompactAsync(It.IsAny<MessageIndex>(), It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync(false);
|
||||
|
||||
PipelineCompactionStrategy pipeline = new(strategy1.Object, strategy2.Object)
|
||||
PipelineCompactionStrategy pipeline = new([strategy1.Object, strategy2.Object])
|
||||
{
|
||||
EarlyStop = true,
|
||||
TargetIncludedGroupCount = 2,
|
||||
};
|
||||
|
||||
MessageGroups groups = MessageGroups.Create(
|
||||
MessageIndex groups = MessageIndex.Create(
|
||||
[
|
||||
new ChatMessage(ChatRole.User, "First"),
|
||||
new ChatMessage(ChatRole.Assistant, "Response"),
|
||||
@@ -137,8 +137,8 @@ public class PipelineCompactionStrategyTests
|
||||
|
||||
// Assert — strategy2 should not have been called
|
||||
Assert.True(result);
|
||||
strategy1.Verify(s => s.CompactAsync(It.IsAny<MessageGroups>(), It.IsAny<CancellationToken>()), Times.Once);
|
||||
strategy2.Verify(s => s.CompactAsync(It.IsAny<MessageGroups>(), It.IsAny<CancellationToken>()), Times.Never);
|
||||
strategy1.Verify(s => s.CompactAsync(It.IsAny<MessageIndex>(), It.IsAny<CancellationToken>()), Times.Once);
|
||||
strategy2.Verify(s => s.CompactAsync(It.IsAny<MessageIndex>(), It.IsAny<CancellationToken>()), Times.Never);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -146,20 +146,20 @@ public class PipelineCompactionStrategyTests
|
||||
{
|
||||
// Arrange — first strategy does NOT bring count to target
|
||||
Mock<ICompactionStrategy> strategy1 = new();
|
||||
strategy1.Setup(s => s.CompactAsync(It.IsAny<MessageGroups>(), It.IsAny<CancellationToken>()))
|
||||
strategy1.Setup(s => s.CompactAsync(It.IsAny<MessageIndex>(), It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync(false);
|
||||
|
||||
Mock<ICompactionStrategy> strategy2 = new();
|
||||
strategy2.Setup(s => s.CompactAsync(It.IsAny<MessageGroups>(), It.IsAny<CancellationToken>()))
|
||||
strategy2.Setup(s => s.CompactAsync(It.IsAny<MessageIndex>(), It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync(false);
|
||||
|
||||
PipelineCompactionStrategy pipeline = new(strategy1.Object, strategy2.Object)
|
||||
PipelineCompactionStrategy pipeline = new([strategy1.Object, strategy2.Object])
|
||||
{
|
||||
EarlyStop = true,
|
||||
TargetIncludedGroupCount = 1,
|
||||
};
|
||||
|
||||
MessageGroups groups = MessageGroups.Create(
|
||||
MessageIndex groups = MessageIndex.Create(
|
||||
[
|
||||
new ChatMessage(ChatRole.User, "First"),
|
||||
new ChatMessage(ChatRole.User, "Second"),
|
||||
@@ -170,8 +170,8 @@ public class PipelineCompactionStrategyTests
|
||||
await pipeline.CompactAsync(groups);
|
||||
|
||||
// Assert — both strategies were called since target was never reached
|
||||
strategy1.Verify(s => s.CompactAsync(It.IsAny<MessageGroups>(), It.IsAny<CancellationToken>()), Times.Once);
|
||||
strategy2.Verify(s => s.CompactAsync(It.IsAny<MessageGroups>(), It.IsAny<CancellationToken>()), Times.Once);
|
||||
strategy1.Verify(s => s.CompactAsync(It.IsAny<MessageIndex>(), It.IsAny<CancellationToken>()), Times.Once);
|
||||
strategy2.Verify(s => s.CompactAsync(It.IsAny<MessageIndex>(), It.IsAny<CancellationToken>()), Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -179,27 +179,27 @@ public class PipelineCompactionStrategyTests
|
||||
{
|
||||
// Arrange
|
||||
Mock<ICompactionStrategy> strategy1 = new();
|
||||
strategy1.Setup(s => s.CompactAsync(It.IsAny<MessageGroups>(), It.IsAny<CancellationToken>()))
|
||||
strategy1.Setup(s => s.CompactAsync(It.IsAny<MessageIndex>(), It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync(true);
|
||||
|
||||
Mock<ICompactionStrategy> strategy2 = new();
|
||||
strategy2.Setup(s => s.CompactAsync(It.IsAny<MessageGroups>(), It.IsAny<CancellationToken>()))
|
||||
strategy2.Setup(s => s.CompactAsync(It.IsAny<MessageIndex>(), It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync(false);
|
||||
|
||||
PipelineCompactionStrategy pipeline = new(strategy1.Object, strategy2.Object)
|
||||
PipelineCompactionStrategy pipeline = new([strategy1.Object, strategy2.Object])
|
||||
{
|
||||
EarlyStop = true,
|
||||
// TargetIncludedGroupCount is null
|
||||
};
|
||||
|
||||
MessageGroups groups = MessageGroups.Create([new ChatMessage(ChatRole.User, "Hello")]);
|
||||
MessageIndex groups = MessageIndex.Create([new ChatMessage(ChatRole.User, "Hello")]);
|
||||
|
||||
// Act
|
||||
await pipeline.CompactAsync(groups);
|
||||
|
||||
// Assert — both strategies called because no target to check against
|
||||
strategy1.Verify(s => s.CompactAsync(It.IsAny<MessageGroups>(), It.IsAny<CancellationToken>()), Times.Once);
|
||||
strategy2.Verify(s => s.CompactAsync(It.IsAny<MessageGroups>(), It.IsAny<CancellationToken>()), Times.Once);
|
||||
strategy1.Verify(s => s.CompactAsync(It.IsAny<MessageIndex>(), It.IsAny<CancellationToken>()), Times.Once);
|
||||
strategy2.Verify(s => s.CompactAsync(It.IsAny<MessageIndex>(), It.IsAny<CancellationToken>()), Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -207,8 +207,8 @@ public class PipelineCompactionStrategyTests
|
||||
{
|
||||
// Arrange — pipeline: first exclude oldest 2 non-system groups, then exclude 2 more
|
||||
Mock<ICompactionStrategy> phase1 = new();
|
||||
phase1.Setup(s => s.CompactAsync(It.IsAny<MessageGroups>(), It.IsAny<CancellationToken>()))
|
||||
.Callback<MessageGroups, CancellationToken>((groups, _) =>
|
||||
phase1.Setup(s => s.CompactAsync(It.IsAny<MessageIndex>(), It.IsAny<CancellationToken>()))
|
||||
.Callback<MessageIndex, CancellationToken>((groups, _) =>
|
||||
{
|
||||
int excluded = 0;
|
||||
foreach (MessageGroup group in groups.Groups)
|
||||
@@ -223,8 +223,8 @@ public class PipelineCompactionStrategyTests
|
||||
.ReturnsAsync(true);
|
||||
|
||||
Mock<ICompactionStrategy> phase2 = new();
|
||||
phase2.Setup(s => s.CompactAsync(It.IsAny<MessageGroups>(), It.IsAny<CancellationToken>()))
|
||||
.Callback<MessageGroups, CancellationToken>((groups, _) =>
|
||||
phase2.Setup(s => s.CompactAsync(It.IsAny<MessageIndex>(), It.IsAny<CancellationToken>()))
|
||||
.Callback<MessageIndex, CancellationToken>((groups, _) =>
|
||||
{
|
||||
int excluded = 0;
|
||||
foreach (MessageGroup group in groups.Groups)
|
||||
@@ -238,9 +238,9 @@ public class PipelineCompactionStrategyTests
|
||||
})
|
||||
.ReturnsAsync(true);
|
||||
|
||||
PipelineCompactionStrategy pipeline = new(phase1.Object, phase2.Object);
|
||||
PipelineCompactionStrategy pipeline = new([phase1.Object, phase2.Object]);
|
||||
|
||||
MessageGroups groups = MessageGroups.Create(
|
||||
MessageIndex groups = MessageIndex.Create(
|
||||
[
|
||||
new ChatMessage(ChatRole.System, "You are helpful."),
|
||||
new ChatMessage(ChatRole.User, "Q1"),
|
||||
@@ -262,8 +262,8 @@ public class PipelineCompactionStrategyTests
|
||||
Assert.Equal("You are helpful.", included[0].Text);
|
||||
Assert.Equal("Q3", included[1].Text);
|
||||
|
||||
phase1.Verify(s => s.CompactAsync(It.IsAny<MessageGroups>(), It.IsAny<CancellationToken>()), Times.Once);
|
||||
phase2.Verify(s => s.CompactAsync(It.IsAny<MessageGroups>(), It.IsAny<CancellationToken>()), Times.Once);
|
||||
phase1.Verify(s => s.CompactAsync(It.IsAny<MessageIndex>(), It.IsAny<CancellationToken>()), Times.Once);
|
||||
phase2.Verify(s => s.CompactAsync(It.IsAny<MessageIndex>(), It.IsAny<CancellationToken>()), Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -271,7 +271,7 @@ public class PipelineCompactionStrategyTests
|
||||
{
|
||||
// Arrange
|
||||
PipelineCompactionStrategy pipeline = new(new List<ICompactionStrategy>());
|
||||
MessageGroups groups = MessageGroups.Create([new ChatMessage(ChatRole.User, "Hello")]);
|
||||
MessageIndex groups = MessageIndex.Create([new ChatMessage(ChatRole.User, "Hello")]);
|
||||
|
||||
// Act
|
||||
bool result = await pipeline.CompactAsync(groups);
|
||||
|
||||
+9
-9
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Agents.AI.Compaction;
|
||||
@@ -16,7 +16,7 @@ public class TruncationCompactionStrategyTests
|
||||
{
|
||||
// Arrange
|
||||
TruncationCompactionStrategy strategy = new(maxGroups: 5);
|
||||
MessageGroups groups = MessageGroups.Create(
|
||||
MessageIndex groups = MessageIndex.Create(
|
||||
[
|
||||
new ChatMessage(ChatRole.User, "Hello"),
|
||||
new ChatMessage(ChatRole.Assistant, "Hi!"),
|
||||
@@ -35,7 +35,7 @@ public class TruncationCompactionStrategyTests
|
||||
{
|
||||
// Arrange
|
||||
TruncationCompactionStrategy strategy = new(maxGroups: 2);
|
||||
MessageGroups groups = MessageGroups.Create(
|
||||
MessageIndex groups = MessageIndex.Create(
|
||||
[
|
||||
new ChatMessage(ChatRole.User, "Hello"),
|
||||
new ChatMessage(ChatRole.Assistant, "Hi!"),
|
||||
@@ -58,7 +58,7 @@ public class TruncationCompactionStrategyTests
|
||||
ChatMessage msg3 = new(ChatRole.User, "Second");
|
||||
ChatMessage msg4 = new(ChatRole.Assistant, "Response 2");
|
||||
|
||||
MessageGroups groups = MessageGroups.Create([msg1, msg2, msg3, msg4]);
|
||||
MessageIndex groups = MessageIndex.Create([msg1, msg2, msg3, msg4]);
|
||||
|
||||
// Act
|
||||
bool result = await strategy.CompactAsync(groups);
|
||||
@@ -82,7 +82,7 @@ public class TruncationCompactionStrategyTests
|
||||
ChatMessage msg2 = new(ChatRole.Assistant, "Response 1");
|
||||
ChatMessage msg3 = new(ChatRole.User, "Second");
|
||||
|
||||
MessageGroups groups = MessageGroups.Create([systemMsg, msg1, msg2, msg3]);
|
||||
MessageIndex groups = MessageIndex.Create([systemMsg, msg1, msg2, msg3]);
|
||||
|
||||
// Act
|
||||
bool result = await strategy.CompactAsync(groups);
|
||||
@@ -109,7 +109,7 @@ public class TruncationCompactionStrategyTests
|
||||
ChatMessage msg2 = new(ChatRole.Assistant, "Response");
|
||||
ChatMessage msg3 = new(ChatRole.User, "Second");
|
||||
|
||||
MessageGroups groups = MessageGroups.Create([systemMsg, msg1, msg2, msg3]);
|
||||
MessageIndex groups = MessageIndex.Create([systemMsg, msg1, msg2, msg3]);
|
||||
|
||||
// Act
|
||||
bool result = await strategy.CompactAsync(groups);
|
||||
@@ -133,7 +133,7 @@ public class TruncationCompactionStrategyTests
|
||||
ChatMessage toolResult = new(ChatRole.Tool, "Sunny");
|
||||
ChatMessage finalResponse = new(ChatRole.User, "Thanks!");
|
||||
|
||||
MessageGroups groups = MessageGroups.Create([assistantToolCall, toolResult, finalResponse]);
|
||||
MessageIndex groups = MessageIndex.Create([assistantToolCall, toolResult, finalResponse]);
|
||||
|
||||
// Act
|
||||
bool result = await strategy.CompactAsync(groups);
|
||||
@@ -152,7 +152,7 @@ public class TruncationCompactionStrategyTests
|
||||
{
|
||||
// Arrange
|
||||
TruncationCompactionStrategy strategy = new(maxGroups: 1);
|
||||
MessageGroups groups = MessageGroups.Create(
|
||||
MessageIndex groups = MessageIndex.Create(
|
||||
[
|
||||
new ChatMessage(ChatRole.User, "Old"),
|
||||
new ChatMessage(ChatRole.User, "New"),
|
||||
@@ -171,7 +171,7 @@ public class TruncationCompactionStrategyTests
|
||||
{
|
||||
// Arrange
|
||||
TruncationCompactionStrategy strategy = new(maxGroups: 1);
|
||||
MessageGroups groups = MessageGroups.Create(
|
||||
MessageIndex groups = MessageIndex.Create(
|
||||
[
|
||||
new ChatMessage(ChatRole.User, "Already excluded"),
|
||||
new ChatMessage(ChatRole.User, "Included 1"),
|
||||
|
||||
Reference in New Issue
Block a user