권한·도구 결과 transcript 안내 강화
Some checks failed
Release Gate / gate (push) Has been cancelled

권한 요청과 도구 결과 metadata를 실제 transcript 카드에 반영했습니다.

ActionHint, Severity, RequiresPreview, FollowUpHint, NeedsAttention, StatusKind를 이용해 보조 문구와 주의 chip을 표시하도록 정리했습니다.

README와 DEVELOPMENT 문서를 갱신했고 dotnet build 기준 경고 0 / 오류 0을 확인했습니다.
This commit is contained in:
2026-04-06 13:03:18 +09:00
parent e747032501
commit 7fd4d1ae5a
3 changed files with 116 additions and 0 deletions

View File

@@ -1210,3 +1210,7 @@ MIT License
- `claw-code` 대비 남아 있던 `도구/권한/스킬 표현 정교화` 1차를 반영했다. [PermissionRequestPresentationCatalog.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Services/Agent/PermissionRequestPresentationCatalog.cs)는 `bash`, `powershell`, `command`, `web_fetch`, `mcp`, `skill`, `question`, `file_edit`, `file_write`, `git`, `document`, `filesystem`까지 세분화하고 `ActionHint`, `Severity`, `RequiresPreview` 메타를 추가했다.
- [ToolResultPresentationCatalog.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Services/Agent/ToolResultPresentationCatalog.cs)는 기존 `success / error / reject / cancel`에 더해 `approval_required`, `partial` 상태와 `FollowUpHint`, `NeedsAttention` 메타를 추가해 후속 안내 품질을 높일 기반을 마련했다.
- [SkillGalleryWindow.xaml.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/SkillGalleryWindow.xaml.cs)는 스킬 상세에 `모델`, `추론 강도`, `실행 컨텍스트`, `에이전트`, `모델 호출 비활성화`, `추천 상황`을 표시하도록 확장해, AX 스킬도 `claw-code`처럼 실행 정책이 보이는 방향으로 정리했다.
- 업데이트: 2026-04-06 13:01 (KST)
- [ChatWindow.AgentEventRendering.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.AgentEventRendering.cs)에 `AppendAgentEventPresentationMeta(...)`와 공통 chip helper를 추가해, 권한 요청/도구 결과 metadata를 실제 transcript 카드에 반영했다.
- 권한 요청 이벤트는 이제 `ActionHint`, `Severity`, `RequiresPreview`를 이용해 `미리보기 권장`, `주의 필요`, `검토 권장` 같은 보조 chip과 안내 문구를 보여준다.
- 도구 결과 이벤트는 `FollowUpHint`, `NeedsAttention`, `StatusKind`를 이용해 `확인 필요`, `승인 후 계속`, `후속 점검` 같은 후속 행동 중심 안내를 transcript 안에서 바로 보여주도록 정리했다.

View File

@@ -4944,3 +4944,5 @@ ow + toggle ?쒓컖 ?몄뼱濡??ㅼ떆 ?뺣젹?덈떎.
- Document update: 2026-04-06 11:52 (KST) - Expanded `PermissionRequestPresentationCatalog.cs` into an action-level permission taxonomy (`bash`, `powershell`, `command`, `web_fetch`, `mcp`, `skill`, `question`, `file_edit`, `file_write`, `git`, `document`, `filesystem`) and added `ActionHint`, `Severity`, `RequiresPreview` metadata for later renderer refinement.
- Document update: 2026-04-06 11:52 (KST) - Expanded `ToolResultPresentationCatalog.cs` with richer result taxonomy and post-result guidance. AX now distinguishes `approval_required` and `partial` in addition to `success / error / reject / cancel`, and each result carries `FollowUpHint` and `NeedsAttention`.
- Document update: 2026-04-06 11:52 (KST) - Extended `SkillGalleryWindow.xaml.cs` to expose runtime-policy metadata (`model`, `effort`, `execution context`, `agent`, `disable model invocation`, `when to use`) so AX skills are easier to inspect and maintain like `claw-code` bundled skills.
- Document update: 2026-04-06 13:01 (KST) - Wired the new permission/result metadata into transcript rendering. `ChatWindow.AgentEventRendering.cs` now appends action-level guidance and attention chips to permission/tool-result event banners instead of using badge labels alone.
- 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 `후속 점검`.

