문서 생성 품질 게이트와 산출물 고도화 2차 반영
공통 ArtifactQualityReviewService를 추가해 HTML, DOCX, XLSX 결과물에 로컬 품질 점수와 보완 포인트를 부여했습니다. DocxSkill에 template_path, cover_subtitle, cover_meta, toc 흐름을 붙여 템플릿 기반 문서와 커버/목차 생성을 강화했고, Excel summary sheet에는 detail sheet 링크와 workbook review를 연결했습니다. HtmlSkill도 결과 요약에 품질 리뷰를 포함하도록 보강했습니다. executive-brief, kpi-workbook, board-report-html 번들 스킬을 추가했고, ArtifactQualityReviewServiceTests, DocxSkillTemplateFeaturesTests, ExcelSkillExecutiveSummaryLinkTests를 포함한 관련 테스트를 보강했습니다. 검증: dotnet build src/AxCopilot/AxCopilot.csproj -c Release -v minimal -p:OutputPath=bin\verify_doc_phase2\ -p:IntermediateOutputPath=obj\verify_doc_phase2\ (경고 0 / 오류 0) 검증: dotnet test src/AxCopilot.Tests/AxCopilot.Tests.csproj -c Release -v minimal --filter ArtifactQualityReviewServiceTests|DocxSkillTemplateFeaturesTests|ExcelSkillExecutiveSummaryLinkTests|DocumentAssemblerSemanticTests|DocumentPlannerBusinessDocumentTests|HtmlSkillConsultingSectionsTests|ExcelSkillSummarySheetTests -p:OutputPath=bin\verify_doc_phase2_tests\ -p:IntermediateOutputPath=obj\verify_doc_phase2_tests\ (통과 9)
This commit is contained in:
@@ -202,6 +202,19 @@ public class ExcelSkill : IAgentTool
|
||||
summaryArg.ValueKind == JsonValueKind.Object,
|
||||
numFmts.Count > 0, alignments.Count > 0, themeName);
|
||||
|
||||
var review = ArtifactQualityReviewService.ReviewWorkbook(new WorkbookReviewInput(
|
||||
sheetName,
|
||||
1,
|
||||
1,
|
||||
rowCount,
|
||||
CountFormulaCells(rows),
|
||||
0,
|
||||
0,
|
||||
false,
|
||||
false,
|
||||
summaryArg.ValueKind == JsonValueKind.Object));
|
||||
features += $"\n{review.ToToolSummary()}";
|
||||
|
||||
return ToolResult.Ok(
|
||||
$"Excel 파일 생성 완료: {fullPath}\n시트: {sheetName}, 열: {colCount}, 행: {rowCount}{features}",
|
||||
fullPath);
|
||||
@@ -274,6 +287,18 @@ public class ExcelSkill : IAgentTool
|
||||
mergesArg.ValueKind == JsonValueKind.Array,
|
||||
summaryArg.ValueKind == JsonValueKind.Object,
|
||||
numFmts.Count > 0, alignments.Count > 0, themeName);
|
||||
var review = ArtifactQualityReviewService.ReviewWorkbook(new WorkbookReviewInput(
|
||||
summaryName,
|
||||
2,
|
||||
1,
|
||||
rowCount,
|
||||
CountFormulaCells(rows),
|
||||
1,
|
||||
0,
|
||||
true,
|
||||
HasSummaryItems(summarySheet, "highlights"),
|
||||
HasSummaryItems(summarySheet, "actions")));
|
||||
features += $"\n{review.ToToolSummary()}";
|
||||
|
||||
return ToolResult.Ok(
|
||||
$"Excel ?뚯씪 ?앹꽦 ?꾨즺: {fullPath}\n?쒗듃: {summaryName}, {sheetName}, ?? {colCount}, ?? {rowCount}{features} [?붿빟 ?쒗듃]",
|
||||
@@ -313,6 +338,7 @@ public class ExcelSkill : IAgentTool
|
||||
uint sheetId = 1;
|
||||
var totalSheets = 0;
|
||||
var totalRows = 0;
|
||||
var totalFormulaCount = 0;
|
||||
var detailSheetNames = new List<string>();
|
||||
|
||||
foreach (var sheetDef in sheetsArr.EnumerateArray())
|
||||
@@ -373,10 +399,10 @@ public class ExcelSkill : IAgentTool
|
||||
sheetId++;
|
||||
totalSheets++;
|
||||
totalRows += rowCount;
|
||||
totalFormulaCount += CountFormulaCells(rows);
|
||||
}
|
||||
|
||||
workbookPart.Workbook.Save();
|
||||
|
||||
return ToolResult.Ok(
|
||||
$"Excel 파일 생성 완료: {fullPath}\n시트: {totalSheets}개, 총 데이터 행: {totalRows}",
|
||||
fullPath);
|
||||
@@ -403,6 +429,7 @@ public class ExcelSkill : IAgentTool
|
||||
worksheetPart.Worksheet.Append(sheetData);
|
||||
|
||||
var merges = new MergeCells();
|
||||
var hyperlinks = new Hyperlinks();
|
||||
uint rowIndex = 1;
|
||||
|
||||
var title = summarySheet.SafeTryGetProperty("title", out var titleEl)
|
||||
@@ -454,8 +481,27 @@ public class ExcelSkill : IAgentTool
|
||||
AppendMergedTextRow(sheetData, merges, rowIndex++, "A", "F", $"• {detailSheetName}", 0);
|
||||
}
|
||||
|
||||
if (detailSheetNames.Count > 0)
|
||||
{
|
||||
var hyperlinkStartRow = rowIndex - (uint)detailSheetNames.Count;
|
||||
for (var i = 0; i < detailSheetNames.Count; i++)
|
||||
{
|
||||
hyperlinks.Append(new Hyperlink
|
||||
{
|
||||
Reference = $"A{hyperlinkStartRow + (uint)i}",
|
||||
Location = $"'{detailSheetNames[i]}'!A1",
|
||||
Display = detailSheetNames[i]
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (merges.HasChildren)
|
||||
worksheetPart.Worksheet.InsertAfter(merges, sheetData);
|
||||
if (hyperlinks.HasChildren)
|
||||
{
|
||||
var anchor = merges.HasChildren ? (OpenXmlElement)merges : sheetData;
|
||||
worksheetPart.Worksheet.InsertAfter(hyperlinks, anchor);
|
||||
}
|
||||
}
|
||||
|
||||
private static void AppendSummaryTextSection(JsonElement summarySheet, string key, string heading, SheetData sheetData, MergeCells merges, ref uint rowIndex)
|
||||
@@ -979,6 +1025,36 @@ public class ExcelSkill : IAgentTool
|
||||
return result;
|
||||
}
|
||||
|
||||
private static int CountFormulaCells(JsonElement rows)
|
||||
{
|
||||
if (rows.ValueKind != JsonValueKind.Array)
|
||||
return 0;
|
||||
|
||||
var count = 0;
|
||||
foreach (var row in rows.EnumerateArray())
|
||||
{
|
||||
if (row.ValueKind != JsonValueKind.Array)
|
||||
continue;
|
||||
|
||||
foreach (var cell in row.EnumerateArray())
|
||||
{
|
||||
var text = cell.ToString();
|
||||
if (!string.IsNullOrWhiteSpace(text) && text.StartsWith('='))
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
private static bool HasSummaryItems(JsonElement summarySheet, string propertyName)
|
||||
{
|
||||
return summarySheet.ValueKind == JsonValueKind.Object
|
||||
&& summarySheet.SafeTryGetProperty(propertyName, out var items)
|
||||
&& items.ValueKind == JsonValueKind.Array
|
||||
&& items.GetArrayLength() > 0;
|
||||
}
|
||||
|
||||
private static string BuildFeatureList(bool isStyled, bool freezeHeader,
|
||||
bool hasMerges, bool hasSummary, bool hasNumFmts, bool hasAlignments, string? theme)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user