AX Agent 코워크·코드 흐름과 컨텍스트 관리를 claude-code 기준으로 대폭 정리

- 코워크·코드 프롬프트, 도구 선택, 문서 생성/검증 흐름을 claude-code 동등 품질 기준으로 재정렬함

- OpenAI/vLLM 경로의 오래된 tool history를 평탄화하고 최근 이력만 구조화해 컨텍스트 직렬화를 경량화함

- AX Agent UI를 테마 기준으로 재구성하고 플랜 승인/오버레이/이벤트 렌더링/명령 입력 상호작용을 개선함

- 파일 후보 제안, 반복 경로 정체 복구, LSP 보강, 문서·PPT 처리 개선, 설정/서비스 인터페이스 정리를 함께 반영함

- README.md 및 docs/DEVELOPMENT.md를 작업 시점별로 갱신함

- 검증: 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:
2026-04-12 22:02:14 +09:00
parent b8f4df1892
commit fb0bea41f7
137 changed files with 18532 additions and 1144 deletions

View File

@@ -0,0 +1,25 @@
using AxCopilot.Models;
using AxCopilot.Services.Agent;
namespace AxCopilot.Services;
/// <summary>앱 전역 상태 요약 저장소 인터페이스.</summary>
public interface IAppStateService
{
ChatSessionStateService? ChatSession { get; }
void AttachChatSession(ChatSessionStateService session);
void LoadFromSettings(ISettingsService settings);
AppStateService.SkillCatalogState Skills { get; }
AppStateService.McpCatalogState Mcp { get; }
AppStateService.PermissionPolicyState Permissions { get; }
AppStateService.AgentCatalogState AgentCatalog { get; }
AppStateService.AgentRunState AgentRun { get; }
void UpsertTask(string id, string kind, string title, string summary, string status = "running", string? filePath = null);
void CompleteTask(string id, string? summary = null, string status = "completed");
void ApplyAgentEvent(AgentEvent evt);
AppStateService.BackgroundJobSummaryState GetBackgroundJobSummary();
AppStateService.PermissionSummaryState GetPermissionSummary(ChatConversation? conversation = null);
}

View File

@@ -0,0 +1,19 @@
using AxCopilot.Models;
namespace AxCopilot.Services;
/// <summary>대화 내역 저장/로드/삭제 인터페이스.</summary>
public interface IChatStorageService
{
void Save(ChatConversation conversation);
ChatConversation? Load(string id);
List<ChatConversation> LoadAllMeta();
void InvalidateMetaCache();
void UpdateMetaCache(ChatConversation conv);
void RemoveFromMetaCache(string id);
void Delete(string id);
int DeleteAll();
int DeleteAllByTab(string tab);
int PurgeExpired(int retentionDays);
int PurgeForDiskSpace(double threshold = 0.98);
}

View File

@@ -0,0 +1,75 @@
using System.Text.Json;
using AxCopilot.Models;
using AxCopilot.Services.Agent;
namespace AxCopilot.Services;
/// <summary>런타임 연결 정보 스냅샷.</summary>
public record RuntimeConnectionSnapshot(
string Service,
string Model,
string Endpoint,
bool AllowInsecureTls,
bool HasApiKey);
/// <summary>LLM API 호출 인터페이스. 스트리밍/비스트리밍 모두 지원.</summary>
public interface ILlmService : IDisposable
{
/// <summary>현재 서비스/모델 정보 조회.</summary>
(string service, string model) GetCurrentModelInfo();
/// <summary>비스트리밍 전체 응답 요청.</summary>
Task<string> SendAsync(List<ChatMessage> messages, CancellationToken ct = default);
/// <summary>스트리밍 응답 요청 (SSE).</summary>
IAsyncEnumerable<string> StreamAsync(
List<ChatMessage> messages,
CancellationToken ct = default);
/// <summary>연결 테스트.</summary>
Task<(bool ok, string message)> TestConnectionAsync();
/// <summary>자동 라우팅용 서비스/모델 오버라이드 설정.</summary>
void PushRouteOverride(string service, string model);
/// <summary>서비스/모델 오버라이드 해제.</summary>
void ClearRouteOverride();
/// <summary>모델/추론 파라미터 오버라이드 Push.</summary>
void PushInferenceOverride(
string? service = null,
string? model = null,
double? temperature = null,
string? reasoningEffort = null);
/// <summary>가장 최근 Push 상태 복원.</summary>
void PopInferenceOverride();
/// <summary>가장 최근 요청의 토큰 사용량.</summary>
TokenUsage? LastTokenUsage { get; }
/// <summary>런타임 연결 정보 스냅샷 조회.</summary>
RuntimeConnectionSnapshot GetRuntimeConnectionSnapshot();
/// <summary>도구 정의를 포함하여 LLM에 요청하고, 텍스트 + tool_use 블록을 파싱하여 반환합니다.</summary>
Task<List<ContentBlock>> SendWithToolsAsync(
List<ChatMessage> messages,
IReadOnlyCollection<IAgentTool> tools,
CancellationToken ct = default,
bool forceToolCall = false,
Func<ContentBlock, Task<ToolPrefetchResult?>>? prefetchToolCallAsync = null);
/// <summary>도구 정의를 포함하여 스트리밍 요청.</summary>
IAsyncEnumerable<ToolStreamEvent> StreamWithToolsAsync(
List<ChatMessage> messages,
IReadOnlyCollection<IAgentTool> tools,
bool forceToolCall = false,
Func<ContentBlock, Task<ToolPrefetchResult?>>? prefetchToolCallAsync = null,
CancellationToken ct = default);
/// <summary>현재 활성 실행 정책 조회.</summary>
ModelExecutionProfileCatalog.ExecutionPolicy GetActiveExecutionPolicy();
/// <summary>현재 시스템 프롬프트 (컨텍스트 토큰 추정에 사용).</summary>
string? SystemPrompt { get; }
}

View File

@@ -0,0 +1,9 @@
namespace AxCopilot.Services;
/// <summary>사용자 메시지의 인텐트를 분석하여 최적 모델을 선택하는 라우터 인터페이스.</summary>
public interface IModelRouterService
{
/// <summary>사용자 메시지를 분석하여 최적 모델을 선택합니다.</summary>
/// <returns>라우팅 결과. null이면 기본 모델 유지.</returns>
ModelRouteResult? Route(string userMessage);
}

View File

@@ -0,0 +1,15 @@
using AxCopilot.Models;
namespace AxCopilot.Services;
/// <summary>애플리케이션 설정 읽기/쓰기 인터페이스.</summary>
public interface ISettingsService
{
AppSettings Settings { get; }
string? MigrationSummary { get; }
event EventHandler? SettingsChanged;
void Load();
void Save();
Task SaveAsync();
}