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:
@@ -18,11 +18,29 @@ public partial class ChatWindow
|
||||
var isToolApproval = options.Contains("확인") && !options.Contains("승인");
|
||||
if (isToolApproval)
|
||||
{
|
||||
string? toolResult = null;
|
||||
await Dispatcher.InvokeAsync(() =>
|
||||
// ToolApprovalWindow.Show는 Dispatcher에서 동기 호출된다.
|
||||
// 장시간 미응답 시 에이전트 루프가 멈추는 것을 방지하기 위해 10분 가드를 두고,
|
||||
// 타임아웃 발생 시 CancellationToken으로 다이얼로그 자체를 닫아 UI를 정리한다.
|
||||
using var toolTimeoutCts = new CancellationTokenSource(TimeSpan.FromMinutes(10));
|
||||
var toolTcs = new TaskCompletionSource<string?>();
|
||||
_ = Dispatcher.InvokeAsync(() =>
|
||||
{
|
||||
toolResult = ToolApprovalWindow.Show(this, planSummary, options);
|
||||
try
|
||||
{
|
||||
var r = ToolApprovalWindow.Show(this, planSummary, options, toolTimeoutCts.Token);
|
||||
toolTcs.TrySetResult(r);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
toolTcs.TrySetException(ex);
|
||||
}
|
||||
});
|
||||
var toolResult = await toolTcs.Task;
|
||||
if (toolTimeoutCts.IsCancellationRequested && string.IsNullOrEmpty(toolResult))
|
||||
{
|
||||
// 타임아웃 — 안전한 선택(중단)으로 폴백
|
||||
return options.Contains("중단") ? "중단" : (options.Contains("취소") ? "취소" : "건너뛰기");
|
||||
}
|
||||
return toolResult;
|
||||
}
|
||||
|
||||
@@ -88,18 +106,9 @@ public partial class ChatWindow
|
||||
if (_planViewerWindow != null && IsPlanWindowAlive())
|
||||
return;
|
||||
|
||||
if (_settings.Settings.Llm.EnableNewPlanViewer)
|
||||
{
|
||||
var v2 = new PlanViewerWindowV2(this);
|
||||
v2.Closing += (_, e) => { e.Cancel = true; v2.Hide(); };
|
||||
_planViewerWindow = v2;
|
||||
}
|
||||
else
|
||||
{
|
||||
var v1 = new PlanViewerWindow(this);
|
||||
v1.Closing += (_, e) => { e.Cancel = true; v1.Hide(); };
|
||||
_planViewerWindow = v1;
|
||||
}
|
||||
var v2 = new PlanViewerWindowV2(this);
|
||||
v2.Closing += (_, e) => { e.Cancel = true; v2.Hide(); };
|
||||
_planViewerWindow = v2;
|
||||
}
|
||||
|
||||
private bool IsPlanWindowAlive() => IsWindowAlive(_planViewerWindow as Window);
|
||||
|
||||
Reference in New Issue
Block a user