AX Agent 도구·스킬 정합성 재구성 및 실행 품질 보강
변경 목적: - AX Agent의 도구 이름, 내부 설정, 스킬 정책, 실행 루프 사이의 불일치를 줄이고 전체 동작 품질을 높인다. - claw-code 수준의 일관된 동작 품질을 참고하되 AX 구조에 맞는 고유한 카탈로그·정규화 레이어로 재구성한다. 핵심 수정사항: - 도구 canonical id, legacy alias, 탭 노출, 설정 카테고리, read-only 분류를 중앙 카탈로그로 통합했다. - ToolRegistry, AgentLoopService, 병렬 실행 분류, 권한 처리, 훅 처리, 스킬 allowed-tools 해석이 같은 이름 체계를 사용하도록 정리했다. - Agent 설정/일반 설정/도움말의 도구 카드와 훅 편집기, 스킬 설명을 현재 런타임 구조에 맞게 갱신했다. - 컨텍스트 압축, intent gate, spawn agents, session learning, model prompt adapter, workspace context 관련 변경과 테스트 추가를 함께 반영했다. - 문서 이력과 비교/로드맵 문서를 최신 상태로 갱신했다. 검증 결과: - dotnet build src/AxCopilot/AxCopilot.csproj -c Release -v minimal -p:OutputPath=bin\verify_toolcat\ -p:IntermediateOutputPath=obj\verify_toolcat\ : 경고 0 / 오류 0 - dotnet test src/AxCopilot.Tests/AxCopilot.Tests.csproj -c Release -v minimal --filter AgentToolCatalogTests -p:OutputPath=bin\verify_toolcat_tests\ -p:IntermediateOutputPath=obj\verify_toolcat_tests\ : 통과 8
This commit is contained in:
@@ -185,14 +185,46 @@ public partial class ChatWindow
|
||||
Margin = new Thickness(0, 6, 0, 0),
|
||||
};
|
||||
var detailStack = new StackPanel();
|
||||
var codeBg = TryFindResource("HintBackground") as Brush ?? Brushes.DarkGray;
|
||||
|
||||
// 도구 입력 파라미터 (ToolInput이 있으면 표시)
|
||||
var toolInput = toolCall.ToolInput;
|
||||
if (!string.IsNullOrWhiteSpace(toolInput))
|
||||
{
|
||||
detailStack.Children.Add(new TextBlock
|
||||
{
|
||||
Text = "입력",
|
||||
FontSize = 10,
|
||||
FontWeight = FontWeights.SemiBold,
|
||||
Foreground = secondaryText,
|
||||
Opacity = 0.7,
|
||||
Margin = new Thickness(0, 0, 0, 3),
|
||||
});
|
||||
detailStack.Children.Add(MarkdownRenderer.Render(
|
||||
$"```json\n{TruncateForDisplay(toolInput, 1200)}\n```",
|
||||
primaryText, secondaryText, accentBrush, codeBg));
|
||||
}
|
||||
|
||||
// 도구 결과 상세 내용
|
||||
var resultSummary = toolResult.Summary;
|
||||
if (!string.IsNullOrWhiteSpace(resultSummary) && resultSummary.Length > 80)
|
||||
if (!string.IsNullOrWhiteSpace(resultSummary))
|
||||
{
|
||||
var codeBg = TryFindResource("HintBackground") as Brush ?? Brushes.DarkGray;
|
||||
// 입력이 이미 있으면 "결과" 라벨 추가
|
||||
if (detailStack.Children.Count > 0)
|
||||
{
|
||||
detailStack.Children.Add(new TextBlock
|
||||
{
|
||||
Text = "결과",
|
||||
FontSize = 10,
|
||||
FontWeight = FontWeights.SemiBold,
|
||||
Foreground = secondaryText,
|
||||
Opacity = 0.7,
|
||||
Margin = new Thickness(0, 6, 0, 3),
|
||||
});
|
||||
}
|
||||
detailStack.Children.Add(MarkdownRenderer.Render(
|
||||
$"```\n{resultSummary}\n```", primaryText, secondaryText, accentBrush, codeBg));
|
||||
$"```\n{TruncateForDisplay(resultSummary, 2000)}\n```",
|
||||
primaryText, secondaryText, accentBrush, codeBg));
|
||||
}
|
||||
|
||||
// 토큰 메타 정보
|
||||
@@ -215,19 +247,22 @@ public partial class ChatWindow
|
||||
}
|
||||
|
||||
detailBorder.Child = detailStack;
|
||||
// 상세 내용이 없으면 화살표도 숨김
|
||||
var hasDetail = detailStack.Children.Count > 0;
|
||||
cardStack.Children.Add(detailBorder);
|
||||
|
||||
// 펼치기 토글 화살표
|
||||
// 펼치기 토글 화살표 (상세 내용이 있을 때만 표시)
|
||||
var arrowTb = new TextBlock
|
||||
{
|
||||
Text = "\uE76C", // 아래 화살표
|
||||
FontFamily = s_segoeIconFont,
|
||||
FontSize = 9,
|
||||
Foreground = secondaryText,
|
||||
Opacity = 0.5,
|
||||
Opacity = 0.7,
|
||||
HorizontalAlignment = HorizontalAlignment.Center,
|
||||
Margin = new Thickness(0, 3, 0, 0),
|
||||
Cursor = Cursors.Hand,
|
||||
Visibility = hasDetail ? Visibility.Visible : Visibility.Collapsed,
|
||||
};
|
||||
cardStack.Children.Add(arrowTb);
|
||||
|
||||
@@ -243,11 +278,20 @@ public partial class ChatWindow
|
||||
arrowTb.Text = isExpanded ? "\uE76C" : "\uE76B"; // 아래↔위
|
||||
};
|
||||
|
||||
// 호버 효과
|
||||
var normalBg = hintBg;
|
||||
var hoverBg = TryFindResource("ItemHoverBackground") as Brush ?? hintBg;
|
||||
card.MouseEnter += (_, _) => card.Background = hoverBg;
|
||||
card.MouseLeave += (_, _) => card.Background = normalBg;
|
||||
// 호버 효과 (부드러운 전환)
|
||||
card.MouseEnter += (_, _) =>
|
||||
{
|
||||
card.BeginAnimation(UIElement.OpacityProperty,
|
||||
new DoubleAnimation(1.0, TimeSpan.FromMilliseconds(120)));
|
||||
card.Background = TryFindResource("ItemHoverBackground") as Brush ?? hintBg;
|
||||
};
|
||||
card.MouseLeave += (_, _) =>
|
||||
{
|
||||
card.BeginAnimation(UIElement.OpacityProperty,
|
||||
new DoubleAnimation(0.92, TimeSpan.FromMilliseconds(200)));
|
||||
card.Background = hintBg;
|
||||
};
|
||||
card.Opacity = 0.92;
|
||||
|
||||
return outerGrid;
|
||||
}
|
||||
@@ -283,7 +327,7 @@ public partial class ChatWindow
|
||||
var thinkLine = new Border
|
||||
{
|
||||
Width = 2,
|
||||
Background = new SolidColorBrush(Color.FromArgb(0x40, 0x59, 0xA5, 0xF5)),
|
||||
Background = new SolidColorBrush(Color.FromArgb(0x60, 0x59, 0xA5, 0xF5)),
|
||||
CornerRadius = new CornerRadius(1),
|
||||
Margin = new Thickness(12, 0, 8, 0),
|
||||
};
|
||||
@@ -292,8 +336,8 @@ public partial class ChatWindow
|
||||
|
||||
var thinkCard = new Border
|
||||
{
|
||||
Background = new SolidColorBrush(Color.FromArgb(0x0A, 0x59, 0xA5, 0xF5)),
|
||||
BorderBrush = new SolidColorBrush(Color.FromArgb(0x30, 0x59, 0xA5, 0xF5)),
|
||||
Background = new SolidColorBrush(Color.FromArgb(0x1C, 0x59, 0xA5, 0xF5)),
|
||||
BorderBrush = new SolidColorBrush(Color.FromArgb(0x40, 0x59, 0xA5, 0xF5)),
|
||||
BorderThickness = new Thickness(1),
|
||||
CornerRadius = new CornerRadius(8),
|
||||
Padding = new Thickness(10, 6, 10, 6),
|
||||
@@ -316,7 +360,7 @@ public partial class ChatWindow
|
||||
FontSize = 11,
|
||||
FontStyle = FontStyles.Italic,
|
||||
Foreground = secondaryText,
|
||||
Opacity = 0.75,
|
||||
Opacity = 0.88,
|
||||
TextWrapping = TextWrapping.Wrap,
|
||||
MaxWidth = msgMaxWidth - 60,
|
||||
});
|
||||
@@ -428,12 +472,12 @@ public partial class ChatWindow
|
||||
|
||||
var banner = new Border
|
||||
{
|
||||
Background = new SolidColorBrush(Color.FromArgb(0x18, 0x66, 0xBB, 0x6A)),
|
||||
BorderBrush = new SolidColorBrush(Color.FromArgb(0x40, 0x66, 0xBB, 0x6A)),
|
||||
Background = new SolidColorBrush(Color.FromArgb(0x24, 0x66, 0xBB, 0x6A)),
|
||||
BorderBrush = new SolidColorBrush(Color.FromArgb(0x50, 0x66, 0xBB, 0x6A)),
|
||||
BorderThickness = new Thickness(1),
|
||||
CornerRadius = new CornerRadius(8),
|
||||
Padding = new Thickness(12, 6, 12, 6),
|
||||
Margin = new Thickness(0, 4, 0, 4),
|
||||
Padding = new Thickness(14, 8, 14, 8),
|
||||
Margin = new Thickness(0, 6, 0, 4),
|
||||
HorizontalAlignment = HorizontalAlignment.Center,
|
||||
MaxWidth = msgMaxWidth,
|
||||
};
|
||||
@@ -465,12 +509,12 @@ public partial class ChatWindow
|
||||
var msgMaxWidth = GetMessageMaxWidth();
|
||||
var banner = new Border
|
||||
{
|
||||
Background = new SolidColorBrush(Color.FromArgb(0x18, 0xEF, 0x53, 0x50)),
|
||||
BorderBrush = new SolidColorBrush(Color.FromArgb(0x40, 0xEF, 0x53, 0x50)),
|
||||
Background = new SolidColorBrush(Color.FromArgb(0x24, 0xEF, 0x53, 0x50)),
|
||||
BorderBrush = new SolidColorBrush(Color.FromArgb(0x50, 0xEF, 0x53, 0x50)),
|
||||
BorderThickness = new Thickness(1),
|
||||
CornerRadius = new CornerRadius(8),
|
||||
Padding = new Thickness(12, 6, 12, 6),
|
||||
Margin = new Thickness(0, 4, 0, 4),
|
||||
Padding = new Thickness(14, 8, 14, 8),
|
||||
Margin = new Thickness(0, 6, 0, 4),
|
||||
HorizontalAlignment = HorizontalAlignment.Center,
|
||||
MaxWidth = msgMaxWidth,
|
||||
};
|
||||
@@ -598,4 +642,12 @@ public partial class ChatWindow
|
||||
|
||||
return path[..remaining] + ".../" + fileName;
|
||||
}
|
||||
|
||||
/// <summary>긴 텍스트를 지정 길이로 잘라서 표시용으로 반환합니다.</summary>
|
||||
private static string TruncateForDisplay(string text, int maxLength)
|
||||
{
|
||||
if (string.IsNullOrEmpty(text) || text.Length <= maxLength)
|
||||
return text;
|
||||
return text[..maxLength] + "\n… (truncated)";
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user