fix: persist claw chat sessions

This commit is contained in:
134 2026-07-07 22:13:39 +08:00
parent 16f23b3f7c
commit f692425607

View File

@ -2432,6 +2432,33 @@ export function CanvasChatPanel({
);
}, [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(
(options?: {
mode?: CanvasComposerMode;
@ -2462,13 +2489,19 @@ export function CanvasChatPanel({
forceHistoryHydrationRef.current = null;
releaseSendGuard(activeChatId);
setChatSessions((prevSessions) => [newSession, ...prevSessions]);
updateChatSessions((prevSessions) => [newSession, ...prevSessions]);
setActiveChatId(newChatSessionId);
replaceChatSessionQuery(newChatSessionId);
toast.success(options?.toastMessage || "已新建聊天窗口");
return newChatSessionId;
},
[activeChatId, chatSessions, releaseSendGuard, replaceChatSessionQuery]
[
activeChatId,
chatSessions,
releaseSendGuard,
replaceChatSessionQuery,
updateChatSessions,
]
);
const setSessionClawdSkillTag = useCallback(
@ -2479,11 +2512,12 @@ export function CanvasChatPanel({
) => {
if (!chatSessionId) return;
const normalizedTagId = String(tagId || "").trim() || null;
setChatSessions((prevSessions) =>
updateChatSessions((prevSessions) =>
prevSessions.map((session) =>
session.id === chatSessionId
? {
...session,
mode: "clawd",
clawdSkillTagId: normalizedTagId,
clawdSkillTagPromptApplied:
normalizedTagId === null
@ -2495,17 +2529,18 @@ export function CanvasChatPanel({
)
);
},
[]
[updateChatSessions]
);
const markSessionClawdSkillTagPromptApplied = useCallback(
(chatSessionId: string, tagId: string) => {
if (!chatSessionId || !tagId) return;
setChatSessions((prevSessions) =>
updateChatSessions((prevSessions) =>
prevSessions.map((session) =>
session.id === chatSessionId && session.clawdSkillTagId === tagId
? {
...session,
mode: "clawd",
clawdSkillTagPromptApplied: true,
updatedAt: Date.now(),
}
@ -2513,7 +2548,7 @@ export function CanvasChatPanel({
)
);
},
[]
[updateChatSessions]
);
const handleTypewriterActiveChange = useCallback((typingKey: string, active: boolean) => {
@ -4510,12 +4545,84 @@ export function CanvasChatPanel({
activeChatSession,
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(
() =>
chatSessions.filter(
(session) => getCanvasChatSessionMode(session) === activeComposerMode
(session) => getCanvasChatSessionMode(session) === activeChatSessionMode
),
[activeComposerMode, chatSessions]
[activeChatSessionMode, chatSessions]
);
const agentSelectableModels = useMemo(
() =>
@ -5319,7 +5426,7 @@ export function CanvasChatPanel({
if (canReuseActiveEmptySession) {
forceHistoryHydrationRef.current = null;
targetChatSessionId = activeChatId;
setChatSessions((prevSessions) =>
updateChatSessions((prevSessions) =>
prevSessions.map((session) =>
session.id === activeChatId
? {
@ -5404,6 +5511,7 @@ export function CanvasChatPanel({
releaseSendGuard,
replaceChatSessionQuery,
startNewChatSession,
updateChatSessions,
]
);
@ -7216,7 +7324,7 @@ export function CanvasChatPanel({
const derivedTitle = deriveSessionTitleFromMessages(messages);
const now = Date.now();
setChatSessions((prevSessions) => {
updateChatSessions((prevSessions) => {
const currentIndex = prevSessions.findIndex(
(session) => session.id === activeChatId
);
@ -7252,7 +7360,7 @@ export function CanvasChatPanel({
nextSessions.sort((a, b) => b.updatedAt - a.updatedAt);
return nextSessions;
});
}, [activeChatId, messages]);
}, [activeChatId, messages, updateChatSessions]);
useEffect(() => {
if (activeChatSessionMode === "clawd") return;
@ -10550,7 +10658,7 @@ export function CanvasChatPanel({
},
} as ChatMessage;
setChatSessions((prevSessions) =>
updateChatSessions((prevSessions) =>
prevSessions.map((session) =>
session.id === activeChatId
? {
@ -11096,6 +11204,7 @@ export function CanvasChatPanel({
status,
mutate,
markSessionClawdSkillTagPromptApplied,
updateChatSessions,
buildHistoryMessagesUrl,
workflowContext,
messages,
@ -12473,8 +12582,8 @@ export function CanvasChatPanel({
);
const createNewChatSession = useCallback(() => {
startNewChatSession({ mode: activeComposerMode });
}, [activeComposerMode, startNewChatSession]);
startNewChatSession({ mode: activeChatSessionMode });
}, [activeChatSessionMode, startNewChatSession]);
const switchToSession = useCallback((sessionId: string) => {
if (!sessionId || sessionId === activeChatId) {