diff --git a/components/canvas/CanvasChatPanel.tsx b/components/canvas/CanvasChatPanel.tsx index 8c27f7154..07cdc1066 100644 --- a/components/canvas/CanvasChatPanel.tsx +++ b/components/canvas/CanvasChatPanel.tsx @@ -4257,7 +4257,7 @@ export function CanvasChatPanel({ const payload: CanvasViewOperationStreamPayload = typeof dataPart.data === "string" ? JSON.parse(dataPart.data) : dataPart.data; const applied = applyCanvasViewOperation(payload); - if (!applied && shouldRetryCanvasViewOperationAfterRefresh(payload)) { + if (!applied && shouldRetryCanvasViewOperationAfterRefresh(payload, canvasId)) { pendingCanvasViewOperationRef.current = payload; } } catch (e) { diff --git a/components/canvas/chat-panel/canvas-agent-stream.ts b/components/canvas/chat-panel/canvas-agent-stream.ts index e8245b7bf..a949a7094 100644 --- a/components/canvas/chat-panel/canvas-agent-stream.ts +++ b/components/canvas/chat-panel/canvas-agent-stream.ts @@ -65,10 +65,20 @@ export function shouldSkipCanvasMediaPayloadForHandledItems(params: { } export function shouldRetryCanvasViewOperationAfterRefresh( - payload: CanvasViewOperationStreamPayload + payload: CanvasViewOperationStreamPayload, + currentProjectId?: string ) { const operation = String(payload?.operation || "").trim(); if (!operation) return false; + const targetProjectId = String(payload?.projectId || "").trim(); + const normalizedCurrentProjectId = String(currentProjectId || "").trim(); + if ( + targetProjectId && + normalizedCurrentProjectId && + targetProjectId !== normalizedCurrentProjectId + ) { + return false; + } if (normalizeCanvasStreamIdList(payload.nodeIds).length > 0) return true; if (String(payload.anchorNodeId || "").trim()) return true; return ( diff --git a/tests/routes/canvas-chat-helpers.test.ts b/tests/routes/canvas-chat-helpers.test.ts index 63c1124d8..e36d6afe4 100644 --- a/tests/routes/canvas-chat-helpers.test.ts +++ b/tests/routes/canvas-chat-helpers.test.ts @@ -1241,6 +1241,18 @@ test.describe("canvas chat pure helpers", () => { operation: "zoom_in", }) ).toBe(false); + expect( + shouldRetryCanvasViewOperationAfterRefresh( + { + version: 1, + viewOperationId: "view-other-project", + operation: "focus_latest_result", + projectId: "project-other", + nodeIds: ["new-image-1"], + }, + "project-current" + ) + ).toBe(false); }); test("builds transient view operations for agent writeback results", () => {