탭별 설정 해석기를 도입해 Cowork/Code 분기 동작을 단일화
Some checks failed
Release Gate / gate (push) Has been cancelled
Some checks failed
Release Gate / gate (push) Has been cancelled
- AgentTabSettingsResolver 신규 추가: 탭 판별, post-tool 검증 활성 여부, Code 전용 비활성 도구 목록 계산 - AgentLoopService.MergeDisabledTools에서 Code 전용 도구 비활성 계산을 resolver 경로로 전환 - AgentLoopTransitions.Execution에서 post-tool verification 판단 시 resolver 결과를 사용하도록 정리 - AgentTabSettingsResolverTests 신규 추가(탭 판별/검증 플래그 분기/비활성 도구 계산) - README.md 업데이트 시각(2026-04-04 13:32 KST) 및 변경 이력 항목 갱신 - docs/DEVELOPMENT.md 연속 실행 28차 이력 추가 - 검증: dotnet build(use shared compilation off) 경고 0/오류 0, 필터 테스트 49건 통과
This commit is contained in:
@@ -222,7 +222,7 @@ public class MyHandler : IActionHandler
|
||||
|
||||
### v0.7.3 — AX Agent 권한 코어 재구성 + 입력 계층 정리
|
||||
|
||||
업데이트: 2026-04-04 13:25 (KST)
|
||||
업데이트: 2026-04-04 13:32 (KST)
|
||||
|
||||
| 분류 | 내용 |
|
||||
|------|------|
|
||||
@@ -278,6 +278,7 @@ public class MyHandler : IActionHandler
|
||||
| slash 명령 카탈로그 분리 | `ChatWindow` 내부 대형 slash 사전을 `SlashCommandCatalog`로 분리해 입력 계층 결합도를 낮추고 유지보수 범위를 축소 |
|
||||
| slash 조회 API 전환 | 내장 slash 매칭/조회 경로를 `SlashCommandCatalog.MatchBuiltinCommands`/`TryGetEntry`로 통일 |
|
||||
| 권한 표시 카탈로그 분리 | 권한 모드 라벨/설명/아이콘/색을 `PermissionModePresentationCatalog`로 분리해 팝업 표면 기준을 단일화 |
|
||||
| 탭별 설정 해석기 도입 | `AgentTabSettingsResolver`를 추가해 Cowork/Code 분기(검증 활성/Code 전용 도구 비활성)를 단일 경로로 정리 |
|
||||
| Slash palette 상태 분리 시작 | `ChatWindow`에 몰려 있던 slash 상태를 `SlashPaletteState`로 분리해 이후 Codex/Claude형 composer 개편 기반 마련 |
|
||||
| 런처 이미지 미리보기 추가 | `#` 클립보드 이미지 항목에서 `Shift+Enter`로 전용 미리보기 창을 열고, 줌·원본 해상도 확인·PNG/JPEG/BMP 저장·클립보드 복사를 지원 |
|
||||
| 검증 | `dotnet build` 경고 0 / 오류 0, `dotnet test` 436 passed / 0 failed |
|
||||
|
||||
@@ -3343,3 +3343,27 @@ else:
|
||||
### 3) 품질 게이트
|
||||
- dotnet build src/AxCopilot/AxCopilot.csproj 통과 (경고 0, 오류 0).
|
||||
- dotnet test src/AxCopilot.Tests/AxCopilot.Tests.csproj --no-build --filter "FullyQualifiedName~ChatWindowSlashPolicyTests|FullyQualifiedName~OperationModeReadinessTests" 통과 (43 passed, 0 failed).
|
||||
## 2026-04-04 추가 진행 기록 (연속 실행 28차: 탭별 설정 해석기 도입)
|
||||
|
||||
업데이트: 2026-04-04 13:32 (KST)
|
||||
|
||||
### 1) 탭별 설정 해석 단일화
|
||||
- 신규 파일 AgentTabSettingsResolver 추가.
|
||||
- ActiveTab 기준 공통 분기 제공:
|
||||
- IsCodeTab, IsCoworkTab
|
||||
- IsPostToolVerificationEnabled(activeTab, llm)
|
||||
- EnumerateCodeTabDisabledTools(codeSettings)
|
||||
|
||||
### 2) Agent loop 연동
|
||||
- AgentLoopService.MergeDisabledTools()에서 Code 탭 전용 도구 비활성 목록을 resolver로 계산하도록 전환.
|
||||
- AgentLoopTransitions.Execution의 post-tool verification 판단에서 resolver 결과를 사용하도록 정리.
|
||||
|
||||
### 3) 테스트 보강
|
||||
- AgentTabSettingsResolverTests 신규 추가:
|
||||
- 탭 판별
|
||||
- Cowork/Code 검증 플래그 분기
|
||||
- Code 전용 비활성 도구 목록 계산
|
||||
|
||||
### 4) 품질 게이트
|
||||
- dotnet build src/AxCopilot/AxCopilot.csproj -p:UseSharedCompilation=false -nodeReuse:false 통과 (경고 0, 오류 0).
|
||||
- dotnet test src/AxCopilot.Tests/AxCopilot.Tests.csproj --filter "FullyQualifiedName~AgentTabSettingsResolverTests|FullyQualifiedName~ChatWindowSlashPolicyTests|FullyQualifiedName~OperationModeReadinessTests" 통과 (49 passed, 0 failed).
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
using AxCopilot.Models;
|
||||
using AxCopilot.Services.Agent;
|
||||
using FluentAssertions;
|
||||
using Xunit;
|
||||
|
||||
namespace AxCopilot.Tests.Services;
|
||||
|
||||
public class AgentTabSettingsResolverTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData("Code", true, false)]
|
||||
[InlineData("Cowork", false, true)]
|
||||
[InlineData("Chat", false, false)]
|
||||
[InlineData(null, false, false)]
|
||||
public void TabDetection_ShouldMatchExpected(string? tab, bool isCode, bool isCowork)
|
||||
{
|
||||
AgentTabSettingsResolver.IsCodeTab(tab).Should().Be(isCode);
|
||||
AgentTabSettingsResolver.IsCoworkTab(tab).Should().Be(isCowork);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IsPostToolVerificationEnabled_ShouldUseTabSpecificFlags()
|
||||
{
|
||||
var llm = new LlmSettings
|
||||
{
|
||||
EnableCoworkVerification = true,
|
||||
Code = new CodeSettings
|
||||
{
|
||||
EnableCodeVerification = false,
|
||||
}
|
||||
};
|
||||
|
||||
AgentTabSettingsResolver.IsPostToolVerificationEnabled("Cowork", llm).Should().BeTrue();
|
||||
AgentTabSettingsResolver.IsPostToolVerificationEnabled("Code", llm).Should().BeFalse();
|
||||
AgentTabSettingsResolver.IsPostToolVerificationEnabled("Chat", llm).Should().BeFalse();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EnumerateCodeTabDisabledTools_ShouldReflectCodeSettings()
|
||||
{
|
||||
var code = new CodeSettings
|
||||
{
|
||||
EnablePlanModeTools = false,
|
||||
EnableWorktreeTools = true,
|
||||
EnableTeamTools = false,
|
||||
EnableCronTools = false,
|
||||
};
|
||||
|
||||
var disabled = AgentTabSettingsResolver.EnumerateCodeTabDisabledTools(code).ToList();
|
||||
|
||||
disabled.Should().Contain(["enter_plan_mode", "exit_plan_mode"]);
|
||||
disabled.Should().Contain(["team_create", "team_delete"]);
|
||||
disabled.Should().Contain(["cron_create", "cron_delete", "cron_list"]);
|
||||
disabled.Should().NotContain(["enter_worktree", "exit_worktree"]);
|
||||
}
|
||||
}
|
||||
@@ -1589,33 +1589,13 @@ public partial class AgentLoopService
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.Equals(ActiveTab, "Code", StringComparison.OrdinalIgnoreCase))
|
||||
if (!AgentTabSettingsResolver.IsCodeTab(ActiveTab))
|
||||
return disabled;
|
||||
|
||||
var code = _settings.Settings.Llm.Code;
|
||||
if (!code.EnablePlanModeTools)
|
||||
foreach (var toolName in AgentTabSettingsResolver.EnumerateCodeTabDisabledTools(code))
|
||||
{
|
||||
disabled.Add("enter_plan_mode");
|
||||
disabled.Add("exit_plan_mode");
|
||||
}
|
||||
|
||||
if (!code.EnableWorktreeTools)
|
||||
{
|
||||
disabled.Add("enter_worktree");
|
||||
disabled.Add("exit_worktree");
|
||||
}
|
||||
|
||||
if (!code.EnableTeamTools)
|
||||
{
|
||||
disabled.Add("team_create");
|
||||
disabled.Add("team_delete");
|
||||
}
|
||||
|
||||
if (!code.EnableCronTools)
|
||||
{
|
||||
disabled.Add("cron_create");
|
||||
disabled.Add("cron_delete");
|
||||
disabled.Add("cron_list");
|
||||
disabled.Add(toolName);
|
||||
}
|
||||
|
||||
return disabled;
|
||||
|
||||
@@ -1399,12 +1399,13 @@ public partial class AgentLoopService
|
||||
if (!result.Success || !IsTerminalDocumentTool(call.ToolName) || toolCalls.Count != 1)
|
||||
return (false, false);
|
||||
|
||||
var verificationEnabled = AgentTabSettingsResolver.IsPostToolVerificationEnabled(ActiveTab, llm);
|
||||
var shouldVerify = ShouldRunPostToolVerification(
|
||||
ActiveTab,
|
||||
call.ToolName,
|
||||
result.Success,
|
||||
llm.Code.EnableCodeVerification,
|
||||
llm.EnableCoworkVerification);
|
||||
verificationEnabled,
|
||||
verificationEnabled);
|
||||
var consumedExtraIteration = false;
|
||||
if (shouldVerify)
|
||||
{
|
||||
@@ -1427,12 +1428,13 @@ public partial class AgentLoopService
|
||||
if (!result.Success)
|
||||
return false;
|
||||
|
||||
var verificationEnabled = AgentTabSettingsResolver.IsPostToolVerificationEnabled(ActiveTab, llm);
|
||||
var shouldVerify = ShouldRunPostToolVerification(
|
||||
ActiveTab,
|
||||
call.ToolName,
|
||||
result.Success,
|
||||
llm.Code.EnableCodeVerification,
|
||||
llm.EnableCoworkVerification);
|
||||
verificationEnabled,
|
||||
verificationEnabled);
|
||||
if (!shouldVerify)
|
||||
return false;
|
||||
|
||||
|
||||
49
src/AxCopilot/Services/Agent/AgentTabSettingsResolver.cs
Normal file
49
src/AxCopilot/Services/Agent/AgentTabSettingsResolver.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
using AxCopilot.Models;
|
||||
|
||||
namespace AxCopilot.Services.Agent;
|
||||
|
||||
internal static class AgentTabSettingsResolver
|
||||
{
|
||||
public static bool IsCodeTab(string? activeTab)
|
||||
=> string.Equals(activeTab, "Code", StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
public static bool IsCoworkTab(string? activeTab)
|
||||
=> string.Equals(activeTab, "Cowork", StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
public static bool IsPostToolVerificationEnabled(string? activeTab, LlmSettings llm)
|
||||
{
|
||||
if (IsCodeTab(activeTab))
|
||||
return llm.Code.EnableCodeVerification;
|
||||
if (IsCoworkTab(activeTab))
|
||||
return llm.EnableCoworkVerification;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static IEnumerable<string> EnumerateCodeTabDisabledTools(CodeSettings code)
|
||||
{
|
||||
if (!code.EnablePlanModeTools)
|
||||
{
|
||||
yield return "enter_plan_mode";
|
||||
yield return "exit_plan_mode";
|
||||
}
|
||||
|
||||
if (!code.EnableWorktreeTools)
|
||||
{
|
||||
yield return "enter_worktree";
|
||||
yield return "exit_worktree";
|
||||
}
|
||||
|
||||
if (!code.EnableTeamTools)
|
||||
{
|
||||
yield return "team_create";
|
||||
yield return "team_delete";
|
||||
}
|
||||
|
||||
if (!code.EnableCronTools)
|
||||
{
|
||||
yield return "cron_create";
|
||||
yield return "cron_delete";
|
||||
yield return "cron_list";
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user