fix: persist claw chat sessions
This commit is contained in:
parent
16f23b3f7c
commit
f692425607
@ -2432,6 +2432,33 @@ export function CanvasChatPanel({
|
|||||||
);
|
);
|
||||||
}, [getSendGuard]);
|
}, [getSendGuard]);
|
||||||
|
|
||||||
|
const persistChatSessions = useCallback(
|
||||||
|
(sessions: CanvasChatSession[]) => {
|
||||||
|
const sessionStorageKey = getSessionStorageKey(canvasId, chatScope);
|
||||||
|
try {
|
||||||
|
localStorage.setItem(sessionStorageKey, JSON.stringify(sessions));
|
||||||
|
setLoadedChatSessionStorageKey(sessionStorageKey);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("[CanvasChat] Failed to save chat sessions:", error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[canvasId, chatScope]
|
||||||
|
);
|
||||||
|
|
||||||
|
const updateChatSessions = useCallback(
|
||||||
|
(updater: (previousSessions: CanvasChatSession[]) => CanvasChatSession[]) => {
|
||||||
|
setChatSessions((previousSessions) => {
|
||||||
|
const nextSessions = updater(previousSessions);
|
||||||
|
if (nextSessions === previousSessions) {
|
||||||
|
return previousSessions;
|
||||||
|
}
|
||||||
|
persistChatSessions(nextSessions);
|
||||||
|
return nextSessions;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
[persistChatSessions]
|
||||||
|
);
|
||||||
|
|
||||||
const startNewChatSession = useCallback(
|
const startNewChatSession = useCallback(
|
||||||
(options?: {
|
(options?: {
|
||||||
mode?: CanvasComposerMode;
|
mode?: CanvasComposerMode;
|
||||||
@ -2462,13 +2489,19 @@ export function CanvasChatPanel({
|
|||||||
|
|
||||||
forceHistoryHydrationRef.current = null;
|
forceHistoryHydrationRef.current = null;
|
||||||
releaseSendGuard(activeChatId);
|
releaseSendGuard(activeChatId);
|
||||||
setChatSessions((prevSessions) => [newSession, ...prevSessions]);
|
updateChatSessions((prevSessions) => [newSession, ...prevSessions]);
|
||||||
setActiveChatId(newChatSessionId);
|
setActiveChatId(newChatSessionId);
|
||||||
replaceChatSessionQuery(newChatSessionId);
|
replaceChatSessionQuery(newChatSessionId);
|
||||||
toast.success(options?.toastMessage || "已新建聊天窗口");
|
toast.success(options?.toastMessage || "已新建聊天窗口");
|
||||||
return newChatSessionId;
|
return newChatSessionId;
|
||||||
},
|
},
|
||||||
[activeChatId, chatSessions, releaseSendGuard, replaceChatSessionQuery]
|
[
|
||||||
|
activeChatId,
|
||||||
|
chatSessions,
|
||||||
|
releaseSendGuard,
|
||||||
|
replaceChatSessionQuery,
|
||||||
|
updateChatSessions,
|
||||||
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
const setSessionClawdSkillTag = useCallback(
|
const setSessionClawdSkillTag = useCallback(
|
||||||
@ -2479,11 +2512,12 @@ export function CanvasChatPanel({
|
|||||||
) => {
|
) => {
|
||||||
if (!chatSessionId) return;
|
if (!chatSessionId) return;
|
||||||
const normalizedTagId = String(tagId || "").trim() || null;
|
const normalizedTagId = String(tagId || "").trim() || null;
|
||||||
setChatSessions((prevSessions) =>
|
updateChatSessions((prevSessions) =>
|
||||||
prevSessions.map((session) =>
|
prevSessions.map((session) =>
|
||||||
session.id === chatSessionId
|
session.id === chatSessionId
|
||||||
? {
|
? {
|
||||||
...session,
|
...session,
|
||||||
|
mode: "clawd",
|
||||||
clawdSkillTagId: normalizedTagId,
|
clawdSkillTagId: normalizedTagId,
|
||||||
clawdSkillTagPromptApplied:
|
clawdSkillTagPromptApplied:
|
||||||
normalizedTagId === null
|
normalizedTagId === null
|
||||||
@ -2495,17 +2529,18 @@ export function CanvasChatPanel({
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
[]
|
[updateChatSessions]
|
||||||
);
|
);
|
||||||
|
|
||||||
const markSessionClawdSkillTagPromptApplied = useCallback(
|
const markSessionClawdSkillTagPromptApplied = useCallback(
|
||||||
(chatSessionId: string, tagId: string) => {
|
(chatSessionId: string, tagId: string) => {
|
||||||
if (!chatSessionId || !tagId) return;
|
if (!chatSessionId || !tagId) return;
|
||||||
setChatSessions((prevSessions) =>
|
updateChatSessions((prevSessions) =>
|
||||||
prevSessions.map((session) =>
|
prevSessions.map((session) =>
|
||||||
session.id === chatSessionId && session.clawdSkillTagId === tagId
|
session.id === chatSessionId && session.clawdSkillTagId === tagId
|
||||||
? {
|
? {
|
||||||
...session,
|
...session,
|
||||||
|
mode: "clawd",
|
||||||
clawdSkillTagPromptApplied: true,
|
clawdSkillTagPromptApplied: true,
|
||||||
updatedAt: Date.now(),
|
updatedAt: Date.now(),
|
||||||
}
|
}
|
||||||
@ -2513,7 +2548,7 @@ export function CanvasChatPanel({
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
[]
|
[updateChatSessions]
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleTypewriterActiveChange = useCallback((typingKey: string, active: boolean) => {
|
const handleTypewriterActiveChange = useCallback((typingKey: string, active: boolean) => {
|
||||||
@ -4510,12 +4545,84 @@ export function CanvasChatPanel({
|
|||||||
activeChatSession,
|
activeChatSession,
|
||||||
activeComposerMode
|
activeComposerMode
|
||||||
);
|
);
|
||||||
|
useEffect(() => {
|
||||||
|
if (activeChatSessionMode !== "clawd") return;
|
||||||
|
if (!isClawdModeEnabled) return;
|
||||||
|
if (activeComposerMode !== "clawd") {
|
||||||
|
setComposerModeOverride("clawd");
|
||||||
|
}
|
||||||
|
if (isDetailGenerationMode) {
|
||||||
|
setIsDetailGenerationMode(false);
|
||||||
|
}
|
||||||
|
}, [
|
||||||
|
activeChatSessionMode,
|
||||||
|
activeComposerMode,
|
||||||
|
isClawdModeEnabled,
|
||||||
|
isDetailGenerationMode,
|
||||||
|
]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!activeChatId) return;
|
||||||
|
const historyMessages = historyData?.messages || [];
|
||||||
|
if (historyMessages.length === 0) return;
|
||||||
|
if (!historyMessages.some(isClawdChatMessage)) return;
|
||||||
|
|
||||||
|
updateChatSessions((prevSessions) => {
|
||||||
|
const currentIndex = prevSessions.findIndex(
|
||||||
|
(session) => session.id === activeChatId
|
||||||
|
);
|
||||||
|
const now = Date.now();
|
||||||
|
|
||||||
|
if (currentIndex < 0) {
|
||||||
|
const title =
|
||||||
|
deriveSessionTitleFromMessages(historyMessages) || `${CLAW_MODE_LABEL} 对话`;
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
id: activeChatId,
|
||||||
|
title,
|
||||||
|
mode: "clawd",
|
||||||
|
createdAt: now,
|
||||||
|
updatedAt: now,
|
||||||
|
},
|
||||||
|
...prevSessions,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
const current = prevSessions[currentIndex];
|
||||||
|
if (getCanvasChatSessionMode(current) === "clawd") {
|
||||||
|
return prevSessions;
|
||||||
|
}
|
||||||
|
|
||||||
|
const nextSessions = [...prevSessions];
|
||||||
|
nextSessions[currentIndex] = {
|
||||||
|
...current,
|
||||||
|
mode: "clawd",
|
||||||
|
updatedAt: Math.max(Number(current.updatedAt) || 0, now),
|
||||||
|
};
|
||||||
|
nextSessions.sort((a, b) => b.updatedAt - a.updatedAt);
|
||||||
|
return nextSessions;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (isClawdModeEnabled && activeComposerMode !== "clawd") {
|
||||||
|
setComposerModeOverride("clawd");
|
||||||
|
if (isDetailGenerationMode) {
|
||||||
|
setIsDetailGenerationMode(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [
|
||||||
|
activeChatId,
|
||||||
|
activeComposerMode,
|
||||||
|
historyData?.messages,
|
||||||
|
isClawdModeEnabled,
|
||||||
|
isDetailGenerationMode,
|
||||||
|
updateChatSessions,
|
||||||
|
]);
|
||||||
const currentModeChatSessions = useMemo(
|
const currentModeChatSessions = useMemo(
|
||||||
() =>
|
() =>
|
||||||
chatSessions.filter(
|
chatSessions.filter(
|
||||||
(session) => getCanvasChatSessionMode(session) === activeComposerMode
|
(session) => getCanvasChatSessionMode(session) === activeChatSessionMode
|
||||||
),
|
),
|
||||||
[activeComposerMode, chatSessions]
|
[activeChatSessionMode, chatSessions]
|
||||||
);
|
);
|
||||||
const agentSelectableModels = useMemo(
|
const agentSelectableModels = useMemo(
|
||||||
() =>
|
() =>
|
||||||
@ -5319,7 +5426,7 @@ export function CanvasChatPanel({
|
|||||||
if (canReuseActiveEmptySession) {
|
if (canReuseActiveEmptySession) {
|
||||||
forceHistoryHydrationRef.current = null;
|
forceHistoryHydrationRef.current = null;
|
||||||
targetChatSessionId = activeChatId;
|
targetChatSessionId = activeChatId;
|
||||||
setChatSessions((prevSessions) =>
|
updateChatSessions((prevSessions) =>
|
||||||
prevSessions.map((session) =>
|
prevSessions.map((session) =>
|
||||||
session.id === activeChatId
|
session.id === activeChatId
|
||||||
? {
|
? {
|
||||||
@ -5404,6 +5511,7 @@ export function CanvasChatPanel({
|
|||||||
releaseSendGuard,
|
releaseSendGuard,
|
||||||
replaceChatSessionQuery,
|
replaceChatSessionQuery,
|
||||||
startNewChatSession,
|
startNewChatSession,
|
||||||
|
updateChatSessions,
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -7216,7 +7324,7 @@ export function CanvasChatPanel({
|
|||||||
const derivedTitle = deriveSessionTitleFromMessages(messages);
|
const derivedTitle = deriveSessionTitleFromMessages(messages);
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
|
|
||||||
setChatSessions((prevSessions) => {
|
updateChatSessions((prevSessions) => {
|
||||||
const currentIndex = prevSessions.findIndex(
|
const currentIndex = prevSessions.findIndex(
|
||||||
(session) => session.id === activeChatId
|
(session) => session.id === activeChatId
|
||||||
);
|
);
|
||||||
@ -7252,7 +7360,7 @@ export function CanvasChatPanel({
|
|||||||
nextSessions.sort((a, b) => b.updatedAt - a.updatedAt);
|
nextSessions.sort((a, b) => b.updatedAt - a.updatedAt);
|
||||||
return nextSessions;
|
return nextSessions;
|
||||||
});
|
});
|
||||||
}, [activeChatId, messages]);
|
}, [activeChatId, messages, updateChatSessions]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (activeChatSessionMode === "clawd") return;
|
if (activeChatSessionMode === "clawd") return;
|
||||||
@ -10550,7 +10658,7 @@ export function CanvasChatPanel({
|
|||||||
},
|
},
|
||||||
} as ChatMessage;
|
} as ChatMessage;
|
||||||
|
|
||||||
setChatSessions((prevSessions) =>
|
updateChatSessions((prevSessions) =>
|
||||||
prevSessions.map((session) =>
|
prevSessions.map((session) =>
|
||||||
session.id === activeChatId
|
session.id === activeChatId
|
||||||
? {
|
? {
|
||||||
@ -11096,6 +11204,7 @@ export function CanvasChatPanel({
|
|||||||
status,
|
status,
|
||||||
mutate,
|
mutate,
|
||||||
markSessionClawdSkillTagPromptApplied,
|
markSessionClawdSkillTagPromptApplied,
|
||||||
|
updateChatSessions,
|
||||||
buildHistoryMessagesUrl,
|
buildHistoryMessagesUrl,
|
||||||
workflowContext,
|
workflowContext,
|
||||||
messages,
|
messages,
|
||||||
@ -12473,8 +12582,8 @@ export function CanvasChatPanel({
|
|||||||
);
|
);
|
||||||
|
|
||||||
const createNewChatSession = useCallback(() => {
|
const createNewChatSession = useCallback(() => {
|
||||||
startNewChatSession({ mode: activeComposerMode });
|
startNewChatSession({ mode: activeChatSessionMode });
|
||||||
}, [activeComposerMode, startNewChatSession]);
|
}, [activeChatSessionMode, startNewChatSession]);
|
||||||
|
|
||||||
const switchToSession = useCallback((sessionId: string) => {
|
const switchToSession = useCallback((sessionId: string) => {
|
||||||
if (!sessionId || sessionId === activeChatId) {
|
if (!sessionId || sessionId === activeChatId) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user