- claude-code 선택적 탐색 흐름을 참고해 Cowork/Code 시스템 프롬프트에서 folder_map 상시 선행 지시를 완화하고 glob/grep 기반 좁은 탐색을 우선하도록 조정함 - FolderMapTool 기본 depth를 2로, include_files 기본값을 false로 낮추고 MultiReadTool 최대 파일 수를 8개로 줄여 초기 과탐색 폭을 보수적으로 조정함 - AgentLoopExplorationPolicy partial을 추가해 탐색 범위 분류, broad-scan corrective hint, exploration_breadth 성능 로그를 연결함 - AgentLoopService에 탐색 범위 가이드 주입과 실행 중 탐색 폭 추적을 추가하고, 좁은 질문에서 반복적인 folder_map/대량 multi_read를 교정하도록 정리함 - DocxToHtmlConverter nullable 경고를 수정해 Release 빌드 경고 0 / 오류 0 기준을 다시 충족함 - README와 docs/DEVELOPMENT.md에 2026-04-09 10:36 (KST) 기준 개발 이력을 반영함
This commit is contained in:
@@ -84,15 +84,15 @@ public class ExcelSkill : IAgentTool
|
||||
{
|
||||
// path 미제공 시 title 또는 sheet_name에서 자동 생성
|
||||
string path;
|
||||
if (args.TryGetProperty("path", out var pathEl) && pathEl.ValueKind == JsonValueKind.String
|
||||
&& !string.IsNullOrWhiteSpace(pathEl.GetString()))
|
||||
if (args.SafeTryGetProperty("path", out var pathEl) && pathEl.ValueKind == JsonValueKind.String
|
||||
&& !string.IsNullOrWhiteSpace(pathEl.SafeGetString()))
|
||||
{
|
||||
path = pathEl.GetString()!;
|
||||
path = pathEl.SafeGetString()!;
|
||||
}
|
||||
else
|
||||
{
|
||||
var hint = (args.TryGetProperty("title", out var tEl) ? tEl.GetString() : null)
|
||||
?? (args.TryGetProperty("sheet_name", out var snEl) ? snEl.GetString() : null)
|
||||
var hint = (args.SafeTryGetProperty("title", out var tEl) ? tEl.SafeGetString() : null)
|
||||
?? (args.SafeTryGetProperty("sheet_name", out var snEl) ? snEl.SafeGetString() : null)
|
||||
?? "workbook";
|
||||
var safe = System.Text.RegularExpressions.Regex.Replace(hint, @"[\\/:*?""<>|]", "_").Trim().TrimEnd('.');
|
||||
if (safe.Length > 60) safe = safe[..60].TrimEnd();
|
||||
@@ -116,7 +116,7 @@ public class ExcelSkill : IAgentTool
|
||||
if (!string.IsNullOrEmpty(dir)) Directory.CreateDirectory(dir);
|
||||
|
||||
// Determine if we are in multi-sheet mode
|
||||
var multiSheetMode = args.TryGetProperty("sheets", out var sheetsArr)
|
||||
var multiSheetMode = args.SafeTryGetProperty("sheets", out var sheetsArr)
|
||||
&& sheetsArr.ValueKind == JsonValueKind.Array
|
||||
&& sheetsArr.GetArrayLength() > 0;
|
||||
|
||||
@@ -137,16 +137,16 @@ public class ExcelSkill : IAgentTool
|
||||
|
||||
private static ToolResult GenerateSingleSheetWorkbook(JsonElement args, string fullPath)
|
||||
{
|
||||
if (!args.TryGetProperty("headers", out var headers) || headers.ValueKind != JsonValueKind.Array)
|
||||
if (!args.SafeTryGetProperty("headers", out var headers) || headers.ValueKind != JsonValueKind.Array)
|
||||
return ToolResult.Fail("필수 파라미터 누락: 'headers'");
|
||||
if (!args.TryGetProperty("rows", out var rows) || rows.ValueKind != JsonValueKind.Array)
|
||||
if (!args.SafeTryGetProperty("rows", out var rows) || rows.ValueKind != JsonValueKind.Array)
|
||||
return ToolResult.Fail("필수 파라미터 누락: 'rows'");
|
||||
|
||||
var sheetName = args.TryGetProperty("sheet_name", out var sn) ? sn.GetString() ?? "Sheet1" : "Sheet1";
|
||||
var tableStyle = args.TryGetProperty("style", out var st) ? st.GetString() ?? "styled" : "styled";
|
||||
var themeName = args.TryGetProperty("theme", out var th) ? th.GetString() : null;
|
||||
var sheetName = args.SafeTryGetProperty("sheet_name", out var sn) ? sn.SafeGetString() ?? "Sheet1" : "Sheet1";
|
||||
var tableStyle = args.SafeTryGetProperty("style", out var st) ? st.SafeGetString() ?? "styled" : "styled";
|
||||
var themeName = args.SafeTryGetProperty("theme", out var th) ? th.SafeGetString() : null;
|
||||
var isStyled = tableStyle != "plain";
|
||||
var freezeHeader= args.TryGetProperty("freeze_header", out var fh) ? fh.GetBoolean() : isStyled;
|
||||
var freezeHeader= args.SafeTryGetProperty("freeze_header", out var fh) ? fh.GetBoolean() : isStyled;
|
||||
|
||||
var theme = GetTheme(themeName);
|
||||
var numFmts = ParseNumberFormats(args, "number_formats");
|
||||
@@ -168,8 +168,8 @@ public class ExcelSkill : IAgentTool
|
||||
|
||||
var colCount = headers.GetArrayLength();
|
||||
|
||||
var summaryArg = args.TryGetProperty("summary_row", out var sumEl) ? sumEl : default;
|
||||
var mergesArg = args.TryGetProperty("merges", out var mergeEl) ? mergeEl : default;
|
||||
var summaryArg = args.SafeTryGetProperty("summary_row", out var sumEl) ? sumEl : default;
|
||||
var mergesArg = args.SafeTryGetProperty("merges", out var mergeEl) ? mergeEl : default;
|
||||
|
||||
var rowCount = WriteSheetContent(worksheetPart, args, sheetName, headers, rows,
|
||||
isStyled, freezeHeader, theme, numFmts, alignments, customFmts,
|
||||
@@ -218,7 +218,7 @@ public class ExcelSkill : IAgentTool
|
||||
}
|
||||
|
||||
// Use first sheet's theme for the shared stylesheet
|
||||
var firstThemeName = sheetsArr[0].TryGetProperty("theme", out var ft) ? ft.GetString() : null;
|
||||
var firstThemeName = sheetsArr[0].SafeTryGetProperty("theme", out var ft) ? ft.SafeGetString() : null;
|
||||
var firstTheme = GetTheme(firstThemeName);
|
||||
|
||||
var combinedCustomFmts = CollectCustomFormats(allNumFmts);
|
||||
@@ -235,21 +235,21 @@ public class ExcelSkill : IAgentTool
|
||||
|
||||
foreach (var sheetDef in sheetsArr.EnumerateArray())
|
||||
{
|
||||
var sheetName = sheetDef.TryGetProperty("name", out var snEl) ? snEl.GetString() ?? $"Sheet{sheetId}" : $"Sheet{sheetId}";
|
||||
var tableStyle = sheetDef.TryGetProperty("style", out var stEl) ? stEl.GetString() ?? "styled" : "styled";
|
||||
var themeName = sheetDef.TryGetProperty("theme", out var thEl) ? thEl.GetString() : firstThemeName;
|
||||
var sheetName = sheetDef.SafeTryGetProperty("name", out var snEl) ? snEl.SafeGetString() ?? $"Sheet{sheetId}" : $"Sheet{sheetId}";
|
||||
var tableStyle = sheetDef.SafeTryGetProperty("style", out var stEl) ? stEl.SafeGetString() ?? "styled" : "styled";
|
||||
var themeName = sheetDef.SafeTryGetProperty("theme", out var thEl) ? thEl.SafeGetString() : firstThemeName;
|
||||
var isStyled = tableStyle != "plain";
|
||||
var freezeHeader = sheetDef.TryGetProperty("freeze_header", out var fhEl) ? fhEl.GetBoolean() : isStyled;
|
||||
var freezeHeader = sheetDef.SafeTryGetProperty("freeze_header", out var fhEl) ? fhEl.GetBoolean() : isStyled;
|
||||
var theme = GetTheme(themeName);
|
||||
var numFmts = ParseNumberFormats(sheetDef, "number_formats");
|
||||
var alignments = ParseAlignments(sheetDef, "col_alignments");
|
||||
|
||||
if (!sheetDef.TryGetProperty("headers", out var headers) || headers.ValueKind != JsonValueKind.Array) continue;
|
||||
if (!sheetDef.TryGetProperty("rows", out var rows) || rows.ValueKind != JsonValueKind.Array) continue;
|
||||
if (!sheetDef.SafeTryGetProperty("headers", out var headers) || headers.ValueKind != JsonValueKind.Array) continue;
|
||||
if (!sheetDef.SafeTryGetProperty("rows", out var rows) || rows.ValueKind != JsonValueKind.Array) continue;
|
||||
|
||||
var colCount = headers.GetArrayLength();
|
||||
var summaryArg = sheetDef.TryGetProperty("summary_row", out var sumEl) ? sumEl : default;
|
||||
var mergesArg = sheetDef.TryGetProperty("merges", out var mergeEl) ? mergeEl : default;
|
||||
var summaryArg = sheetDef.SafeTryGetProperty("summary_row", out var sumEl) ? sumEl : default;
|
||||
var mergesArg = sheetDef.SafeTryGetProperty("merges", out var mergeEl) ? mergeEl : default;
|
||||
|
||||
var worksheetPart = workbookPart.AddNewPart<WorksheetPart>();
|
||||
worksheetPart.Worksheet = new Worksheet();
|
||||
@@ -315,7 +315,7 @@ public class ExcelSkill : IAgentTool
|
||||
{
|
||||
CellReference = cellRef,
|
||||
DataType = CellValues.String,
|
||||
CellValue = new CellValue(h.ValueKind != JsonValueKind.Undefined ? h.GetString() ?? "" : ""),
|
||||
CellValue = new CellValue(h.ValueKind != JsonValueKind.Undefined ? h.SafeGetString() ?? "" : ""),
|
||||
StyleIndex = isStyled ? (uint)1 : 0,
|
||||
};
|
||||
headerRow.Append(cell);
|
||||
@@ -374,7 +374,7 @@ public class ExcelSkill : IAgentTool
|
||||
var mergeCells = new MergeCells();
|
||||
foreach (var merge in mergesArg.EnumerateArray())
|
||||
{
|
||||
var range = merge.GetString();
|
||||
var range = merge.SafeGetString();
|
||||
if (!string.IsNullOrEmpty(range))
|
||||
mergeCells.Append(new MergeCell { Reference = range });
|
||||
}
|
||||
@@ -678,7 +678,7 @@ public class ExcelSkill : IAgentTool
|
||||
|
||||
private static Columns? CreateColumns(JsonElement args, int colCount)
|
||||
{
|
||||
var hasWidths = args.TryGetProperty("col_widths", out var widthsArr) && widthsArr.ValueKind == JsonValueKind.Array;
|
||||
var hasWidths = args.SafeTryGetProperty("col_widths", out var widthsArr) && widthsArr.ValueKind == JsonValueKind.Array;
|
||||
|
||||
var columns = new Columns();
|
||||
for (int i = 0; i < colCount; i++)
|
||||
@@ -706,8 +706,8 @@ public class ExcelSkill : IAgentTool
|
||||
private static void AddSummaryRow(SheetData sheetData, JsonElement summary,
|
||||
uint rowNum, int colCount, int dataRowCount, bool isStyled)
|
||||
{
|
||||
var label = summary.TryGetProperty("label", out var lbl) ? lbl.GetString() ?? "합계" : "합계";
|
||||
var colFormulas = summary.TryGetProperty("columns", out var cols) ? cols : default;
|
||||
var label = summary.SafeTryGetProperty("label", out var lbl) ? lbl.SafeGetString() ?? "합계" : "합계";
|
||||
var colFormulas = summary.SafeTryGetProperty("columns", out var cols) ? cols : default;
|
||||
|
||||
var summaryRow = new Row { RowIndex = rowNum };
|
||||
|
||||
@@ -730,9 +730,9 @@ public class ExcelSkill : IAgentTool
|
||||
};
|
||||
|
||||
if (colFormulas.ValueKind == JsonValueKind.Object &&
|
||||
colFormulas.TryGetProperty(colLetter, out var funcName))
|
||||
colFormulas.SafeTryGetProperty(colLetter, out var funcName))
|
||||
{
|
||||
var func = funcName.GetString()?.ToUpper() ?? "SUM";
|
||||
var func = funcName.SafeGetString()?.ToUpper() ?? "SUM";
|
||||
var startRow = 2;
|
||||
var endRow = startRow + dataRowCount - 1;
|
||||
cell.CellFormula = new CellFormula($"={func}({colLetter}{startRow}:{colLetter}{endRow})");
|
||||
@@ -751,20 +751,20 @@ public class ExcelSkill : IAgentTool
|
||||
private static List<string?> ParseNumberFormats(JsonElement args, string key)
|
||||
{
|
||||
var result = new List<string?>();
|
||||
if (!args.TryGetProperty(key, out var arr) || arr.ValueKind != JsonValueKind.Array)
|
||||
if (!args.SafeTryGetProperty(key, out var arr) || arr.ValueKind != JsonValueKind.Array)
|
||||
return result;
|
||||
foreach (var el in arr.EnumerateArray())
|
||||
result.Add(el.ValueKind == JsonValueKind.Null ? null : el.GetString());
|
||||
result.Add(el.ValueKind == JsonValueKind.Null ? null : el.SafeGetString());
|
||||
return result;
|
||||
}
|
||||
|
||||
private static List<string?> ParseAlignments(JsonElement args, string key)
|
||||
{
|
||||
var result = new List<string?>();
|
||||
if (!args.TryGetProperty(key, out var arr) || arr.ValueKind != JsonValueKind.Array)
|
||||
if (!args.SafeTryGetProperty(key, out var arr) || arr.ValueKind != JsonValueKind.Array)
|
||||
return result;
|
||||
foreach (var el in arr.EnumerateArray())
|
||||
result.Add(el.ValueKind == JsonValueKind.Null ? null : el.GetString()?.ToLower());
|
||||
result.Add(el.ValueKind == JsonValueKind.Null ? null : el.SafeGetString()?.ToLower());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user