에이전트 진행 표시 구조를 claude-code식 row 기반으로 재정리
Some checks failed
Release Gate / gate (push) Has been cancelled

- AgentTranscriptDisplayCatalog를 row presentation 중심으로 재구성해 thinking/waiting/compact/tool activity/permission/tool result/status를 타입별로 분리함
- PermissionRequestPresentationCatalog와 ToolResultPresentationCatalog를 정리해 권한 요청과 결과 상태를 행위/상태 기준으로 더 명확하게 표현함
- ChatWindow.AgentEventRendering에서 process feed 계열 이벤트를 GroupKey 기준으로 병합해 append 수를 줄이고 진행 흐름이 기본 transcript에 남도록 조정함
- FooterPresentation에서 Cowork/Chat 프리셋 안내 카드가 execution event 이후 자동으로 숨겨지도록 하고 입력 워터마크와 footer 기본 문구를 정리함
- render_messages 성능 로그에 processFeed append/merge 수치와 rowKindCounts를 추가해 %APPDATA%\\AxCopilot\\perf 기준 실검증이 가능하도록 함
- dotnet build src/AxCopilot/AxCopilot.csproj -c Release -v minimal -p:OutputPath=bin\\verify\\ -p:IntermediateOutputPath=obj\\verify\\ 기준 경고 0 / 오류 0 확인
This commit is contained in:
2026-04-09 14:49:53 +09:00
parent 33c1db4dae
commit 227f5ab0d3
9 changed files with 867 additions and 548 deletions

View File