View File

@@ -47,6 +47,104 @@ public partial class ChatWindow
};
}
private Border CreateAgentMetaChip(string text, string icon, Brush foreground, Brush background, Brush borderBrush)
{
return new Border
{
Background = background,
BorderBrush = borderBrush,
BorderThickness = new Thickness(1),
CornerRadius = new CornerRadius(999),
Padding = new Thickness(5, 1.5, 5, 1.5),
Margin = new Thickness(0, 0, 4, 0),
Child = new StackPanel
{
Orientation = Orientation.Horizontal,
Children =
{
new TextBlock
{
Text = icon,
FontFamily = new FontFamily("Segoe MDL2 Assets"),
FontSize = 7.5,
Foreground = foreground,
VerticalAlignment = VerticalAlignment.Center,
},
new TextBlock
{
Text = text,
FontSize = 7.75,
Foreground = foreground,
Margin = new Thickness(3, 0, 0, 0),
VerticalAlignment = VerticalAlignment.Center,
}
}
}
};
}
private void AppendAgentEventPresentationMeta(
StackPanel stack,
AgentEvent evt,
PermissionRequestPresentation? permissionPresentation,
ToolResultPresentation? toolResultPresentation,
Brush secondaryText,
Brush hintBg,
Brush borderColor)
{
string? guidance = null;
var chipRow = new WrapPanel
{
Margin = new Thickness(11, 2, 0, 0),
Orientation = Orientation.Horizontal,
};
if (permissionPresentation != null)
{
guidance = permissionPresentation.ActionHint;
if (permissionPresentation.RequiresPreview)
chipRow.Children.Add(CreateAgentMetaChip("미리보기 권장", "\uE8A7", secondaryText, hintBg, borderColor));
if (evt.Type == AgentEventType.PermissionRequest)
{
if (string.Equals(permissionPresentation.Severity, "high", StringComparison.OrdinalIgnoreCase))
chipRow.Children.Add(CreateAgentMetaChip("주의 필요", "\uE814", secondaryText, hintBg, borderColor));
else if (string.Equals(permissionPresentation.Severity, "medium", StringComparison.OrdinalIgnoreCase))
chipRow.Children.Add(CreateAgentMetaChip("검토 권장", "\uE946", secondaryText, hintBg, borderColor));
}
}
if (toolResultPresentation != null)
{
guidance = toolResultPresentation.FollowUpHint;
if (toolResultPresentation.NeedsAttention)
chipRow.Children.Add(CreateAgentMetaChip("확인 필요", "\uE814", secondaryText, hintBg, borderColor));
if (string.Equals(toolResultPresentation.StatusKind, "approval_required", StringComparison.OrdinalIgnoreCase))
chipRow.Children.Add(CreateAgentMetaChip("승인 후 계속", "\uE8D7", secondaryText, hintBg, borderColor));
else if (string.Equals(toolResultPresentation.StatusKind, "partial", StringComparison.OrdinalIgnoreCase))
chipRow.Children.Add(CreateAgentMetaChip("후속 점검", "\uE7BA", secondaryText, hintBg, borderColor));
}
if (!string.IsNullOrWhiteSpace(guidance))
{
var clipped = guidance.Length > 92 ? guidance[..92] + "..." : guidance;
stack.Children.Add(new TextBlock
{
Text = clipped,
FontSize = 8.15,
Foreground = secondaryText,
TextWrapping = TextWrapping.Wrap,
Margin = new Thickness(11, 1, 0, 0),
});
}
if (chipRow.Children.Count > 0)
stack.Children.Add(chipRow);
}
private void AddAgentEventBanner(AgentEvent evt)
{
var logLevel = _settings.Settings.Llm.AgentLogLevel;
@@ -272,6 +370,18 @@ public partial class ChatWindow
});
}
if (permissionPresentation != null || toolResultPresentation != null)
{
AppendAgentEventPresentationMeta(
sp,
evt,
permissionPresentation,
toolResultPresentation,
secondaryText,
hintBg,
borderColor);
}
var reviewChipRow = BuildReviewSignalChipRow(
kind: null,
toolName: evt.ToolName,