From 89b4a82e620e0dba8e280e84288b03048947de2b Mon Sep 17 00:00:00 2001 From: 134 Date: Tue, 23 Jun 2026 20:07:53 +0800 Subject: [PATCH] fix: support canvas view prompts without context payload --- app/(chat)/api/chat/route.ts | 72 +++++++++++++++++++++++++++++++----- 1 file changed, 62 insertions(+), 10 deletions(-) diff --git a/app/(chat)/api/chat/route.ts b/app/(chat)/api/chat/route.ts index b92c19b07..cbef1e2e0 100644 --- a/app/(chat)/api/chat/route.ts +++ b/app/(chat)/api/chat/route.ts @@ -881,6 +881,16 @@ export async function POST(request: Request) { return ""; } })(); + const isCanvasPageRequest = (() => { + const referer = request.headers.get("referer"); + if (!referer) return false; + try { + const pathname = new URL(referer).pathname; + return pathname === "/canvas" || pathname.startsWith("/canvas/"); + } catch { + return false; + } + })(); const requestTextContent = message.parts .filter((part): part is { type: "text"; text: string } => part.type === "text") .map((part) => part.text) @@ -900,7 +910,8 @@ export async function POST(request: Request) { composerMode !== "agent" && (contextPayload?.source === "canvas" || contextPayload?.source === "realtime-canvas" || - Boolean(requestCanvasAgentContext)) && + Boolean(requestCanvasAgentContext) || + isCanvasPageRequest) && shouldBypassCanvasImagePointsPrecheckForAgentControl({ text: requestTextContent, activeComposerMode: composerMode, @@ -3213,8 +3224,11 @@ export async function POST(request: Request) { const resolveCanvasViewOperationPlan = (): CanvasViewOperationPlan | null => { if (!canvasAgentFeatures.viewOperationEnabled) return null; if (composerMode !== "agent" && !hasCanvasControlIntentFastPath) return null; - if (contextPayload?.source !== "canvas" || !contextPayload.projectId) return null; - if (!requestCanvasAgentContext) return null; + const projectId = + contextPayload?.projectId || + requestCanvasAgentContext?.projectId || + (hasCanvasControlIntentFastPath ? id : undefined); + if (!projectId) return null; const text = requestTextContent.trim(); if (!text) return null; @@ -3234,10 +3248,48 @@ export async function POST(request: Request) { const viewOperationId = `${message.id}:canvas-view:${Date.now()}`; + if (!requestCanvasAgentContext) { + if (/看全局|看整体|看全部|全局|整体/.test(lowerText)) { + return { + version: 1, + viewOperationId, + operation: "fit_all", + projectId, + padding: 140, + persist: false, + reason: "fit_all_canvas", + }; + } + + if (/缩小|拉远|zoom\s*out/.test(lowerText)) { + return { + version: 1, + viewOperationId, + operation: "zoom_out", + projectId, + persist: false, + reason: "zoom_out_canvas", + }; + } + + if (/放大|拉近|zoom\s*in/.test(lowerText)) { + return { + version: 1, + viewOperationId, + operation: "zoom_in", + projectId, + persist: false, + reason: "zoom_in_canvas", + }; + } + + return null; + } + if (hasLatestResultViewIntent) { const latestResultViewPlan = buildCanvasAgentLatestResultViewPlan({ userText: text, - projectId: contextPayload.projectId, + projectId, operationId: viewOperationId, }); if (latestResultViewPlan) return latestResultViewPlan; @@ -3270,7 +3322,7 @@ export async function POST(request: Request) { if (hasComparisonViewIntent) { const comparisonViewPlan = buildCanvasAgentComparisonViewPlan({ context: requestCanvasAgentContext, - projectId: contextPayload.projectId, + projectId, operationId: viewOperationId, }); if (comparisonViewPlan) return comparisonViewPlan; @@ -3281,7 +3333,7 @@ export async function POST(request: Request) { version: 1, viewOperationId, operation: "fit_all", - projectId: contextPayload.projectId, + projectId, padding: 140, persist: false, reason: "fit_all_canvas", @@ -3293,7 +3345,7 @@ export async function POST(request: Request) { version: 1, viewOperationId, operation: "zoom_out", - projectId: contextPayload.projectId, + projectId, persist: false, reason: "zoom_out_canvas", }; @@ -3313,7 +3365,7 @@ export async function POST(request: Request) { version: 1, viewOperationId, operation: nodeIds.length > 1 ? "focus_nodes" : "focus_selection", - projectId: contextPayload.projectId, + projectId, nodeIds, anchorNodeId: anchorNode?.nodeId, padding: 120, @@ -3326,7 +3378,7 @@ export async function POST(request: Request) { const panViewPlan = buildCanvasAgentPanViewPlan({ userText: text, context: requestCanvasAgentContext, - projectId: contextPayload.projectId, + projectId, operationId: viewOperationId, }); if (panViewPlan) return panViewPlan; @@ -3337,7 +3389,7 @@ export async function POST(request: Request) { version: 1, viewOperationId, operation: "zoom_in", - projectId: contextPayload.projectId, + projectId, persist: false, reason: "zoom_in_canvas", };