AX Agent loop 정책을 분리하고 transcript 가상화·성능 계측 구조를 강화한다
Some checks failed
Release Gate / gate (push) Has been cancelled
Some checks failed
Release Gate / gate (push) Has been cancelled
- AgentLoop 검증/문서/compact 정책 메서드를 partial 파일로 분리해 loop 본문의 책임을 줄임 - transcript 렌더에 cache pruning과 deferred scrolling을 적용해 긴 세션의 UI 부담을 낮춤 - AgentPerformanceLogService를 추가해 transcript 렌더와 agent loop 실행 요약을 perf 로그로 남김 - README와 DEVELOPMENT 문서에 2026-04-09 10:08 (KST) 기준 구조 개선 및 계측 이력을 반영함 - dotnet build src/AxCopilot/AxCopilot.csproj -c Release -v minimal -p:OutputPath=bin\\verify\\ -p:IntermediateOutputPath=obj\\verify\\ 검증 결과 경고 0개 오류 0개
This commit is contained in:
72
src/AxCopilot/Services/AgentPerformanceLogService.cs
Normal file
72
src/AxCopilot/Services/AgentPerformanceLogService.cs
Normal file
@@ -0,0 +1,72 @@
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.IO;
|
||||
|
||||
namespace AxCopilot.Services;
|
||||
|
||||
public static class AgentPerformanceLogService
|
||||
{
|
||||
private static readonly string PerfDir;
|
||||
private static readonly object _lock = new();
|
||||
private static readonly JsonSerializerOptions _jsonOptions = new()
|
||||
{
|
||||
WriteIndented = false,
|
||||
Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
|
||||
};
|
||||
|
||||
static AgentPerformanceLogService()
|
||||
{
|
||||
PerfDir = Path.Combine(
|
||||
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
|
||||
"AxCopilot",
|
||||
"perf");
|
||||
try { Directory.CreateDirectory(PerfDir); } catch { }
|
||||
}
|
||||
|
||||
public static void LogMetric(
|
||||
string area,
|
||||
string name,
|
||||
string conversationId,
|
||||
string tab,
|
||||
long durationMs,
|
||||
object? detail = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var fileName = $"performance-{DateTime.Now:yyyy-MM-dd}.json";
|
||||
var filePath = Path.Combine(PerfDir, fileName);
|
||||
var json = JsonSerializer.Serialize(new AgentPerformanceEntry
|
||||
{
|
||||
Timestamp = DateTime.Now,
|
||||
Area = area,
|
||||
Name = name,
|
||||
ConversationId = conversationId ?? "",
|
||||
Tab = tab ?? "",
|
||||
DurationMs = durationMs,
|
||||
Detail = detail == null ? "" : JsonSerializer.Serialize(detail, _jsonOptions),
|
||||
}, _jsonOptions);
|
||||
|
||||
lock (_lock)
|
||||
{
|
||||
File.AppendAllText(filePath, json + Environment.NewLine, Encoding.UTF8);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 성능 로그 실패는 런타임에 영향 주지 않음
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetPerformanceFolder() => PerfDir;
|
||||
}
|
||||
|
||||
public sealed class AgentPerformanceEntry
|
||||
{
|
||||
public DateTime Timestamp { get; init; }
|
||||
public string Area { get; init; } = "";
|
||||
public string Name { get; init; } = "";
|
||||
public string ConversationId { get; init; } = "";
|
||||
public string Tab { get; init; } = "";
|
||||
public long DurationMs { get; init; }
|
||||
public string Detail { get; init; } = "";
|
||||
}
|
||||
Reference in New Issue
Block a user