@@ -1,3 +1,5 @@
using System;
namespace AxCopilot.Services.Agent;
internal sealed record ToolResultPresentation(
@@ -29,7 +31,7 @@ internal static class ToolResultPresentationCatalog
"\uE711",
$"{baseLabel} 취소",
"요청이 중단되어 결과가 취소되었습니다.",
"필요하면 같은 요청을 다시 실행하세요.",
"필요하면 같은 요청을 다시 실행할 수 있습니다.",
"#F8FAFC",
"#475569",
"cancel",
@@ -45,7 +47,7 @@ internal static class ToolResultPresentationCatalog
"\uE783",
$"{baseLabel} 거부",
"권한이 거부되어 작업이 중단되었습니다.",
"권한 모드를 바꾸거나 다시 인하면 이어서 진행할 수 있습니다.",
"권한 모드를 바꾸거나 다시 인하면 이어서 진행할 수 있습니다.",
"#FEF2F2",
"#DC2626",
"reject",
@@ -58,8 +60,8 @@ internal static class ToolResultPresentationCatalog
return new ToolResultPresentation(
kind,
"\uE8D7",
$"{baseLabel} 승인 대기",
"다음 단계로 진행하려면 사용자 승인이 필요합니다.",
$"{baseLabel} 승인 필요",
"다음 단계로 진행하려면 사용자 승인이나 확인이 필요합니다.",
"승인 후 같은 작업 흐름이 이어집니다.",
"#FFF7ED",
"#C2410C",
@@ -74,8 +76,8 @@ internal static class ToolResultPresentationCatalog
kind,
"\uE7BA",
$"{baseLabel} 부분 완료",
"일부 단계만 완료되어 후속 확인이나 재실행이 필요할 수 있습니다.",
"남은 단계나 누락된 결과를 확인세요.",
"일부 단계만 완료되어 후속 확인이나 재시도가 필요할 수 있습니다.",
"후속 단계와 파일 결과를 확인해 주세요.",
"#FFFBEA",
"#A16207",
"partial",
@@ -114,7 +116,7 @@ internal static class ToolResultPresentationCatalog
return "file_edit";
if (tool.Contains("file_write"))
return "file_write";
if (tool.Contains("file_read") || tool.Contains("glob") || tool.Contains("grep"))
if (tool.Contains("file_read") || tool.Contains("glob") || tool.Contains("grep") || tool.Contains("folder_map") || tool.Contains("multi_read"))
return "filesystem";
if (tool.Contains("file"))
return "file";
@@ -141,111 +143,93 @@ internal static class ToolResultPresentationCatalog
return "generic";
}
private static string BuildSuccessLabel(string kind, string baseLabel)
private static string BuildSuccessLabel(string kind, string baseLabel) => kind switch
{
return kind switch
{
"file_edit" => "파일 수정 완료",
"file_write" => "파일 쓰기 완료",
"filesystem" => "파일 탐색 완료",
"file" => "파일 작업 완료",
"build_test" => "빌드/테스트 완료",
"git" => "Git 작업 완료",
"document" => "문서 작업 완료",
"skill" => "스킬 실행 완료",
"mcp" => "MCP 도구 완료",
"question" => "의견 요청 완료",
"web" => "웹 요청 완료",
"command" => "명령 실행 완료",
_ => baseLabel,
};
}
"file_edit" => "파일 수정 완료",
"file_write" => "파일 쓰기 완료",
"filesystem" => "파일 탐색 완료",
"file" => "파일 작업 완료",
"build_test" => "빌드/테스트 완료",
"git" => "Git 작업 완료",
"document" => "문서 작업 완료",
"skill" => "스킬 실행 완료",
"mcp" => "MCP 도구 완료",
"question" => "질문 요청 완료",
"web" => "웹 요청 완료",
"command" => "명령 실행 완료",
_ => baseLabel,
};
private static string BuildFailureLabel(string kind, string baseLabel)
private static string BuildFailureLabel(string kind, string baseLabel) => kind switch
{
return kind switch
{
"file_edit" => "파일 수정 실패",
"file_write" => "파일 쓰기 실패",
"filesystem" => "파일 탐색 실패",
"file" => "파일 작업 실패",
"build_test" => "빌드/테스트 실패",
"git" => "Git 작업 실패",
"document" => "문서 작업 실패",
"skill" => "스킬 실행 실패",
"mcp" => "MCP 도구 실패",
"question" => "의견 요청 실패",
"web" => "웹 요청 실패",
"command" => "명령 실행 실패",
_ => $"{baseLabel} 실패",
};
}
"file_edit" => "파일 수정 실패",
"file_write" => "파일 쓰기 실패",
"filesystem" => "파일 탐색 실패",
"file" => "파일 작업 실패",
"build_test" => "빌드/테스트 실패",
"git" => "Git 작업 실패",
"document" => "문서 작업 실패",
"skill" => "스킬 실행 실패",
"mcp" => "MCP 도구 실패",
"question" => "질문 요청 실패",
"web" => "웹 요청 실패",
"command" => "명령 실행 실패",
_ => $"{baseLabel} 실패",
};
private static string BuildSuccessDescription(string kind)
private static string BuildSuccessDescription(string kind) => kind switch
{
return kind switch
{
"file_edit" => "파일 수정 결과가 저장되었습니다.",
"file_write" => "파일 작성 결과가 저장되었습니다.",
"filesystem" => "파일과 폴더 정보를 성공적으로 읽었습니다.",
"file" => "파일 관련 작업이 정상적으로 끝났습니다.",
"build_test" => "빌드 또는 테스트 단계가 성공적으로 끝났습니다.",
"git" => "Git 관련 작업이 정상적으로 끝났습니다.",
"document" => "문서 생성 또는 변환 작업이 완료되었습니다.",
"skill" => "선택한 스킬이 정상적으로 실행되었습니다.",
"mcp" => "등록된 MCP 도구 호출이 성공적으로 끝났습니다.",
"question" => "사용자 응답을 받아 다음 단계로 넘어갈 수 있습니다.",
"web" => "요청이 정상적으로 끝났습니다.",
"command" => "명령 실행이 정상적으로 끝났습니다.",
_ => "요청한 작업이 정상적으로 완료되었습니다.",
};
}
"file_edit" => "파일 수정 결과가 정상적으로 반영되었습니다.",
"file_write" => "새 파일 생성이나 쓰기 작업이 완료되었습니다.",
"filesystem" => "질문과 관련된 파일과 구조 정보를 찾았습니다.",
"file" => "파일 관련 작업이 정상적으로 끝났습니다.",
"build_test" => "빌드나 테스트 단계가 정상적으로 끝났습니다.",
"git" => "저장소 상태 확인 또는 변경 작업이 완료되었습니다.",
"document" => "문서 산출물 생성 또는 조립이 완료되었습니다.",
"skill" => "선택한 스킬이 정상적으로 실행되었습니다.",
"mcp" => "등록된 MCP 도구 호출이 완료되었습니다.",
"question" => "사용자 응답을 받아 다음 단계로 이어갈 수 있습니다.",
"web" => "필요한 웹 정보 조회가 완료되었습니다.",
"command" => "명령 실행이 완료되어 결과를 확인할 수 있습니다.",
_ => "요청한 작업이 정상적으로 완료되었습니다.",
};
private static string BuildFailureDescription(string kind)
private static string BuildFailureDescription(string kind) => kind switch
{
return kind switch
{
"file_edit" => "파일 변경 과정에서 문제가 발생했습니다.",
"file_write" => "파일 작성 또는 저장 과정에서 문제가 발생했습니다.",
"filesystem" => "파일/폴더 접근 중 문제가 발생했습니다.",
"file" => "파일 처리문제가 발생했습니다.",
"build_test" => "빌드 또는 테스트 단계에서 실패가 발생했습니다.",
"git" => "Git 관련 작업이 실패했습니다.",
"document" => "문서 생성 또는 변환 작업이 실패했습니다.",
"skill" => "스킬 실행 중 문제가 발생했습니다.",
"mcp" => "MCP 도구 호출 중 문제가 발생했습니다.",
"question" => "사용자 의견 요청 과정에서 문제가 발생했습니다.",
"web" => "웹 요청 처리에 실패했습니다.",
"command" => "명령 실행 중 오류가 발생했습니다.",
_ => "작업 처리 중 오류가 발생했습니다.",
};
}
"file_edit" => "파일 변경 과정에서 문제가 발생했습니다.",
"file_write" => "파일 생성 또는 쓰기 과정에서 문제가 발생했습니다.",
"filesystem" => "파일이나 폴더를 확인하는 과정에서 문제가 발생했습니다.",
"file" => "파일 처리 중 문제가 발생했습니다.",
"build_test" => "빌드 또는 테스트 단계에서 실패가 발생했습니다.",
"git" => "Git 작업오류가 발생했습니다.",
"document" => "문서 생성 또는 조합 과정이 실패했습니다.",
"skill" => "스킬 실행 중 문제가 발생했습니다.",
"mcp" => "MCP 도구 호출 중 문제가 발생했습니다.",
"question" => "사용자 질문/응답 처리 단계에서 문제가 발생했습니다.",
"web" => "웹 요청 처리에 실패했습니다.",
"command" => "명령 실행 중 오류가 발생했습니다.",
_ => "작업 처리 중 오류가 발생했습니다.",
};
private static string BuildSuccessFollowUp(string kind)
private static string BuildSuccessFollowUp(string kind) => kind switch
{
return kind switch
{
"file_edit" or "file_write" => "변경 내용을 preview나 diff에서 다시 확인할 수 있습니다.",
"build_test" => "출력 로그와 후속 수정 필요 여부를 확인세요.",
"git" => "브랜치 상태나 변경 요약을 이어서 확인하세요.",
"document" => "생성된 산출물 경로를 열어 결과를 확인하세요.",
"skill" => "같은 스킬을 다른 입력으로 이어서 실행할 수 있습니다.",
_ => "필요하면 후속 요청을 이어서 실행할 수 있습니다.",
};
}
"file_edit" or "file_write" => "변경 내용은 preview나 diff에서 다시 확인할 수 있습니다.",
"build_test" => "출력 로그와 후속 수정 필요 여부를 확인해 주세요.",
"git" => "브랜치와 변경 수치를 이어서 확인해 주세요.",
"document" => "생성된 산출물 경로를 열어 결과를 확인해 주세요.",
"skill" => "같은 스킬을 다른 입력으로 이어서 실행할 수 있습니다.",
_ => "필요하면 다음 요청으로 이어서 작업할 수 있습니다.",
};
private static string BuildFailureFollowUp(string kind)
private static string BuildFailureFollowUp(string kind) => kind switch
{
return kind switch
{
"file_edit" or "file_write" => "대상 파일 경로와 권한, diff를 다시 확인세요.",
"build_test" => "실패 로그와 컴파일 오류 메시지를 먼저 확인하세요.",
"git" => "현재 브랜치, 잠금 상태, 충돌 여부를 확인하세요.",
"document" => "입력 데이터와 출력 형식, 저장 위치를 다시 확인세요.",
"skill" => "허용 도구와 런타임 요구사항을 다시 확인세요.",
"web" => "연결 상태와 요청 대상 URL을 다시 확인하세요.",
"mcp" => "MCP 서버 연결 상태와 도구 등록 상태를 다시 확인하세요.",
_ => "같은 요청을 재시도하기 전에 원인 메시지를 먼저 확인하세요.",
};
}
"file_edit" or "file_write" => "대상 파일 경로와 권한, diff 결과를 다시 확인해 주세요.",
"build_test" => "실패 로그와 컴파일/테스트 오류 메시지를 먼저 확인해 주세요.",
"git" => "브랜치 상태와 충돌 여부를 다시 확인해 주세요.",
"document" => "입력 데이터, 출력 형식, 대상 위치를 다시 확인해 주세요.",
"skill" => "사용 도구와 스킬 요구사항을 다시 확인해 주세요.",
"web" => "연결 상태와 요청 URL을 다시 확인해 주세요.",
"mcp" => "MCP 서버 연결 상태와 도구 등록 상태를 다시 확인해 주세요.",
_ => "같은 요청을 다시 시도하기 전에 원인 메시지를 먼저 확인해 주세요.",
};
}