diff --git a/lib/ai/conversation-state-protocol.ts b/lib/ai/conversation-state-protocol.ts index 76f311541..11f48bdd5 100644 --- a/lib/ai/conversation-state-protocol.ts +++ b/lib/ai/conversation-state-protocol.ts @@ -182,6 +182,16 @@ type ConversationStateProtocolEventObserver = (event: { payload: Record; }) => void; +function preferIncomingNonEmptyArray( + incoming?: string[] | null, + fallback?: string[] | null, +): string[] | null | undefined { + if (incoming === undefined) return fallback ?? undefined; + if (Array.isArray(incoming) && incoming.length > 0) return incoming; + if (Array.isArray(fallback) && fallback.length > 0) return fallback; + return incoming; +} + let protocolEventObserver: ConversationStateProtocolEventObserver | null = null; export function bootstrapConversationStateProtocol(params: { @@ -671,21 +681,63 @@ export async function persistConversationStateEvent; + const existing = await getConversationWorkingStateByChatId({ + chatId: typed.chatId, + }).catch(() => null); + const existingImageWorkflowMemory = extractImageWorkflowMemory(existing); + const preservedCurrentFocusAssetIds = preferIncomingNonEmptyArray( + typed.currentFocusAssetIds, + existing?.currentFocusAssetIds, + ); + const preservedCurrentFocusImageUrls = preferIncomingNonEmptyArray( + typed.currentFocusImageUrls, + existing?.currentFocusImageUrls, + ); + const preservedLastUploadedAssetIds = preferIncomingNonEmptyArray( + typed.lastUploadedAssetIds, + existing?.lastUploadedAssetIds, + ); + const preservedLastUploadedImageUrls = preferIncomingNonEmptyArray( + typed.lastUploadedImageUrls, + existing?.lastUploadedImageUrls, + ); + const preservedLastReferencedAssetIds = preferIncomingNonEmptyArray( + typed.lastReferencedAssetIds, + existing?.lastReferencedAssetIds, + ); + const preservedLastReferencedImageUrls = preferIncomingNonEmptyArray( + typed.lastReferencedImageUrls, + existing?.lastReferencedImageUrls, + ); + const preservedLastResolvedTargetAssetIds = preferIncomingNonEmptyArray( + typed.lastResolvedTargetAssetIds, + existing?.lastResolvedTargetAssetIds, + ); + const preservedLastResolvedTargetImageUrls = preferIncomingNonEmptyArray( + typed.lastResolvedTargetImageUrls, + existing?.lastResolvedTargetImageUrls, + ); + const workflowSourceImageUrls = + (Array.isArray(preservedLastResolvedTargetImageUrls) && + preservedLastResolvedTargetImageUrls.length > 0 + ? preservedLastResolvedTargetImageUrls + : preservedLastUploadedImageUrls) || null; + return persistConversationStateProtocol({ userId: typed.userId, chatId: typed.chatId, projectId: typed.projectId, currentIntent: typed.currentIntent, - currentFocusAssetIds: typed.currentFocusAssetIds, - currentFocusImageUrls: typed.currentFocusImageUrls, + currentFocusAssetIds: preservedCurrentFocusAssetIds, + currentFocusImageUrls: preservedCurrentFocusImageUrls, selectedAssetIds: typed.selectedAssetIds, selectedImageUrls: typed.selectedImageUrls, - lastUploadedAssetIds: typed.lastUploadedAssetIds, - lastUploadedImageUrls: typed.lastUploadedImageUrls, - lastReferencedAssetIds: typed.lastReferencedAssetIds, - lastReferencedImageUrls: typed.lastReferencedImageUrls, - lastResolvedTargetAssetIds: typed.lastResolvedTargetAssetIds, - lastResolvedTargetImageUrls: typed.lastResolvedTargetImageUrls, + lastUploadedAssetIds: preservedLastUploadedAssetIds, + lastUploadedImageUrls: preservedLastUploadedImageUrls, + lastReferencedAssetIds: preservedLastReferencedAssetIds, + lastReferencedImageUrls: preservedLastReferencedImageUrls, + lastResolvedTargetAssetIds: preservedLastResolvedTargetAssetIds, + lastResolvedTargetImageUrls: preservedLastResolvedTargetImageUrls, activeCanvasNodeIds: typed.activeCanvasNodeIds, lastCanvasSnapshot: typed.lastCanvasSnapshot, lastMessageId: typed.lastMessageId, @@ -694,6 +746,17 @@ export async function persistConversationStateEvent