From ec0ed7fb1cdce044493b45dda6978016cf999a81 Mon Sep 17 00:00:00 2001 From: lacvet Date: Mon, 6 Apr 2026 13:43:19 +0900 Subject: [PATCH] =?UTF-8?q?=EA=B6=8C=ED=95=9C=C2=B7=EB=8F=84=EA=B5=AC=20?= =?UTF-8?q?=EA=B2=B0=EA=B3=BC=20=EC=B9=B4=EB=93=9C=20callout=20=EA=B5=AC?= =?UTF-8?q?=EC=A1=B0=20=EB=8F=84=EC=9E=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 권한 요청과 도구 결과 transcript 안내를 단순 보조 문구에서 callout 카드 구조로 정리했습니다. 권한 요청은 확인 포인트, 도구 결과는 다음 권장 작업으로 보여주도록 바꿔 카드 성격 차이를 더 분명하게 만들었습니다. README와 DEVELOPMENT 문서를 갱신했고 dotnet build 기준 경고 0 / 오류 0을 확인했습니다. --- README.md | 2 + docs/DEVELOPMENT.md | 1 + .../Views/ChatWindow.AgentEventRendering.cs | 81 +++++++++++++++++-- 3 files changed, 77 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index d8cce18..595720e 100644 --- a/README.md +++ b/README.md @@ -1218,3 +1218,5 @@ MIT License - 같은 metadata가 모두 회색 chip으로 보이던 부분을 보강했다. [ChatWindow.AgentEventRendering.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.AgentEventRendering.cs) 의 보조 chip 색을 `주의 필요=빨강`, `검토 권장/후속 점검=앰버`, `미리보기 권장=파랑`, `승인 후 계속=오렌지`로 나눠, 권한 요청과 도구 결과 상태가 시각적으로도 더 즉시 구분되게 맞췄다. - 업데이트: 2026-04-06 13:14 (KST) - [ChatWindow.AgentEventRendering.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.AgentEventRendering.cs)에 권한 요청/도구 결과 카테고리 chip을 추가했다. 이제 `명령 실행`, `파일 수정`, `웹 요청`, `Git`, `문서`, `스킬`, `MCP` 같은 종류가 상태 chip과 함께 보여서, 어떤 성격의 요청/결과인지 transcript에서 더 빨리 파악할 수 있다. +- 업데이트: 2026-04-06 13:20 (KST) + - [ChatWindow.AgentEventRendering.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.AgentEventRendering.cs)의 metadata 안내를 callout 구조로 바꿨다. 권한 요청은 `확인 포인트`, 도구 결과는 `다음 권장 작업` 카드형 안내로 보여줘, 같은 transcript 안에서도 요청과 결과의 UX가 더 분리되어 보이게 정리했다. diff --git a/docs/DEVELOPMENT.md b/docs/DEVELOPMENT.md index c5b2dd5..f7cf055 100644 --- a/docs/DEVELOPMENT.md +++ b/docs/DEVELOPMENT.md @@ -4948,3 +4948,4 @@ ow + toggle ?쒓컖 ?몄뼱濡??ㅼ떆 ?뺣젹?덈떎. - Document update: 2026-04-06 13:01 (KST) - Permission events now surface `ActionHint`, `Severity`, and `RequiresPreview` through inline cues such as `미리보기 권장`, `주의 필요`, and `검토 권장`, while tool-result events surface `FollowUpHint`, `NeedsAttention`, and `StatusKind` through cues such as `확인 필요`, `승인 후 계속`, and `후속 점검`. - Document update: 2026-04-06 13:08 (KST) - Refined the transcript chips to visually differentiate metadata states instead of rendering every cue in the same neutral style. `ChatWindow.AgentEventRendering.cs` now uses blue for preview guidance, red for high-severity attention, amber for review/partial follow-up, and orange for approval-required continuation cues. - Document update: 2026-04-06 13:14 (KST) - Added kind/category chips to permission and tool-result transcript banners so the action domain is visible at a glance. `ChatWindow.AgentEventRendering.cs` now surfaces labels such as `명령 실행`, `파일 수정`, `웹 요청`, `Git`, `문서`, `스킬`, and `MCP` alongside the status-oriented chips. +- Document update: 2026-04-06 13:20 (KST) - Replaced the plain guidance line with typed callout boxes in `ChatWindow.AgentEventRendering.cs`. Permission requests now show an `확인 포인트` callout, while tool results show a `다음 권장 작업` callout, making the two transcript surfaces read differently even when they share the same chip language. diff --git a/src/AxCopilot/Views/ChatWindow.AgentEventRendering.cs b/src/AxCopilot/Views/ChatWindow.AgentEventRendering.cs index c5bd8d2..430d1d1 100644 --- a/src/AxCopilot/Views/ChatWindow.AgentEventRendering.cs +++ b/src/AxCopilot/Views/ChatWindow.AgentEventRendering.cs @@ -83,6 +83,40 @@ public partial class ChatWindow }; } + private Border CreateAgentMetaCallout(string title, string body, Brush titleBrush, Brush background, Brush borderBrush) + { + return new Border + { + Background = background, + BorderBrush = borderBrush, + BorderThickness = new Thickness(1), + CornerRadius = new CornerRadius(8), + Padding = new Thickness(7, 5, 7, 5), + Margin = new Thickness(11, 2, 0, 0), + Child = new StackPanel + { + Children = + { + new TextBlock + { + Text = title, + FontSize = 7.75, + FontWeight = FontWeights.SemiBold, + Foreground = titleBrush, + }, + new TextBlock + { + Text = body, + FontSize = 8.1, + Foreground = TryFindResource("SecondaryText") as Brush ?? Brushes.DimGray, + TextWrapping = TextWrapping.Wrap, + Margin = new Thickness(0, 1, 0, 0), + } + } + } + }; + } + private static string GetPermissionKindLabel(string kind) { return kind switch @@ -215,14 +249,47 @@ public partial class ChatWindow if (!string.IsNullOrWhiteSpace(guidance)) { var clipped = guidance.Length > 92 ? guidance[..92] + "..." : guidance; - stack.Children.Add(new TextBlock + if (permissionPresentation != null) { - Text = clipped, - FontSize = 8.15, - Foreground = secondaryText, - TextWrapping = TextWrapping.Wrap, - Margin = new Thickness(11, 1, 0, 0), - }); + var titleBrush = string.Equals(permissionPresentation.Severity, "high", StringComparison.OrdinalIgnoreCase) + ? BrushFromHex("#B91C1C") + : string.Equals(permissionPresentation.Severity, "medium", StringComparison.OrdinalIgnoreCase) + ? BrushFromHex("#A16207") + : BrushFromHex("#2563EB"); + var background = string.Equals(permissionPresentation.Severity, "high", StringComparison.OrdinalIgnoreCase) + ? BrushFromHex("#FFF7F7") + : string.Equals(permissionPresentation.Severity, "medium", StringComparison.OrdinalIgnoreCase) + ? BrushFromHex("#FFFBEB") + : BrushFromHex("#EFF6FF"); + var border = string.Equals(permissionPresentation.Severity, "high", StringComparison.OrdinalIgnoreCase) + ? BrushFromHex("#FECACA") + : string.Equals(permissionPresentation.Severity, "medium", StringComparison.OrdinalIgnoreCase) + ? BrushFromHex("#FDE68A") + : BrushFromHex("#BFDBFE"); + stack.Children.Add(CreateAgentMetaCallout("확인 포인트", clipped, titleBrush, background, border)); + } + else if (toolResultPresentation != null) + { + var titleBrush = string.Equals(toolResultPresentation.StatusKind, "error", StringComparison.OrdinalIgnoreCase) + || string.Equals(toolResultPresentation.StatusKind, "reject", StringComparison.OrdinalIgnoreCase) + ? BrushFromHex("#B91C1C") + : string.Equals(toolResultPresentation.StatusKind, "approval_required", StringComparison.OrdinalIgnoreCase) + ? BrushFromHex("#C2410C") + : BrushFromHex("#A16207"); + var background = string.Equals(toolResultPresentation.StatusKind, "error", StringComparison.OrdinalIgnoreCase) + || string.Equals(toolResultPresentation.StatusKind, "reject", StringComparison.OrdinalIgnoreCase) + ? BrushFromHex("#FFF7F7") + : string.Equals(toolResultPresentation.StatusKind, "approval_required", StringComparison.OrdinalIgnoreCase) + ? BrushFromHex("#FFF7ED") + : BrushFromHex("#FFFBEB"); + var border = string.Equals(toolResultPresentation.StatusKind, "error", StringComparison.OrdinalIgnoreCase) + || string.Equals(toolResultPresentation.StatusKind, "reject", StringComparison.OrdinalIgnoreCase) + ? BrushFromHex("#FECACA") + : string.Equals(toolResultPresentation.StatusKind, "approval_required", StringComparison.OrdinalIgnoreCase) + ? BrushFromHex("#FED7AA") + : BrushFromHex("#FDE68A"); + stack.Children.Add(CreateAgentMetaCallout("다음 권장 작업", clipped, titleBrush, background, border)); + } } if (chipRow.Children.Count > 0)