using System.Text.Json.Serialization;
namespace AxCopilot.Models;
/// 대화 주제 카테고리.
public static class ChatCategory
{
public const string General = "일반";
public const string Management = "경영";
public const string HR = "인사";
public const string Finance = "재무";
public const string RnD = "연구개발";
public const string Product = "제품분석";
public const string Yield = "수율분석";
public const string MfgTech = "제조기술";
public const string System = "시스템";
public static readonly (string Key, string Label, string Symbol, string Color)[] All =
{
(General, "일반", "\uE8BD", "#6B7280"), // Chat – gray
(Management, "경영", "\uE902", "#8B5CF6"), // Briefcase – purple
(HR, "인사", "\uE716", "#0EA5E9"), // People – sky blue
(Finance, "재무", "\uE8C7", "#D97706"), // Money – amber/orange
(RnD, "연구개발", "\uE9A8", "#3B82F6"), // Research – blue
(Product, "제품분석", "\uE9D9", "#EC4899"), // Design – pink
(Yield, "수율분석", "\uE9F9", "#F59E0B"), // Analytics – amber
(MfgTech, "제조기술", "\uE90F", "#10B981"), // Manufacturing – emerald
(System, "시스템", "\uE770", "#EF4444"), // IT System – red
};
public static string GetSymbol(string? category)
{
if (string.IsNullOrEmpty(category)) return "\uE8BD";
foreach (var (key, _, symbol, _) in All)
if (key == category) return symbol;
return "\uE8BD";
}
public static string GetColor(string? category)
{
if (string.IsNullOrEmpty(category)) return "#6B7280";
foreach (var (key, _, _, color) in All)
if (key == category) return color;
return "#6B7280";
}
}
/// 하나의 대화(세션). 복수의 메시지를 포함합니다.
public class ChatConversation
{
[JsonPropertyName("id")]
public string Id { get; set; } = Guid.NewGuid().ToString("N");
[JsonPropertyName("title")]
public string Title { get; set; } = "새 대화";
[JsonPropertyName("createdAt")]
public DateTime CreatedAt { get; set; } = DateTime.Now;
[JsonPropertyName("updatedAt")]
public DateTime UpdatedAt { get; set; } = DateTime.Now;
[JsonPropertyName("pinned")]
public bool Pinned { get; set; } = false;
/// 대화가 속한 탭. "Chat" | "Cowork" | "Code".
[JsonPropertyName("tab")]
public string Tab { get; set; } = "Chat";
/// 대화 주제. ChatCategory 상수 중 하나.
[JsonPropertyName("category")]
public string Category { get; set; } = ChatCategory.General;
/// 사용자가 보이지 않는 시스템 명령어 (대화별 커스텀 프롬프트).
[JsonPropertyName("systemCommand")]
public string SystemCommand { get; set; } = "";
/// 대화에 연결된 작업 폴더 경로.
[JsonPropertyName("workFolder")]
public string WorkFolder { get; set; } = "";
/// 첫 사용자 메시지 요약 (검색용, 최대 100자). 저장 시 자동 갱신.
[JsonPropertyName("preview")]
public string Preview { get; set; } = "";
/// 분기 원본 대화 ID. null이면 원본 대화.
[JsonPropertyName("parentId")]
public string? ParentId { get; set; }
/// 분기 라벨 (예: "대안 A", "접근법 2").
[JsonPropertyName("branchLabel")]
public string? BranchLabel { get; set; }
/// 분기 시점의 메시지 인덱스 (parentId의 Messages[index] 이후부터 분기).
[JsonPropertyName("branchAtIndex")]
public int? BranchAtIndex { get; set; }
// ─── 대화별 설정 (하단 바에서 변경, 대화마다 독립 저장) ───
/// 파일 접근 권한. null이면 전역 설정 사용. "Ask" | "Plan" | "Auto" | "Deny"
[JsonPropertyName("permission")]
public string? Permission { get; set; }
/// 데이터 활용 모드. null이면 전역 설정 사용. "active" | "passive" | "none"
[JsonPropertyName("dataUsage")]
public string? DataUsage { get; set; }
/// 출력 포맷. null이면 전역 설정 사용.
[JsonPropertyName("outputFormat")]
public string? OutputFormat { get; set; }
/// 무드/디자인 템플릿. null이면 전역 설정 사용.
[JsonPropertyName("mood")]
public string? Mood { get; set; }
[JsonPropertyName("messages")]
public List Messages { get; set; } = new();
[JsonPropertyName("executionEvents")]
public List ExecutionEvents { get; set; } = new();
[JsonPropertyName("draftQueue")]
public List DraftQueue { get; set; } = new();
[JsonPropertyName("draftQueueItems")]
public List DraftQueueItems { get; set; } = new();
[JsonPropertyName("showExecutionHistory")]
public bool ShowExecutionHistory { get; set; } = true;
[JsonPropertyName("agentRunHistory")]
public List AgentRunHistory { get; set; } = new();
[JsonPropertyName("conversationFailedOnlyFilter")]
public bool ConversationFailedOnlyFilter { get; set; }
[JsonPropertyName("conversationRunningOnlyFilter")]
public bool ConversationRunningOnlyFilter { get; set; }
[JsonPropertyName("conversationSortMode")]
public string ConversationSortMode { get; set; } = "activity";
[JsonPropertyName("compactionCount")]
public int CompactionCount { get; set; }
[JsonPropertyName("automaticCompactionCount")]
public int AutomaticCompactionCount { get; set; }
[JsonPropertyName("manualCompactionCount")]
public int ManualCompactionCount { get; set; }
[JsonPropertyName("compactionSavedTokens")]
public int CompactionSavedTokens { get; set; }
[JsonPropertyName("sessionMemoryCompactionCount")]
public int SessionMemoryCompactionCount { get; set; }
[JsonPropertyName("microcompactBoundaryCount")]
public int MicrocompactBoundaryCount { get; set; }
[JsonPropertyName("snipCompactionCount")]
public int SnipCompactionCount { get; set; }
[JsonPropertyName("lastCompactionAt")]
public DateTime? LastCompactionAt { get; set; }
[JsonPropertyName("lastCompactionWasAutomatic")]
public bool LastCompactionWasAutomatic { get; set; }
[JsonPropertyName("lastCompactionBeforeTokens")]
public int? LastCompactionBeforeTokens { get; set; }
[JsonPropertyName("lastCompactionAfterTokens")]
public int? LastCompactionAfterTokens { get; set; }
[JsonPropertyName("lastCompactionStageSummary")]
public string? LastCompactionStageSummary { get; set; }
[JsonPropertyName("pendingPostCompaction")]
public bool PendingPostCompaction { get; set; }
[JsonPropertyName("postCompactionResponseCount")]
public int PostCompactionResponseCount { get; set; }
[JsonPropertyName("postCompactionPromptTokens")]
public int PostCompactionPromptTokens { get; set; }
[JsonPropertyName("postCompactionCompletionTokens")]
public int PostCompactionCompletionTokens { get; set; }
}
public class ChatAgentRunRecord
{
[JsonPropertyName("runId")]
public string RunId { get; set; } = "";
[JsonPropertyName("status")]
public string Status { get; set; } = "completed";
[JsonPropertyName("summary")]
public string Summary { get; set; } = "";
[JsonPropertyName("lastIteration")]
public int LastIteration { get; set; }
[JsonPropertyName("startedAt")]
public DateTime StartedAt { get; set; } = DateTime.Now;
[JsonPropertyName("updatedAt")]
public DateTime UpdatedAt { get; set; } = DateTime.Now;
}
public class DraftQueueItem
{
[JsonPropertyName("id")]
public string Id { get; set; } = Guid.NewGuid().ToString("N");
[JsonPropertyName("text")]
public string Text { get; set; } = "";
[JsonPropertyName("priority")]
public string Priority { get; set; } = "next";
[JsonPropertyName("kind")]
public string Kind { get; set; } = "message";
[JsonPropertyName("state")]
public string State { get; set; } = "queued";
[JsonPropertyName("attemptCount")]
public int AttemptCount { get; set; }
[JsonPropertyName("lastError")]
public string? LastError { get; set; }
[JsonPropertyName("nextRetryAt")]
public DateTime? NextRetryAt { get; set; }
[JsonPropertyName("createdAt")]
public DateTime CreatedAt { get; set; } = DateTime.Now;
}
/// 대화 내 개별 메시지.
public class ChatMessage
{
[JsonPropertyName("role")]
public string Role { get; set; } = "user"; // "user" | "assistant" | "system"
[JsonPropertyName("content")]
public string Content { get; set; } = "";
[JsonPropertyName("timestamp")]
public DateTime Timestamp { get; set; } = DateTime.Now;
[JsonPropertyName("metaKind")]
public string? MetaKind { get; set; }
[JsonPropertyName("metaRunId")]
public string? MetaRunId { get; set; }
/// 피드백 상태. null=없음, "like", "dislike"
[JsonPropertyName("feedback")]
public string? Feedback { get; set; }
/// 첨부된 파일 경로 목록.
[JsonPropertyName("attachedFiles")]
public List? AttachedFiles { get; set; }
/// 첨부된 이미지 목록. base64 인코딩된 이미지 데이터.
[JsonPropertyName("images")]
public List? Images { get; set; }
}
public class ChatExecutionEvent
{
[JsonPropertyName("timestamp")]
public DateTime Timestamp { get; set; } = DateTime.Now;
[JsonPropertyName("runId")]
public string RunId { get; set; } = "";
[JsonPropertyName("type")]
public string Type { get; set; } = "Thinking";
[JsonPropertyName("toolName")]
public string ToolName { get; set; } = "";
[JsonPropertyName("summary")]
public string Summary { get; set; } = "";
[JsonPropertyName("filePath")]
public string? FilePath { get; set; }
[JsonPropertyName("success")]
public bool Success { get; set; } = true;
[JsonPropertyName("stepCurrent")]
public int StepCurrent { get; set; }
[JsonPropertyName("stepTotal")]
public int StepTotal { get; set; }
[JsonPropertyName("steps")]
public List? Steps { get; set; }
[JsonPropertyName("elapsedMs")]
public long ElapsedMs { get; set; }
[JsonPropertyName("inputTokens")]
public int InputTokens { get; set; }
[JsonPropertyName("outputTokens")]
public int OutputTokens { get; set; }
[JsonPropertyName("toolInput")]
public string? ToolInput { get; set; }
[JsonPropertyName("iteration")]
public int Iteration { get; set; }
}
/// 이미지 첨부 데이터. LLM Vision API에 전달되는 base64 인코딩 이미지.
public class ImageAttachment
{
/// base64 인코딩된 이미지 데이터.
[JsonPropertyName("base64")]
public string Base64 { get; set; } = "";
/// MIME 타입. image/png, image/jpeg 등.
[JsonPropertyName("mimeType")]
public string MimeType { get; set; } = "image/png";
/// 원본 파일명 또는 설명.
[JsonPropertyName("fileName")]
public string FileName { get; set; } = "";
}