메모리 include 감사 로그와 AX Agent 메모리 상태 UX 강화

- AgentMemoryService에 @include 성공/차단 감사 로그(MemoryInclude) 기록 추가
- Cowork/Code 하단 폴더 바에 메모리 규칙/학습 메모리 상태 요약 표시 추가
- 설정의 외부 메모리 include 안내 문구를 감사 로그 기준으로 정리
- dotnet build 검증 완료 (경고 0 / 오류 0)
This commit is contained in:
2026-04-07 00:46:56 +09:00
parent aef5f51c89
commit 594bb6ffe6
6 changed files with 154 additions and 16 deletions

View File

@@ -76,6 +76,7 @@ public partial class ChatWindow
LoadCompactionMetricsFromConversation();
UpdatePermissionUI();
UpdateDataUsageUI();
UpdateMemoryStatusUi();
RefreshContextUsageVisual();
ScheduleGitBranchRefresh();
UpdateGitBranchUi(_currentGitBranchName, GitBranchFilesText?.Text ?? "", GitBranchAddedText?.Text ?? "", GitBranchDeletedText?.Text ?? "", _currentGitTooltip ?? "", BtnGitBranch?.Visibility ?? Visibility.Collapsed);
@@ -86,6 +87,61 @@ public partial class ChatWindow
_folderDataUsage = GetAutomaticFolderDataUsage();
}
private void UpdateMemoryStatusUi()
{
if (BtnMemoryStatus == null || MemoryStatusLabel == null)
return;
if (_activeTab == "Chat")
{
BtnMemoryStatus.Visibility = Visibility.Collapsed;
MemoryStatusSeparator.Visibility = Visibility.Collapsed;
return;
}
var app = System.Windows.Application.Current as App;
var memory = app?.MemoryService;
if (memory == null || !_settings.Settings.Llm.EnableAgentMemory)
{
MemoryStatusLabel.Text = "메모리 꺼짐";
BtnMemoryStatus.ToolTip = "에이전트 메모리가 비활성화되어 있습니다.";
BtnMemoryStatus.Visibility = Visibility.Visible;
MemoryStatusSeparator.Visibility = Visibility.Visible;
return;
}
var workFolder = GetCurrentWorkFolder();
memory.Load(workFolder);
var docs = memory.InstructionDocuments;
var learned = memory.All.Count;
MemoryStatusLabel.Text = docs.Count > 0 || learned > 0
? $"메모리 {docs.Count} · 학습 {learned}"
: "메모리 없음";
var lines = docs
.Take(4)
.Select(doc =>
{
var priority = doc.Priority > 0 ? $"우선순위 {doc.Priority}" : "우선순위 미정";
var description = string.IsNullOrWhiteSpace(doc.Description) ? "" : $" · {doc.Description}";
return $"[{doc.Label}] {priority}{description}";
})
.ToList();
if (docs.Count > lines.Count)
lines.Add($"외 {docs.Count - lines.Count}개 규칙");
var includePolicy = _settings.Settings.Llm.AllowExternalMemoryIncludes
? "외부 include 허용"
: "외부 include 차단";
BtnMemoryStatus.ToolTip = lines.Count == 0
? $"계층형 규칙이 없습니다.\n학습 메모리 {learned}개\n{includePolicy}"
: $"계층형 규칙 {docs.Count}개 · 학습 메모리 {learned}개\n{string.Join("\n", lines)}\n{includePolicy}";
BtnMemoryStatus.Visibility = Visibility.Visible;
MemoryStatusSeparator.Visibility = Visibility.Visible;
}
private void UpdateSelectedPresetGuide(ChatConversation? conversation = null)
{
if (SelectedPresetGuide == null || SelectedPresetGuideTitle == null || SelectedPresetGuideDesc == null)

View File

@@ -2379,9 +2379,11 @@
<ColumnDefinition Width="Auto"/> <!-- 4: 구분선 -->
<ColumnDefinition Width="Auto"/> <!-- 5: 데이터 활용 -->
<ColumnDefinition Width="Auto"/> <!-- 6: 구분선 -->
<ColumnDefinition Width="Auto"/> <!-- 7: 권한 -->
<ColumnDefinition Width="Auto"/> <!-- 7: 메모리 -->
<ColumnDefinition Width="Auto"/> <!-- 8: 구분선 -->
<ColumnDefinition Width="Auto"/> <!-- 9: git -->
<ColumnDefinition Width="Auto"/> <!-- 9: 권한 -->
<ColumnDefinition Width="Auto"/> <!-- 10: 구분선 -->
<ColumnDefinition Width="Auto"/> <!-- 11: git -->
</Grid.ColumnDefinitions>
<!-- 폴더 아이콘 -->
@@ -2412,8 +2414,27 @@
<!-- 폴더 데이터 활용은 코드/코워크 자동 정책으로만 동작 -->
<Border x:Name="MemoryStatusSeparator" Grid.Column="8" Width="1" Height="18" Margin="4,0"
Visibility="Collapsed"
Background="{DynamicResource SeparatorColor}"/>
<Button x:Name="BtnMemoryStatus" Grid.Column="7" Style="{StaticResource FooterChipBtn}"
Padding="10,5"
Visibility="Collapsed"
BorderThickness="0"
ToolTip="현재 적용된 메모리 상태">
<StackPanel Orientation="Horizontal">
<TextBlock Text="&#xE943;" FontFamily="Segoe MDL2 Assets" FontSize="12"
Foreground="{DynamicResource SecondaryText}"
VerticalAlignment="Center" Margin="0,0,4,0"/>
<TextBlock x:Name="MemoryStatusLabel" Text="메모리 없음" FontSize="12"
Foreground="{DynamicResource SecondaryText}"
VerticalAlignment="Center"/>
</StackPanel>
</Button>
<!-- 권한 메뉴 -->
<Button x:Name="BtnPermission" Grid.Column="7" Style="{StaticResource FooterChipBtn}"
<Button x:Name="BtnPermission" Grid.Column="9" Style="{StaticResource FooterChipBtn}"
Padding="10,5" Click="BtnPermission_Click" ToolTip="파일 접근 권한"
BorderThickness="0">
<StackPanel Orientation="Horizontal">
@@ -2426,12 +2447,12 @@
</StackPanel>
</Button>
<Border x:Name="GitBranchSeparator" Grid.Column="8" Width="1" Height="18" Margin="4,0"
<Border x:Name="GitBranchSeparator" Grid.Column="10" Width="1" Height="18" Margin="4,0"
Visibility="Collapsed"
Background="{DynamicResource SeparatorColor}"/>
<Button x:Name="BtnGitBranch"
Grid.Column="9"
Grid.Column="11"
Style="{StaticResource FooterChipBtn}"
Padding="10,5"
Margin="2,0,0,0"

View File

@@ -4940,7 +4940,7 @@
<Grid>
<StackPanel HorizontalAlignment="Left" Margin="0,0,60,0">
<TextBlock Style="{StaticResource RowLabel}" Text="외부 메모리 include 허용"/>
<TextBlock Style="{StaticResource RowHint}" Text="AXMEMORY.md의 @include가 프로젝트 바깥 파일을 읽는 것을 허용합니다. 기본은 안전하게 꺼져 있니다."/>
<TextBlock Style="{StaticResource RowHint}" Text="AXMEMORY.md의 @include가 프로젝트 바깥 파일을 읽는 것을 허용합니다. 기본은 안전하게 꺼져 있으며, include 시도는 감사 로그에 기록됩니다."/>
</StackPanel>
<CheckBox Style="{StaticResource ToggleSwitch}" HorizontalAlignment="Right" VerticalAlignment="Center"
IsChecked="{Binding AllowExternalMemoryIncludes, Mode=TwoWay}"/>