?? ?? tool_result preview ??? ???? golden workbook ??? ??
?? ?? - ??, ??, ?? ?? tool_result preview? ??? ??? ???? replacement state? ?? ??? ? ??? ??? ?? ??? ?? - XLSX ?? ?? ??? ?? ?? ?? workbook golden ??? ??? summary/dashboard/detail ??? ????? ?? ?? ???? - AgentMessageInvariantHelper? synthetic tool_result preview ?? ??? ??? QueryPreviewContent? ?? ?? ?? ??? tool_use_id, tool_name, ??? content/output/error ?? preview? ????? ?? - BuildToolResultPreviewMap? ?? preview? ?? ???? ?? ?? synthetic preview? ?? ??? ?? - AgentMessageInvariantHelperTests? ??? preview? ?? long tool_result? synthetic preview? ???? ??? explicit preview ?? ?? ??? ?? ?? - AgentQueryContextBuilderTests? synthetic preview? query view ?? ? ?? ???? ???? ????? ?? - ExcelSkillGoldenWorkbookTests? ??? summary/dashboard/detail, formula, data validation, conditional formatting? ??? ?? ?? workbook? Needs work: none ? Repair guide: none? ????? ?? - README.md? docs/DEVELOPMENT.md? 2026-04-15 09:36 (KST) ?? ?? ??? ?? ??? ?? ?? ?? - dotnet build src/AxCopilot/AxCopilot.csproj -c Release -v minimal -p:OutputPath=bin\\verify_preview_golden_finish\\ -p:IntermediateOutputPath=obj\\verify_preview_golden_finish\\ : ?? 0 / ?? 0 - dotnet test src/AxCopilot.Tests/AxCopilot.Tests.csproj -c Release -v minimal --filter "AgentMessageInvariantHelperTests|AgentQueryContextBuilderTests|AgentQueuedCommandProjectorTests|ExcelSkillGoldenWorkbookTests|ExcelSkillDashboardSummaryTests|PptxSkillGoldenDeckTests" -p:OutputPath=bin\\verify_preview_golden_finish_tests\\ -p:IntermediateOutputPath=obj\\verify_preview_golden_finish_tests\\ : ?? 10
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
using AxCopilot.Models;
|
||||
using AxCopilot.Services.Agent;
|
||||
using FluentAssertions;
|
||||
using Xunit;
|
||||
|
||||
namespace AxCopilot.Tests.Services;
|
||||
|
||||
public class AgentMessageInvariantHelperTests
|
||||
{
|
||||
[Fact]
|
||||
public void PopulateMissingToolResultPreviews_ShouldSynthesizePreview_WhenNoStoredPreviewExists()
|
||||
{
|
||||
var longContent = string.Join(' ', Enumerable.Repeat("Detailed output row for recovery.", 40));
|
||||
var messages = new List<ChatMessage>
|
||||
{
|
||||
new()
|
||||
{
|
||||
MsgId = "tool-result-1",
|
||||
Role = "user",
|
||||
Content = $$"""{"type":"tool_result","tool_use_id":"call-synth","tool_name":"file_read","content":"{{longContent}}"}"""
|
||||
}
|
||||
};
|
||||
|
||||
var changed = AgentMessageInvariantHelper.PopulateMissingToolResultPreviews(messages);
|
||||
|
||||
changed.Should().BeTrue();
|
||||
messages[0].QueryPreviewContent.Should().NotBeNullOrWhiteSpace();
|
||||
messages[0].QueryPreviewContent.Should().Contain("call-synth");
|
||||
messages[0].QueryPreviewContent.Should().Contain("...");
|
||||
messages[0].QueryPreviewContent.Should().NotContain(longContent);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BuildToolResultPreviewMap_ShouldPreferExplicitPreview_WhenAvailable()
|
||||
{
|
||||
var explicitPreview = """{"type":"tool_result","tool_use_id":"call-explicit","tool_name":"file_read","content":"preview"}""";
|
||||
var messages = new List<ChatMessage>
|
||||
{
|
||||
new()
|
||||
{
|
||||
MsgId = "tool-result-1",
|
||||
Role = "user",
|
||||
Content = """{"type":"tool_result","tool_use_id":"call-explicit","tool_name":"file_read","content":"long output content"}""",
|
||||
QueryPreviewContent = explicitPreview
|
||||
},
|
||||
new()
|
||||
{
|
||||
MsgId = "tool-result-2",
|
||||
Role = "user",
|
||||
Content = """{"type":"tool_result","tool_use_id":"call-explicit","tool_name":"file_read","content":"another long output content"}"""
|
||||
}
|
||||
};
|
||||
|
||||
var map = AgentMessageInvariantHelper.BuildToolResultPreviewMap(messages);
|
||||
|
||||
map["call-explicit"].Should().Be(explicitPreview);
|
||||
}
|
||||
}
|
||||
@@ -39,4 +39,33 @@ public class AgentQueryContextBuilderTests
|
||||
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<ChatMessage>
|
||||
{
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
using System.IO;
|
||||
using System.Text.Json;
|
||||
using AxCopilot.Services.Agent;
|
||||
using FluentAssertions;
|
||||
using Xunit;
|
||||
|
||||
namespace AxCopilot.Tests.Services;
|
||||
|
||||
public class ExcelSkillGoldenWorkbookTests
|
||||
{
|
||||
[Fact]
|
||||
public async Task ExecuteAsync_WithRichOperatingWorkbook_ShouldReturnStableQualitySummary()
|
||||
{
|
||||
var workDir = Path.Combine(Path.GetTempPath(), "ax-xlsx-golden-" + Guid.NewGuid().ToString("N"));
|
||||
Directory.CreateDirectory(workDir);
|
||||
|
||||
try
|
||||
{
|
||||
var tool = new ExcelSkill();
|
||||
var context = new AgentContext
|
||||
{
|
||||
WorkFolder = workDir,
|
||||
Permission = "Auto",
|
||||
OperationMode = "external",
|
||||
};
|
||||
|
||||
var args = JsonDocument.Parse(
|
||||
"""
|
||||
{
|
||||
"path": "operating-golden.xlsx",
|
||||
"summary_sheet": {
|
||||
"name": "Summary",
|
||||
"dashboard_sheet_name": "Dashboard",
|
||||
"title": "Operating Review",
|
||||
"decision_summary": [
|
||||
{ "label": "Decision Ask", "value": "Approve phase-2 staffing", "owner": "COO" }
|
||||
],
|
||||
"scorecards": [
|
||||
{ "label": "Revenue", "value": "128", "status": "On Track", "note": "Above plan" }
|
||||
],
|
||||
"dashboard_tiles": [
|
||||
{ "label": "Funding Status", "value": "Ready", "status": "Green", "note": "Decision aligned" }
|
||||
],
|
||||
"trend_series": [
|
||||
{ "label": "Revenue", "current": "128", "target": "125", "delta": "+3", "status": "Green" }
|
||||
],
|
||||
"variance_series": [
|
||||
{ "label": "Opex", "actual": "84", "target": "82", "variance": "+2", "status": "Watch" }
|
||||
],
|
||||
"sheet_summaries": [
|
||||
{ "sheet": "Revenue", "status": "Green", "summary": "Bookings remain above plan", "owner": "Sales Ops" },
|
||||
{ "sheet": "Cost", "status": "Watch", "summary": "Contractor spend needs control", "owner": "Finance" }
|
||||
],
|
||||
"highlights": ["Revenue remains above plan"],
|
||||
"actions": ["Approve phase-2 staffing"]
|
||||
},
|
||||
"sheets": [
|
||||
{
|
||||
"name": "Revenue",
|
||||
"headers": ["Metric", "Value"],
|
||||
"rows": [["Revenue", 128], ["Growth", "=B2/100"], ["Target Gap", "=B2-125"]],
|
||||
"conditional_formats": [{ "range": "B2:B3", "type": "data_bar", "color": "2563EB" }]
|
||||
},
|
||||
{
|
||||
"name": "Cost",
|
||||
"headers": ["Metric", "Value"],
|
||||
"rows": [["Opex", 84], ["Target", 82], ["Variance", "=B2-B3"]],
|
||||
"data_validations": [{ "range": "A2:A3", "type": "list", "formula1": "\"Opex,Target\"", "allow_blank": false }]
|
||||
}
|
||||
]
|
||||
}
|
||||
""").RootElement;
|
||||
|
||||
var result = await tool.ExecuteAsync(args, context, CancellationToken.None);
|
||||
|
||||
result.Success.Should().BeTrue();
|
||||
result.Output.Should().Contain("Quality score");
|
||||
result.Output.Should().Contain("Needs work: none");
|
||||
result.Output.Should().Contain("Repair guide: none");
|
||||
File.Exists(Path.Combine(workDir, "operating-golden.xlsx")).Should().BeTrue();
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Directory.Exists(workDir))
|
||||
Directory.Delete(workDir, true);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user