AX Agent transcript 품질 향상과 회귀 기준 정리
Some checks failed
Release Gate / gate (push) Has been cancelled
Some checks failed
Release Gate / gate (push) Has been cancelled
- 도구/스킬 transcript 표시 카탈로그를 분리해 파일, 빌드, Git, 문서, 질문, 제안, 스킬 분류를 공통 라벨로 통일함 - task summary popup을 active 우선, recent/debug 보조 기준으로 축소하고 transcript policy helper를 partial로 분리함 - AX Agent와 claw-code 비교용 회귀 프롬프트 세트를 별도 문서로 추가하고 관련 개발 문서를 즉시 갱신함 - 검증: 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:
@@ -996,6 +996,11 @@ ow + toggle 시각 언어로 통일했습니다.
|
||||
- 이번 정리 후 parity 는 `core engine 100% / main transcript UI 100% / Cowork·Code runtime UX 100% / internal settings 100% / overall 100%` 기준으로 최종 마감 판단했습니다.
|
||||
- 검증: `dotnet build src/AxCopilot/AxCopilot.csproj -c Release -v minimal -p:OutputPath=bin\\verify\\ -p:IntermediateOutputPath=obj\\verify\\` 경고 0 / 오류 0
|
||||
- 업데이트: 2026-04-05 21:43 (KST)
|
||||
- 업데이트: 2026-04-05 22:18 (KST)
|
||||
- transcript 품질 향상 2차로 도구/스킬 표시 카탈로그를 [AgentTranscriptDisplayCatalog.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Services/Agent/AgentTranscriptDisplayCatalog.cs) 로 분리했습니다. 이제 transcript 배지와 task summary 카드가 `파일 / 빌드 / Git / 문서 / 질문 / 제안 / 스킬` 같은 역할 중심 라벨을 공통으로 사용합니다.
|
||||
- [ChatWindow.TranscriptPolicy.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.TranscriptPolicy.cs) 를 추가해 transcript badge/summary/task-summary policy를 partial helper로 분리했고, [ChatWindow.xaml.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml.cs) 의 task summary popup 은 active task 우선, recent history 는 debug 또는 active 없음일 때만 보이도록 축소했습니다.
|
||||
- 동일 프롬프트 회귀 세트는 [docs/AX_AGENT_REGRESSION_PROMPTS.md](/E:/AX%20Copilot%20-%20Codex/docs/AX_AGENT_REGRESSION_PROMPTS.md) 로 별도 분리해 Chat/Cowork/Code/queue/permission/slash 시나리오를 바로 비교할 수 있게 했습니다.
|
||||
- 검증: `dotnet build src/AxCopilot/AxCopilot.csproj -c Release -v minimal -p:OutputPath=bin\\verify\\ -p:IntermediateOutputPath=obj\\verify\\` 예정
|
||||
|
||||
---
|
||||
|
||||
|
||||
79
docs/AX_AGENT_REGRESSION_PROMPTS.md
Normal file
79
docs/AX_AGENT_REGRESSION_PROMPTS.md
Normal file
@@ -0,0 +1,79 @@
|
||||
# AX Agent Regression Prompts
|
||||
|
||||
업데이트: 2026-04-05 22:18 (KST)
|
||||
|
||||
`claw-code`와 AX Agent를 같은 기준으로 비교하기 위한 회귀 프롬프트 세트입니다.
|
||||
|
||||
## Chat
|
||||
|
||||
1. 기본 답변
|
||||
- 프롬프트: `회의 일정 조정 메일을 정중한 한국어로 써줘`
|
||||
- 확인:
|
||||
- 빈 assistant 카드 없음
|
||||
- 재생성/재시도 후 transcript 중복 없음
|
||||
|
||||
2. 장문 설명
|
||||
- 프롬프트: `RAG와 fine-tuning 차이를 실무 관점으로 7가지로 설명해줘`
|
||||
- 확인:
|
||||
- 장문 렌더 유지
|
||||
- compact 이후 다음 턴 문맥 유지
|
||||
|
||||
## Cowork
|
||||
|
||||
3. 문서형 작업
|
||||
- 프롬프트: `신규 ERP 도입 제안서 초안을 작성해줘. 목적, 범위, 기대효과, 추진일정 포함`
|
||||
- 확인:
|
||||
- 작업 유형 반영
|
||||
- 계획 이후 실제 문서형 결과 흐름
|
||||
- 기본 로그 과다 노출 없음
|
||||
|
||||
4. 데이터형 작업
|
||||
- 프롬프트: `매출 CSV를 분석해서 월별 추세와 이상치를 요약해줘`
|
||||
- 확인:
|
||||
- 데이터 분석형 도구 선택
|
||||
- 결과 요약 품질
|
||||
- runtime 노이즈 최소화
|
||||
|
||||
## Code
|
||||
|
||||
5. 버그 수정
|
||||
- 프롬프트: `현재 프로젝트에서 설정 저장 버그 원인 찾고 수정해줘`
|
||||
- 확인:
|
||||
- 읽기/검색/수정 흐름 일관성
|
||||
- diff 저장
|
||||
- reopen 시 transcript 보존
|
||||
|
||||
6. 빌드/테스트
|
||||
- 프롬프트: `빌드 오류를 재현하고 수정한 뒤 다시 빌드해줘`
|
||||
- 확인:
|
||||
- build/test 루프
|
||||
- 실패 후 재시도
|
||||
- 완료 메시지 정합성
|
||||
|
||||
## Cross-tab
|
||||
|
||||
7. 후속 큐
|
||||
- 순차 프롬프트:
|
||||
- `이 창 레이아웃 문제 원인 찾아줘`
|
||||
- `끝나면 README도 같이 갱신해줘`
|
||||
- 확인:
|
||||
- queue chaining
|
||||
- 입력창 직접 변형 없이 다음 턴 수행
|
||||
|
||||
8. compact 이후 연속성
|
||||
- 프롬프트: `지금까지 논의한 내용을 5줄로 이어서 정리하고 다음 작업 제안해줘`
|
||||
- 확인:
|
||||
- token-only completion 없음
|
||||
- compact 후 문맥 유지
|
||||
|
||||
9. 권한 승인
|
||||
- 프롬프트: `이 파일을 수정해서 저장해줘`
|
||||
- 확인:
|
||||
- 승인 요청 transcript 표시
|
||||
- 승인/거부 후 결과 정합성
|
||||
|
||||
10. slash / skill
|
||||
- 프롬프트: `/bug-hunt src 폴더 잠재 버그 찾아줘`
|
||||
- 확인:
|
||||
- slash 진입과 일반 send 경로 동일성
|
||||
- skill 실행 이유/결과 표기
|
||||
@@ -4754,3 +4754,7 @@ ow + toggle ?쒓컖 ?몄뼱濡??ㅼ떆 ?뺣젹?덈떎.
|
||||
- Document update: 2026-04-05 22:04 (KST) - Added a canonical 10-prompt regression set to `docs/claw-code-parity-plan.md` so AX Agent and `claw-code` can be compared on the same Chat/Cowork/Code scenarios: basic/long chat, document/data cowork, bug-fix/build code, queued follow-up, post-compaction continuity, permission approval, and slash skill entry.
|
||||
- Document update: 2026-04-05 22:04 (KST) - Added a tool/skill delta snapshot to the parity plan. AX remains stronger on document/office/data workflows, while `claw-code` remains stronger on transcript-native approval/tool-result/permission message taxonomy.
|
||||
- Document update: 2026-04-05 22:04 (KST) - Switched plan approval flow to transcript-first. `CreatePlanDecisionCallback()` now prepares `PlanViewerWindow` without auto-opening it, shows the inline approval controls in the transcript first, and keeps the bottom `계획` button as the secondary detail surface.
|
||||
- 업데이트: 2026-04-05 22:18 (KST)
|
||||
- transcript 도구/스킬 표시 카탈로그를 [AgentTranscriptDisplayCatalog.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Services/Agent/AgentTranscriptDisplayCatalog.cs) 로 분리했습니다. 도구 결과와 task summary 카드가 공통 분류 기준(`파일 / 빌드 / Git / 문서 / 질문 / 제안 / 스킬`)을 사용하도록 맞춰 transcript 언어 일관성을 높였습니다.
|
||||
- [ChatWindow.TranscriptPolicy.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.TranscriptPolicy.cs) 를 추가해 transcript badge/summary/task-summary policy helper 를 partial class 로 분리했습니다. `ChatWindow.xaml.cs` 본문에는 실제 렌더만 남기고, recent task 노출 정책은 `active 우선 + debug 보조` 기준으로 축소했습니다.
|
||||
- 회귀 프롬프트 세트는 [AX_AGENT_REGRESSION_PROMPTS.md](/E:/AX%20Copilot%20-%20Codex/docs/AX_AGENT_REGRESSION_PROMPTS.md) 로 별도 분리했습니다. Chat/Cowork/Code, queue follow-up, compact 이후 다음 턴, permission, slash skill 진입까지 `claw-code`와 같은 체크리스트로 비교할 수 있습니다.
|
||||
|
||||
@@ -125,6 +125,7 @@
|
||||
## Canonical Prompt Set
|
||||
- Updated: 2026-04-05 22:04 (KST)
|
||||
- The following prompt set should be used for AX vs `claw-code` parity checks. The goal is not byte-identical output, but equivalent execution route, approval behavior, and artifact/result quality.
|
||||
- Operational checklist copy: `docs/AX_AGENT_REGRESSION_PROMPTS.md`
|
||||
|
||||
1. Chat basic answer
|
||||
- Prompt: `회의 일정 조정 메일을 정중한 한국어로 써줘`
|
||||
|
||||
111
src/AxCopilot/Services/Agent/AgentTranscriptDisplayCatalog.cs
Normal file
111
src/AxCopilot/Services/Agent/AgentTranscriptDisplayCatalog.cs
Normal file
@@ -0,0 +1,111 @@
|
||||
namespace AxCopilot.Services.Agent;
|
||||
|
||||
internal static class AgentTranscriptDisplayCatalog
|
||||
{
|
||||
public static string GetDisplayName(string? rawName, bool slashPrefix = false)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(rawName))
|
||||
return slashPrefix ? "/스킬" : "도구";
|
||||
|
||||
var normalized = rawName.Trim();
|
||||
var mapped = normalized.ToLowerInvariant() switch
|
||||
{
|
||||
"file_read" => "파일 읽기",
|
||||
"file_write" => "파일 쓰기",
|
||||
"file_edit" => "파일 편집",
|
||||
"document_reader" => "문서 읽기",
|
||||
"document_planner" => "문서 계획",
|
||||
"document_assembler" => "문서 조합",
|
||||
"document_review" => "문서 검토",
|
||||
"format_convert" => "형식 변환",
|
||||
"code_search" => "코드 검색",
|
||||
"code_review" => "코드 리뷰",
|
||||
"build_run" => "빌드/실행",
|
||||
"git_tool" => "Git",
|
||||
"process" => "프로세스",
|
||||
"glob" => "파일 찾기",
|
||||
"grep" => "내용 검색",
|
||||
"folder_map" => "폴더 맵",
|
||||
"memory" => "메모리",
|
||||
"user_ask" => "의견 요청",
|
||||
"suggest_actions" => "다음 작업 제안",
|
||||
"task_create" => "작업 생성",
|
||||
"task_update" => "작업 업데이트",
|
||||
"task_list" => "작업 목록",
|
||||
"task_get" => "작업 조회",
|
||||
"task_stop" => "작업 중지",
|
||||
"task_output" => "작업 출력",
|
||||
"spawn_agent" => "서브에이전트",
|
||||
"wait_agents" => "에이전트 대기",
|
||||
_ => normalized.Replace('_', ' ').Trim(),
|
||||
};
|
||||
|
||||
if (!slashPrefix)
|
||||
return mapped;
|
||||
|
||||
return normalized.StartsWith('/') ? normalized : "/" + normalized.Replace(' ', '-');
|
||||
}
|
||||
|
||||
public static string GetEventBadgeLabel(AgentEvent evt)
|
||||
{
|
||||
if (evt.Type == AgentEventType.SkillCall)
|
||||
return "스킬";
|
||||
|
||||
if (evt.Type is AgentEventType.PermissionRequest or AgentEventType.PermissionGranted or AgentEventType.PermissionDenied)
|
||||
return "권한";
|
||||
|
||||
return GetToolCategoryLabel(evt.ToolName);
|
||||
}
|
||||
|
||||
public static string GetTaskCategoryLabel(string? kind, string? title)
|
||||
{
|
||||
if (string.Equals(kind, "permission", System.StringComparison.OrdinalIgnoreCase))
|
||||
return "권한";
|
||||
if (string.Equals(kind, "queue", System.StringComparison.OrdinalIgnoreCase))
|
||||
return "큐";
|
||||
if (string.Equals(kind, "hook", System.StringComparison.OrdinalIgnoreCase))
|
||||
return "훅";
|
||||
if (string.Equals(kind, "subagent", System.StringComparison.OrdinalIgnoreCase))
|
||||
return "에이전트";
|
||||
if (string.Equals(kind, "tool", System.StringComparison.OrdinalIgnoreCase))
|
||||
return GetToolCategoryLabel(title);
|
||||
return "작업";
|
||||
}
|
||||
|
||||
public static string BuildEventSummary(AgentEvent evt, string displayName)
|
||||
{
|
||||
var summary = (evt.Summary ?? "").Trim();
|
||||
if (!string.IsNullOrWhiteSpace(summary))
|
||||
return summary;
|
||||
|
||||
return evt.Type switch
|
||||
{
|
||||
AgentEventType.ToolCall => $"{displayName} 실행 준비",
|
||||
AgentEventType.ToolResult => evt.Success ? $"{displayName} 실행 완료" : $"{displayName} 실행 실패",
|
||||
AgentEventType.SkillCall => $"{displayName} 실행",
|
||||
AgentEventType.PermissionRequest => $"{displayName} 실행 전 사용자 확인 필요",
|
||||
AgentEventType.PermissionGranted => $"{displayName} 실행이 허용됨",
|
||||
AgentEventType.PermissionDenied => $"{displayName} 실행이 거부됨",
|
||||
_ => summary,
|
||||
};
|
||||
}
|
||||
|
||||
private static string GetToolCategoryLabel(string? rawName)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(rawName))
|
||||
return "도구";
|
||||
|
||||
return rawName.Trim().ToLowerInvariant() switch
|
||||
{
|
||||
"file_read" or "file_write" or "file_edit" or "glob" or "grep" or "folder_map" or "file_watch" or "file_info" or "file_manage" => "파일",
|
||||
"build_run" or "test_loop" or "dev_env_detect" => "빌드",
|
||||
"git_tool" or "diff_tool" or "diff_preview" => "Git",
|
||||
"document_reader" or "document_planner" or "document_assembler" or "document_review" or "format_convert" or "template_render" => "문서",
|
||||
"user_ask" => "질문",
|
||||
"suggest_actions" => "제안",
|
||||
"process" => "실행",
|
||||
"spawn_agent" or "wait_agents" => "에이전트",
|
||||
_ => "도구",
|
||||
};
|
||||
}
|
||||
}
|
||||
26
src/AxCopilot/Views/ChatWindow.TranscriptPolicy.cs
Normal file
26
src/AxCopilot/Views/ChatWindow.TranscriptPolicy.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using System.Windows.Media;
|
||||
using AxCopilot.Services;
|
||||
using AxCopilot.Services.Agent;
|
||||
|
||||
namespace AxCopilot.Views;
|
||||
|
||||
public partial class ChatWindow
|
||||
{
|
||||
private bool IsDebugTranscriptMode()
|
||||
=> string.Equals(_settings.Settings.Llm.AgentLogLevel, "debug", StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
private string GetTranscriptBadgeLabel(AgentEvent evt)
|
||||
=> AgentTranscriptDisplayCatalog.GetEventBadgeLabel(evt);
|
||||
|
||||
private string GetTranscriptTaskCategory(TaskRunStore.TaskRun task)
|
||||
=> AgentTranscriptDisplayCatalog.GetTaskCategoryLabel(task.Kind, task.Title);
|
||||
|
||||
private string GetTranscriptDisplayName(string? rawName, bool slashPrefix = false)
|
||||
=> AgentTranscriptDisplayCatalog.GetDisplayName(rawName, slashPrefix);
|
||||
|
||||
private string GetTranscriptEventSummary(AgentEvent evt, string displayName)
|
||||
=> AgentTranscriptDisplayCatalog.BuildEventSummary(evt, displayName);
|
||||
|
||||
private bool ShouldIncludeRecentTaskSummary(IReadOnlyCollection<TaskRunStore.TaskRun> activeTasks)
|
||||
=> IsDebugTranscriptMode() || activeTasks.Count == 0;
|
||||
}
|
||||
@@ -9375,73 +9375,16 @@ public partial class ChatWindow : Window
|
||||
_ => "진행 중",
|
||||
};
|
||||
|
||||
private static string GetAgentItemDisplayName(string? rawName, bool slashPrefix = false)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(rawName))
|
||||
return slashPrefix ? "/스킬" : "도구";
|
||||
|
||||
var normalized = rawName.Trim();
|
||||
var mapped = normalized.ToLowerInvariant() switch
|
||||
{
|
||||
"file_read" => "파일 읽기",
|
||||
"file_write" => "파일 쓰기",
|
||||
"file_edit" => "파일 편집",
|
||||
"document_reader" => "문서 읽기",
|
||||
"document_planner" => "문서 계획",
|
||||
"document_assembler" => "문서 조합",
|
||||
"code_search" => "코드 검색",
|
||||
"code_review" => "코드 리뷰",
|
||||
"build_run" => "빌드/실행",
|
||||
"git_tool" => "Git",
|
||||
"process" => "프로세스",
|
||||
"glob" => "파일 찾기",
|
||||
"grep" => "내용 검색",
|
||||
"folder_map" => "폴더 맵",
|
||||
"memory" => "메모리",
|
||||
"user_ask" => "의견 요청",
|
||||
"suggest_actions" => "다음 작업 제안",
|
||||
"task_create" => "작업 생성",
|
||||
"task_update" => "작업 업데이트",
|
||||
"task_list" => "작업 목록",
|
||||
"task_get" => "작업 조회",
|
||||
"task_stop" => "작업 중지",
|
||||
"task_output" => "작업 출력",
|
||||
"spawn_agent" => "서브에이전트",
|
||||
"wait_agents" => "에이전트 대기",
|
||||
_ => normalized.Replace('_', ' ').Trim(),
|
||||
};
|
||||
|
||||
if (!slashPrefix)
|
||||
return mapped;
|
||||
|
||||
var slashName = normalized.StartsWith('/')
|
||||
? normalized
|
||||
: "/" + normalized.Replace(' ', '-');
|
||||
return slashName;
|
||||
}
|
||||
private string GetAgentItemDisplayName(string? rawName, bool slashPrefix = false)
|
||||
=> GetTranscriptDisplayName(rawName, slashPrefix);
|
||||
|
||||
private static bool IsTranscriptToolLikeEvent(AgentEvent evt)
|
||||
=> evt.Type is AgentEventType.ToolCall or AgentEventType.ToolResult or AgentEventType.SkillCall
|
||||
|| (!string.IsNullOrWhiteSpace(evt.ToolName)
|
||||
&& evt.Type is AgentEventType.PermissionRequest or AgentEventType.PermissionGranted or AgentEventType.PermissionDenied);
|
||||
|
||||
private static string BuildAgentEventSummaryText(AgentEvent evt, string displayName)
|
||||
{
|
||||
var summary = (evt.Summary ?? "").Trim();
|
||||
if (!string.IsNullOrWhiteSpace(summary))
|
||||
return summary;
|
||||
|
||||
return evt.Type switch
|
||||
{
|
||||
AgentEventType.ToolCall => $"{displayName} 실행 준비",
|
||||
AgentEventType.ToolResult => evt.Success ? $"{displayName} 실행 완료" : $"{displayName} 실행 실패",
|
||||
AgentEventType.SkillCall => $"{displayName} 실행",
|
||||
AgentEventType.PermissionRequest => $"{displayName} 실행 전 사용자 확인 필요",
|
||||
AgentEventType.PermissionGranted => $"{displayName} 실행이 허용됨",
|
||||
AgentEventType.PermissionDenied => $"{displayName} 실행이 거부됨",
|
||||
_ => summary,
|
||||
};
|
||||
}
|
||||
private string BuildAgentEventSummaryText(AgentEvent evt, string displayName)
|
||||
=> GetTranscriptEventSummary(evt, displayName);
|
||||
|
||||
private IEnumerable<TaskRunStore.TaskRun> FilterTaskSummaryItems(IEnumerable<TaskRunStore.TaskRun> tasks)
|
||||
=> _taskSummaryTaskFilter switch
|
||||
@@ -10794,9 +10737,9 @@ public partial class ChatWindow : Window
|
||||
AgentEventType.PermissionGranted => GetPermissionBadgeMeta(evt.ToolName, pending: false),
|
||||
AgentEventType.PermissionDenied => ("\uE783", "권한 거부", "#FEF2F2", "#DC2626"),
|
||||
AgentEventType.Decision => GetDecisionBadgeMeta(evt.Summary),
|
||||
AgentEventType.ToolCall => ("\uE8A7", "도구", "#EEF6FF", "#3B82F6"),
|
||||
AgentEventType.ToolResult => ("\uE73E", "도구 결과", "#EEF9EE", "#16A34A"),
|
||||
AgentEventType.SkillCall => ("\uE8A5", "스킬", "#FFF7ED", "#EA580C"),
|
||||
AgentEventType.ToolCall => ("\uE8A7", GetTranscriptBadgeLabel(evt), "#EEF6FF", "#3B82F6"),
|
||||
AgentEventType.ToolResult => ("\uE73E", GetTranscriptBadgeLabel(evt), "#EEF9EE", "#16A34A"),
|
||||
AgentEventType.SkillCall => ("\uE8A5", GetTranscriptBadgeLabel(evt), "#FFF7ED", "#EA580C"),
|
||||
AgentEventType.Error => ("\uE783", "오류", "#FEF2F2", "#DC2626"),
|
||||
AgentEventType.Complete => ("\uE930", "완료", "#F0FFF4", "#15803D"),
|
||||
AgentEventType.StepDone => ("\uE73E", "단계 완료", "#EEF9EE", "#16A34A"),
|
||||
@@ -20795,13 +20738,19 @@ private static (string icon, string label, string bgHex, string fgHex) GetDecisi
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var task in FilterTaskSummaryItems(_appState.ActiveTasks).Take(3))
|
||||
var activeTasks = FilterTaskSummaryItems(_appState.ActiveTasks).Take(3).ToList();
|
||||
var recentTasks = FilterTaskSummaryItems(_appState.RecentTasks).Take(2).ToList();
|
||||
|
||||
foreach (var task in activeTasks)
|
||||
panel.Children.Add(BuildTaskSummaryCard(task, active: true));
|
||||
|
||||
foreach (var task in FilterTaskSummaryItems(_appState.RecentTasks).Take(2))
|
||||
panel.Children.Add(BuildTaskSummaryCard(task, active: false));
|
||||
if (ShouldIncludeRecentTaskSummary(activeTasks))
|
||||
{
|
||||
foreach (var task in recentTasks)
|
||||
panel.Children.Add(BuildTaskSummaryCard(task, active: false));
|
||||
}
|
||||
|
||||
if (!FilterTaskSummaryItems(_appState.ActiveTasks).Any() && !FilterTaskSummaryItems(_appState.RecentTasks).Any())
|
||||
if (activeTasks.Count == 0 && recentTasks.Count == 0)
|
||||
{
|
||||
panel.Children.Add(new TextBlock
|
||||
{
|
||||
@@ -21591,6 +21540,7 @@ private static (string icon, string label, string bgHex, string fgHex) GetDecisi
|
||||
var primaryText = TryFindResource("PrimaryText") as Brush ?? Brushes.Black;
|
||||
var secondaryText = TryFindResource("SecondaryText") as Brush ?? Brushes.DimGray;
|
||||
var (kindIcon, kindColor) = GetTaskKindVisual(task.Kind);
|
||||
var categoryLabel = GetTranscriptTaskCategory(task);
|
||||
var displayTitle = string.Equals(task.Kind, "tool", StringComparison.OrdinalIgnoreCase)
|
||||
|| string.Equals(task.Kind, "permission", StringComparison.OrdinalIgnoreCase)
|
||||
|| string.Equals(task.Kind, "hook", StringComparison.OrdinalIgnoreCase)
|
||||
@@ -21623,6 +21573,24 @@ private static (string icon, string label, string bgHex, string fgHex) GetDecisi
|
||||
});
|
||||
taskStack.Children.Add(headerRow);
|
||||
|
||||
taskStack.Children.Add(new Border
|
||||
{
|
||||
Background = BrushFromHex("#F8FAFC"),
|
||||
BorderBrush = BrushFromHex("#E5E7EB"),
|
||||
BorderThickness = new Thickness(1),
|
||||
CornerRadius = new CornerRadius(999),
|
||||
Padding = new Thickness(6, 1, 6, 1),
|
||||
Margin = new Thickness(0, 0, 0, 4),
|
||||
HorizontalAlignment = HorizontalAlignment.Left,
|
||||
Child = new TextBlock
|
||||
{
|
||||
Text = categoryLabel,
|
||||
FontSize = 8,
|
||||
FontWeight = FontWeights.SemiBold,
|
||||
Foreground = secondaryText,
|
||||
},
|
||||
});
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(task.Summary))
|
||||
{
|
||||
taskStack.Children.Add(new TextBlock
|
||||
|
||||
Reference in New Issue
Block a user