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:
@@ -15,135 +15,7 @@ public partial class ChatWindow
|
||||
if (MessageList == null) return;
|
||||
if (!string.Equals(runTab, _activeTab, StringComparison.OrdinalIgnoreCase)) return;
|
||||
|
||||
// V2 분기
|
||||
if (_settings.Settings.Llm.EnableNewChatRendering)
|
||||
{
|
||||
ShowAgentLiveCardV2(runTab);
|
||||
return;
|
||||
}
|
||||
|
||||
RemoveAgentLiveCard(animated: false);
|
||||
|
||||
_agentLiveStartTime = DateTime.UtcNow;
|
||||
_agentLiveSubItemTexts.Clear();
|
||||
_agentLiveCurrentCategory = null;
|
||||
|
||||
var msgMaxWidth = GetMessageMaxWidth();
|
||||
var secondaryText = TryFindResource("SecondaryText") as Brush ?? Brushes.Gray;
|
||||
var borderBrush = TryFindResource("BorderColor") as Brush ?? Brushes.Gray;
|
||||
|
||||
var container = new StackPanel
|
||||
{
|
||||
HorizontalAlignment = HorizontalAlignment.Center,
|
||||
Width = msgMaxWidth,
|
||||
MaxWidth = msgMaxWidth,
|
||||
Margin = new Thickness(0, 4, 0, 6),
|
||||
Opacity = IsLightweightLiveProgressMode(runTab) ? 1 : 0,
|
||||
RenderTransform = IsLightweightLiveProgressMode(runTab)
|
||||
? Transform.Identity
|
||||
: new TranslateTransform(0, 8),
|
||||
};
|
||||
if (!IsLightweightLiveProgressMode(runTab))
|
||||
{
|
||||
container.BeginAnimation(UIElement.OpacityProperty,
|
||||
new DoubleAnimation(0, 1, TimeSpan.FromMilliseconds(260)));
|
||||
((TranslateTransform)container.RenderTransform).BeginAnimation(
|
||||
TranslateTransform.YProperty,
|
||||
new DoubleAnimation(8, 0, TimeSpan.FromMilliseconds(280))
|
||||
{
|
||||
EasingFunction = new QuadraticEase { EasingMode = EasingMode.EaseOut }
|
||||
});
|
||||
}
|
||||
|
||||
var headerGrid = new Grid { Margin = new Thickness(2, 0, 0, 3) };
|
||||
headerGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
|
||||
headerGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
|
||||
headerGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
|
||||
|
||||
var (agentName, _, _) = GetAgentIdentity();
|
||||
var (liveIconHost, livePixels, liveGlows, liveRotate, liveScale) = CreateMiniLauncherIconEx(4.0, "none");
|
||||
{
|
||||
// 모든 모드에서 동일한 순차 점멸 애니메이션 적용
|
||||
var canvas = liveIconHost.Children.OfType<Canvas>().FirstOrDefault();
|
||||
if (canvas != null)
|
||||
{
|
||||
var animState = new ChatIconAnimState
|
||||
{
|
||||
Host = liveIconHost, Canvas = canvas, Pixels = livePixels,
|
||||
Glows = liveGlows, Rotate = liveRotate, Scale = liveScale,
|
||||
IsRandomMode = _settings.Settings.Launcher.EnableChatIconRandomAnimation,
|
||||
};
|
||||
StartChatIconAnimation(animState);
|
||||
}
|
||||
}
|
||||
|
||||
Grid.SetColumn(liveIconHost, 0);
|
||||
headerGrid.Children.Add(liveIconHost);
|
||||
var nameTb = new TextBlock
|
||||
{
|
||||
Text = agentName,
|
||||
FontSize = 11,
|
||||
FontWeight = FontWeights.SemiBold,
|
||||
Foreground = secondaryText,
|
||||
Margin = new Thickness(6, 0, 0, 0),
|
||||
VerticalAlignment = VerticalAlignment.Center,
|
||||
};
|
||||
Grid.SetColumn(nameTb, 1);
|
||||
headerGrid.Children.Add(nameTb);
|
||||
|
||||
_agentLiveElapsedText = new TextBlock
|
||||
{
|
||||
Text = "",
|
||||
FontSize = 10,
|
||||
Foreground = secondaryText,
|
||||
Opacity = 0.50,
|
||||
HorizontalAlignment = HorizontalAlignment.Right,
|
||||
VerticalAlignment = VerticalAlignment.Center,
|
||||
};
|
||||
Grid.SetColumn(_agentLiveElapsedText, 2);
|
||||
headerGrid.Children.Add(_agentLiveElapsedText);
|
||||
container.Children.Add(headerGrid);
|
||||
|
||||
var card = new Border
|
||||
{
|
||||
BorderBrush = borderBrush,
|
||||
BorderThickness = new Thickness(1),
|
||||
CornerRadius = new CornerRadius(12),
|
||||
Padding = new Thickness(13, 10, 13, 10),
|
||||
};
|
||||
card.SetResourceReference(Border.BackgroundProperty, "ItemBackground");
|
||||
|
||||
var cardStack = new StackPanel();
|
||||
_agentLiveStatusText = new TextBlock
|
||||
{
|
||||
Text = "준비 중...",
|
||||
FontSize = 12,
|
||||
FontFamily = s_segoeUiFont,
|
||||
Foreground = secondaryText,
|
||||
TextWrapping = TextWrapping.Wrap,
|
||||
};
|
||||
cardStack.Children.Add(_agentLiveStatusText);
|
||||
|
||||
_agentLiveSubItems = new StackPanel { Margin = new Thickness(0, 6, 0, 0) };
|
||||
cardStack.Children.Add(_agentLiveSubItems);
|
||||
|
||||
card.Child = cardStack;
|
||||
container.Children.Add(card);
|
||||
|
||||
_agentLiveContainer = container;
|
||||
AddTranscriptElement(container);
|
||||
ForceScrollToEnd();
|
||||
|
||||
_agentLiveElapsedTimer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) };
|
||||
_agentLiveElapsedTimer.Tick += (_, _) =>
|
||||
{
|
||||
if (_agentLiveElapsedText == null)
|
||||
return;
|
||||
|
||||
var sec = (int)(DateTime.UtcNow - _agentLiveStartTime).TotalSeconds;
|
||||
_agentLiveElapsedText.Text = sec > 0 ? $"{sec}초 경과" : "";
|
||||
};
|
||||
_agentLiveElapsedTimer.Start();
|
||||
ShowAgentLiveCardV2(runTab);
|
||||
}
|
||||
|
||||
private void UpdateAgentLiveCard(string message, string? subItem = null,
|
||||
|
||||
Reference in New Issue
Block a user