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:
@@ -232,20 +232,15 @@ public partial class ChatWindow
|
||||
if (viewportWidth < 200)
|
||||
return false;
|
||||
|
||||
// claw-code처럼 메시지 축과 입력축이 같은 중심선을 공유하도록,
|
||||
// 메시지 축과 입력축이 같은 중심선을 공유하도록
|
||||
// 본문 폭 상한을 조금 더 낮추고 창 폭 변화에 더 부드럽게 반응시킵니다.
|
||||
var contentWidth = Math.Max(360, viewportWidth - 24);
|
||||
var messageWidth = Math.Clamp(contentWidth * 0.9, 360, 960);
|
||||
var composerWidth = Math.Clamp(contentWidth * 0.86, 360, 900);
|
||||
|
||||
if (contentWidth < 760)
|
||||
{
|
||||
messageWidth = Math.Clamp(contentWidth - 10, 344, 820);
|
||||
composerWidth = Math.Clamp(contentWidth - 14, 340, 780);
|
||||
}
|
||||
// 고정 최대폭 — 큰 창에서 안정적, 작은 창에서만 축소
|
||||
var messageWidth = Math.Min(contentWidth - 10, 800);
|
||||
var composerWidth = Math.Min(contentWidth - 24, 760);
|
||||
|
||||
var changed = false;
|
||||
if (Math.Abs(_lastResponsiveMessageWidth - messageWidth) > 1)
|
||||
if (Math.Abs(_lastResponsiveMessageWidth - messageWidth) > 8)
|
||||
{
|
||||
_lastResponsiveMessageWidth = messageWidth;
|
||||
if (MessageList != null)
|
||||
@@ -255,7 +250,7 @@ public partial class ChatWindow
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (Math.Abs(_lastResponsiveComposerWidth - composerWidth) > 1)
|
||||
if (Math.Abs(_lastResponsiveComposerWidth - composerWidth) > 8)
|
||||
{
|
||||
_lastResponsiveComposerWidth = composerWidth;
|
||||
if (ComposerShell != null)
|
||||
@@ -293,6 +288,7 @@ public partial class ChatWindow
|
||||
var headerGrid = new Grid { Margin = new Thickness(2, 0, 0, 2) };
|
||||
headerGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
|
||||
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 aiIcon = new TextBlock
|
||||
@@ -320,6 +316,29 @@ public partial class ChatWindow
|
||||
Grid.SetColumn(aiNameTb, 1);
|
||||
headerGrid.Children.Add(aiNameTb);
|
||||
|
||||
// 유니코드 스피너 (에이전트 이름 옆)
|
||||
var spinChars = new[] { "\u00b7", "\u2722", "\u2733", "\u2736", "\u273b", "\u273d" };
|
||||
var spinIndex = 0;
|
||||
var spinnerText = new TextBlock
|
||||
{
|
||||
Text = spinChars[0],
|
||||
FontFamily = new FontFamily("Consolas"),
|
||||
FontSize = 13,
|
||||
VerticalAlignment = VerticalAlignment.Center,
|
||||
Margin = new Thickness(6, 0, 0, 0),
|
||||
};
|
||||
spinnerText.SetResourceReference(TextBlock.ForegroundProperty, "AccentColor");
|
||||
var spinTimer = new System.Windows.Threading.DispatcherTimer { Interval = TimeSpan.FromMilliseconds(333) };
|
||||
spinTimer.Tick += (_, _) =>
|
||||
{
|
||||
spinIndex = (spinIndex + 1) % spinChars.Length;
|
||||
spinnerText.Text = spinChars[spinIndex];
|
||||
};
|
||||
spinTimer.Start();
|
||||
_activeSpinnerTimer = spinTimer;
|
||||
Grid.SetColumn(spinnerText, 2);
|
||||
headerGrid.Children.Add(spinnerText);
|
||||
|
||||
// 실시간 경과 시간 (헤더 우측)
|
||||
_elapsedLabel = new TextBlock
|
||||
{
|
||||
@@ -330,7 +349,7 @@ public partial class ChatWindow
|
||||
VerticalAlignment = VerticalAlignment.Center,
|
||||
Opacity = 0.5,
|
||||
};
|
||||
Grid.SetColumn(_elapsedLabel, 2);
|
||||
Grid.SetColumn(_elapsedLabel, 3);
|
||||
headerGrid.Children.Add(_elapsedLabel);
|
||||
|
||||
container.Children.Add(headerGrid);
|
||||
@@ -601,11 +620,12 @@ public partial class ChatWindow
|
||||
else
|
||||
foreach (var cts in _tabStreamCts.Values) cts.Cancel();
|
||||
|
||||
// 대기열 정리: 실행 중 + 대기 중 항목 모두 제거 (중지는 "전부 멈춤"을 의미)
|
||||
// 대기열 정리: 실행 중인 항목만 취소, 대기 중 항목은 보존
|
||||
lock (_convLock)
|
||||
{
|
||||
_draftQueueProcessor.CancelRunning(ChatSession, _activeTab, _storage);
|
||||
_draftQueueProcessor.ClearQueued(ChatSession, _activeTab, _storage);
|
||||
// Queue preserved — user can manually clear or items will execute on next send
|
||||
// _draftQueueProcessor.ClearQueued(ChatSession, _activeTab, _storage);
|
||||
_runningDraftId = null;
|
||||
}
|
||||
RefreshDraftQueueUi();
|
||||
|
||||
Reference in New Issue
Block a user