Parcourir la source

feat: persist chat de-ai skill selection

Mochocyang il y a 3 mois
Parent
commit
50509f4b78
2 fichiers modifiés avec 29 ajouts et 2 suppressions
  1. 19 2
      src/lib/persist.ts
  2. 10 0
      src/stores/chat-store.ts

+ 19 - 2
src/lib/persist.ts

@@ -103,6 +103,17 @@ interface PersistedChatData {
   messages: DisplayMessage[]
 }
 
+function normalizeConversation(conv: Conversation): Conversation {
+  return {
+    ...conv,
+    deAiMode: Boolean(conv.deAiMode),
+    selectedDeAiSkillId:
+      conv.selectedDeAiSkillId === null || typeof conv.selectedDeAiSkillId === "string"
+        ? conv.selectedDeAiSkillId
+        : undefined,
+  }
+}
+
 export async function saveChatHistory(
   projectPath: string,
   conversations: Conversation[],
@@ -153,7 +164,7 @@ export async function loadChatHistory(projectPath: string): Promise<PersistedCha
   try {
     // Try new format: separate files per conversation
     const convContent = await readFile(`${pp}/.qmai/conversations.json`)
-    const conversations = safeParseArray<Conversation>(convContent, "conversations")
+    const conversations = safeParseArray<Conversation>(convContent, "conversations").map(normalizeConversation)
 
     const allMessages: DisplayMessage[] = []
     for (const conv of conversations) {
@@ -182,6 +193,7 @@ export async function loadChatHistory(projectPath: string): Promise<PersistedCha
           createdAt: legacyMessages[0]?.timestamp ?? Date.now(),
           updatedAt: legacyMessages[legacyMessages.length - 1]?.timestamp ?? Date.now(),
           deAiMode: false,
+          selectedDeAiSkillId: undefined,
         }
         const migratedMessages = legacyMessages.map((m) => ({
           ...m,
@@ -193,7 +205,12 @@ export async function loadChatHistory(projectPath: string): Promise<PersistedCha
       // Old combined format
       if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
         const data = parsed as PersistedChatData
-        return data
+        return {
+          conversations: Array.isArray(data.conversations)
+            ? data.conversations.map(normalizeConversation)
+            : [],
+          messages: Array.isArray(data.messages) ? data.messages : [],
+        }
       }
       console.warn("persist: 聊天历史数据格式无效")
       return { conversations: [], messages: [] }

+ 10 - 0
src/stores/chat-store.ts

@@ -8,6 +8,7 @@ export interface Conversation {
   createdAt: number
   updatedAt: number
   deAiMode: boolean
+  selectedDeAiSkillId?: string | null
   inputDraft?: string
 }
 
@@ -42,6 +43,7 @@ interface ChatState {
   setActiveConversation: (id: string | null) => void
   renameConversation: (id: string, title: string) => void
   setConversationDeAiMode: (id: string, deAiMode: boolean) => void
+  setConversationDeAiSkillId: (id: string, skillId: string | null | undefined) => void
   setConversationInputDraft: (id: string, draft: string) => void
 
   // Message management
@@ -102,6 +104,7 @@ export const useChatStore = create<ChatState>((set, get) => ({
       createdAt: now,
       updatedAt: now,
       deAiMode: false,
+      selectedDeAiSkillId: undefined,
       inputDraft: "",
     }
     set((state) => ({
@@ -144,6 +147,13 @@ export const useChatStore = create<ChatState>((set, get) => ({
       ),
     })),
 
+  setConversationDeAiSkillId: (id, selectedDeAiSkillId) =>
+    set((state) => ({
+      conversations: state.conversations.map((c) =>
+        c.id === id ? { ...c, selectedDeAiSkillId, updatedAt: Date.now() } : c
+      ),
+    })),
+
   setConversationInputDraft: (id, draft) =>
     set((state) => ({
       conversations: state.conversations.map((c) =>