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; } = ""; }