Separate agent chat sessions from canvas chats
Some checks failed
Lint / build (20) (push) Has been cancelled
Playwright Tests / test (push) Has been cancelled

This commit is contained in:
Your Name 2026-03-11 09:44:04 +08:00
parent 0a2b8b3045
commit 9c6abd93da
2 changed files with 36 additions and 10 deletions

View File

@ -758,6 +758,7 @@ export default function CanvasEditorPage({ params }: PageProps) {
chatId={`canvas-${id}`}
onClose={() => {}}
selectedAgentPresetId={isAgentFeatureEnabled ? selectedAgentPresetId : null}
chatScope="agent"
/>
</div>
</div>
@ -815,6 +816,7 @@ export default function CanvasEditorPage({ params }: PageProps) {
onClose={() => setIsPanelOpen(false)}
onOpenFileList={() => setPanelMode('fileList')}
selectedAgentPresetId={isAgentFeatureEnabled ? selectedAgentPresetId : null}
chatScope="canvas"
/>
</div>
) : (

View File

@ -109,6 +109,7 @@ interface CanvasChatPanelProps {
onClose?: () => void;
onOpenFileList?: () => void;
selectedAgentPresetId?: string | null;
chatScope?: "canvas" | "agent";
}
type VideoStoryboardStreamData =
@ -1254,8 +1255,12 @@ function toRawCanvasChatId(value: string): string {
return value.startsWith("canvas-") ? value.replace("canvas-", "") : value;
}
function getSessionStorageKey(canvasId: string): string {
return `canvas-chat-sessions:${canvasId}`;
function getSessionStorageKey(canvasId: string, scope: "canvas" | "agent"): string {
return `canvas-chat-sessions:${scope}:${canvasId}`;
}
function getSessionRootStorageKey(canvasId: string, scope: "canvas" | "agent"): string {
return `canvas-chat-root:${scope}:${canvasId}`;
}
function deriveSessionTitleFromMessages(messages: ChatMessage[]): string {
@ -1592,6 +1597,7 @@ export function CanvasChatPanel({
onClose,
onOpenFileList,
selectedAgentPresetId,
chatScope = "canvas",
}: CanvasChatPanelProps) {
const { data: session } = useSession();
const [input, setInput] = useState("");
@ -1918,15 +1924,33 @@ export function CanvasChatPanel({
useEffect(() => {
const now = Date.now();
let rootChatId = chatId;
if (chatScope === "agent") {
try {
const rootKey = getSessionRootStorageKey(canvasId, chatScope);
const savedRootChatId = localStorage.getItem(rootKey);
if (savedRootChatId && savedRootChatId.startsWith("canvas-")) {
rootChatId = savedRootChatId;
} else {
rootChatId = `canvas-${crypto.randomUUID()}`;
localStorage.setItem(rootKey, rootChatId);
}
} catch (error) {
console.error("[CanvasChat] Failed to initialize agent root chat id:", error);
rootChatId = `canvas-${crypto.randomUUID()}`;
}
}
const fallbackSession: CanvasChatSession = {
id: chatId,
id: rootChatId,
title: "对话 1",
createdAt: now,
updatedAt: now,
};
try {
const key = getSessionStorageKey(canvasId);
const key = getSessionStorageKey(canvasId, chatScope);
const saved = localStorage.getItem(key);
const parsed = saved ? (JSON.parse(saved) as CanvasChatSession[]) : [];
@ -1939,21 +1963,21 @@ export function CanvasChatPanel({
updatedAt: Number(session.updatedAt) || now,
}));
const hasCurrent = sanitized.some((session) => session.id === chatId);
const hasCurrent = sanitized.some((session) => session.id === rootChatId);
const nextSessions = hasCurrent
? sanitized
: [fallbackSession, ...sanitized];
const sorted = [...nextSessions].sort((a, b) => b.updatedAt - a.updatedAt);
setChatSessions(sorted);
setActiveChatId(chatId);
setActiveChatId(rootChatId);
localStorage.setItem(key, JSON.stringify(sorted));
} catch (error) {
console.error("[CanvasChat] Failed to load chat sessions:", error);
setChatSessions([fallbackSession]);
setActiveChatId(chatId);
setActiveChatId(rootChatId);
}
}, [canvasId, chatId]);
}, [canvasId, chatId, chatScope]);
useEffect(() => {
if (!isSessionMenuOpen) return;
@ -1969,13 +1993,13 @@ export function CanvasChatPanel({
useEffect(() => {
try {
localStorage.setItem(
getSessionStorageKey(canvasId),
getSessionStorageKey(canvasId, chatScope),
JSON.stringify(chatSessions)
);
} catch (error) {
console.error("[CanvasChat] Failed to save chat sessions:", error);
}
}, [canvasId, chatSessions]);
}, [canvasId, chatScope, chatSessions]);
// Canvas store
const addNode = useCanvasStore((state) => state.addNode);