From 1a6a1a8d6eefe49425ec55a7239e178b3b30491f Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 19 Mar 2026 00:12:27 +0800 Subject: [PATCH] fix: isolate direct image mode context --- app/(chat)/api/chat/route.ts | 75 +++++++++++++++------------ components/canvas/CanvasChatPanel.tsx | 11 +++- 2 files changed, 51 insertions(+), 35 deletions(-) diff --git a/app/(chat)/api/chat/route.ts b/app/(chat)/api/chat/route.ts index cddfa35d3..400ae4870 100644 --- a/app/(chat)/api/chat/route.ts +++ b/app/(chat)/api/chat/route.ts @@ -3141,6 +3141,7 @@ export async function POST(request: Request) { const deepThinkingOn = deepThinkingEnabled !== false; const shouldRespectDirectComposerMode = composerMode === "image" || composerMode === "video" || composerMode === "detail"; + const shouldIsolateDirectComposerContext = shouldRespectDirectComposerMode; let shouldRunAgentConversation = finalModelId === "auto"; let shouldKeepSelectedModel = false; if (shouldRespectDirectComposerMode && shouldRunAgentConversation) { @@ -3338,25 +3339,29 @@ export async function POST(request: Request) { allowWorkflowExecution?: boolean; } | undefined; - const activeStoryboardTaskForChat = await getLatestActiveVideoStoryboardTaskByChatId({ - chatId: id, - }).catch((storyboardLookupError) => { - console.warn( - "[Chat API] Failed to preload active storyboard task before smart auto mode:", - storyboardLookupError - ); - return null; - }); + const activeStoryboardTaskForChat = shouldIsolateDirectComposerContext + ? null + : await getLatestActiveVideoStoryboardTaskByChatId({ + chatId: id, + }).catch((storyboardLookupError) => { + console.warn( + "[Chat API] Failed to preload active storyboard task before smart auto mode:", + storyboardLookupError + ); + return null; + }); - requestWorkingState = await getConversationWorkingStateByChatId({ - chatId: id, - }).catch((workingStatePreloadError) => { - console.warn( - "[Chat API] Failed to preload conversation working state before smart auto mode:", - workingStatePreloadError - ); - return null; - }); + requestWorkingState = shouldIsolateDirectComposerContext + ? null + : await getConversationWorkingStateByChatId({ + chatId: id, + }).catch((workingStatePreloadError) => { + console.warn( + "[Chat API] Failed to preload conversation working state before smart auto mode:", + workingStatePreloadError + ); + return null; + }); const hasImageInputForConversationAction = message.parts.some((part: any) => part?.type === "file" || part?.type === "image" || part?.type === "image_url" ); @@ -3535,7 +3540,7 @@ export async function POST(request: Request) { }); autoTextForFallback = smartAutoInputText; - if (!requestWorkingState) { + if (!requestWorkingState && !shouldIsolateDirectComposerContext) { requestWorkingState = await getConversationWorkingStateByChatId({ chatId: id, }); @@ -4775,21 +4780,25 @@ export async function POST(request: Request) { messagesFromDb = await getMessagesByChatId({ id }); } - const loadedMessagesForBoundary = messagesFromDb; - messagesFromDb = pruneTaskBoundaryHistoryMessages({ - decision: taskBoundaryDecision, - messages: loadedMessagesForBoundary, - purpose: "model", - hasCurrentImageInput: hasImageInputForConversationAction, - }); - messagesForMediaInput = pruneTaskBoundaryHistoryMessages({ - decision: taskBoundaryDecision, - messages: loadedMessagesForBoundary, - purpose: "media", - hasCurrentImageInput: hasImageInputForConversationAction, - }); + const loadedMessagesForBoundary = shouldIsolateDirectComposerContext ? [] : messagesFromDb; + messagesFromDb = shouldIsolateDirectComposerContext + ? [] + : pruneTaskBoundaryHistoryMessages({ + decision: taskBoundaryDecision, + messages: loadedMessagesForBoundary, + purpose: "model", + hasCurrentImageInput: hasImageInputForConversationAction, + }); + messagesForMediaInput = shouldIsolateDirectComposerContext + ? [] + : pruneTaskBoundaryHistoryMessages({ + decision: taskBoundaryDecision, + messages: loadedMessagesForBoundary, + purpose: "media", + hasCurrentImageInput: hasImageInputForConversationAction, + }); - if (!requestWorkingState) { + if (!requestWorkingState && !shouldIsolateDirectComposerContext) { requestWorkingState = await getConversationWorkingStateByChatId({ chatId: id, }); diff --git a/components/canvas/CanvasChatPanel.tsx b/components/canvas/CanvasChatPanel.tsx index b3f6be7a0..af899c922 100644 --- a/components/canvas/CanvasChatPanel.tsx +++ b/components/canvas/CanvasChatPanel.tsx @@ -4936,10 +4936,17 @@ export function CanvasChatPanel({ if (imageNodes.length === 0) return undefined; + const shouldIsolateDirectModeContext = activeComposerMode !== "agent"; + if (shouldIsolateDirectModeContext && selectedImageNodes.length === 0) { + return undefined; + } + const MAX_CONTEXT_IMAGES = 12; const selectedIds = new Set(selectedImageNodes.map((node) => node.id)); const prioritizedNodes = - selectedImageNodes.length > 0 + shouldIsolateDirectModeContext + ? selectedImageNodes + : selectedImageNodes.length > 0 ? [ ...selectedImageNodes, ...imageNodes.filter((node) => !selectedIds.has(node.id)), @@ -4985,7 +4992,7 @@ export function CanvasChatPanel({ isSelected: selectedIds.has(node.id), })), }; - }, [canvasId, nodes, selectedImageNodes]); + }, [activeComposerMode, canvasId, nodes, selectedImageNodes]); const updateAttachmentAtVideoSlot = useCallback( (slotIndex: number, attachment: PickedObjectAttachment | null) => {