using AxCopilot.Models; using AxCopilot.Services.Agent; using FluentAssertions; using Xunit; namespace AxCopilot.Tests.Services; public class AgentQueryContextBuilderTests { [Fact] public void Build_ShouldPopulateMissingToolResultPreviewBeforeCreatingQueryView() { var longContent = new string('Z', 1800); var sourceMessages = new List { new() { MsgId = "tool-source-1", Role = "user", Content = $$"""{"type":"tool_result","tool_use_id":"call-view","tool_name":"file_read","content":"{{longContent}}"}""", QueryPreviewContent = """{"type":"tool_result","tool_use_id":"call-view","tool_name":"file_read","content":"preview-view"}""" }, new() { MsgId = "tool-source-2", Role = "user", Content = $$"""{"type":"tool_result","tool_use_id":"call-view","tool_name":"file_read","content":"{{longContent}}"}""" }, new() { MsgId = "tail-1", Role = "assistant", Content = "recent tail" } }; var result = AgentQueryContextBuilder.Build(sourceMessages); sourceMessages[1].QueryPreviewContent.Should().Be(sourceMessages[0].QueryPreviewContent); result.Messages[1].QueryPreviewContent.Should().Be(sourceMessages[0].QueryPreviewContent); } [Fact] public void Build_ShouldSynthesizeToolResultPreview_WhenNoStoredPreviewExists() { var longContent = string.Join(' ', Enumerable.Repeat("long tool output", 120)); var sourceMessages = new List { new() { MsgId = "tool-source-1", Role = "user", Content = $$"""{"type":"tool_result","tool_use_id":"call-synth-view","tool_name":"file_read","content":"{{longContent}}"}""" }, new() { MsgId = "tail-1", Role = "assistant", Content = "recent tail" } }; var result = AgentQueryContextBuilder.Build(sourceMessages); sourceMessages[0].QueryPreviewContent.Should().NotBeNullOrWhiteSpace(); sourceMessages[0].QueryPreviewContent.Should().Contain("call-synth-view"); result.Messages.Should().Contain(message => message.QueryPreviewContent != null && message.QueryPreviewContent.Contains("call-synth-view", StringComparison.OrdinalIgnoreCase)); } [Fact] public void Build_ShouldExposeCodeProfileMetadata() { var sourceMessages = new List { new() { MsgId = "tool-source-1", Role = "user", Content = """{"type":"tool_result","tool_use_id":"call-code","tool_name":"build_run","content":"short"}""" }, new() { MsgId = "tail-1", Role = "assistant", Content = "recent tail" } }; var result = AgentQueryContextBuilder.Build( sourceMessages, AgentQueryContextBuilder.AgentQueryContextBuildOptions.CreateCodeDefault()); result.ProfileName.Should().Be("code"); result.ProtectedRecentNonSystemMessages.Should().BeGreaterThan(8); result.ToolResultAggregateBudgetChars.Should().BeGreaterThan(AgentToolResultBudget.DefaultAggregateBudgetChars); } [Fact] public void Build_ShouldRestoreRecentCompactedToolSnippetsIntoPostCompactContextMessage() { var sourceMessages = new List { new() { MsgId = "tool-call-1", Role = "assistant", Content = """{"_tool_use_blocks":[{"type":"tool_use","id":"call-restore","name":"file_read","input":{"path":"MainWindow.xaml"}}]}""" }, new() { MsgId = "tool-result-1", Role = "user", Content = """{"type":"tool_result","tool_use_id":"call-restore","tool_name":"file_read","content":""}""" }, new() { MsgId = "boundary-1", Role = "system", MetaKind = "microcompact_boundary", Content = "[previous conversation summary]" }, new() { MsgId = "tail-1", Role = "assistant", Content = "recent tail" } }; var result = AgentQueryContextBuilder.Build(sourceMessages); var postCompactMessage = result.Messages.Single(message => message.MetaKind == "post_compact_context"); postCompactMessage.Content.Should().Contain("recent compacted tool trace:"); postCompactMessage.Content.Should().Contain("file_read result:"); } }