diff --git a/src/apps/chat/AppChat.tsx b/src/apps/chat/AppChat.tsx index d973597c8..91384b9bf 100644 --- a/src/apps/chat/AppChat.tsx +++ b/src/apps/chat/AppChat.tsx @@ -18,7 +18,6 @@ import type { DConversation, DConversationId } from '~/common/stores/chat/chat.c import type { OptimaBarControlMethods } from '~/common/layout/optima/bar/OptimaBarDropdown'; import { ConfirmationModal } from '~/common/components/modals/ConfirmationModal'; import { ConversationsManager } from '~/common/chat-overlay/ConversationsManager'; -import { createErrorContentFragment, createTextContentFragment, DMessageAttachmentFragment, DMessageContentFragment, duplicateDMessageFragmentsNoVoid } from '~/common/stores/chat/chat.fragments'; import { LLM_IF_ANT_PromptCaching, LLM_IF_OAI_Vision } from '~/common/stores/llms/llms.types'; import { OptimaDrawerIn, OptimaToolbarIn } from '~/common/layout/optima/portals/OptimaPortalsIn'; import { PanelResizeInset } from '~/common/components/panes/GoodPanelResizeHandler'; @@ -27,6 +26,8 @@ import { ScrollToBottomButton } from '~/common/scroll-to-bottom/ScrollToBottomBu import { WorkspaceIdProvider } from '~/common/stores/workspace/WorkspaceIdProvider'; import { addSnackbar, removeSnackbar } from '~/common/components/snackbar/useSnackbarsStore'; import { createDMessageFromFragments, createDMessagePlaceholderIncomplete, DMessageMetadata, duplicateDMessageMetadata } from '~/common/stores/chat/chat.message'; +import { createErrorContentFragment, createTextContentFragment, DMessageAttachmentFragment, DMessageContentFragment, duplicateDMessageFragmentsNoVoid } from '~/common/stores/chat/chat.fragments'; +import { gcChatImageAssets } from '~/common/stores/chat/chat.gc'; import { getChatLLMId } from '~/common/stores/llms/store-llms'; import { getConversation, getConversationSystemPurposeId, useConversation } from '~/common/stores/chat/store-chats'; import { optimaActions, optimaOpenModels, optimaOpenPreferences, useSetOptimaAppMenu } from '~/common/layout/optima/useOptima'; @@ -52,7 +53,6 @@ import { usePanesManager } from './components/panes/usePanesManager'; import type { ChatExecuteMode } from './execute-mode/execute-mode.types'; import { _handleExecute } from './editors/_handleExecute'; -import { gcChatImageAssets } from './editors/image-generate'; // what to say when a chat is new and has no title diff --git a/src/apps/chat/editors/image-generate.ts b/src/apps/chat/editors/image-generate.ts index e0e94678c..c2f267501 100644 --- a/src/apps/chat/editors/image-generate.ts +++ b/src/apps/chat/editors/image-generate.ts @@ -1,11 +1,11 @@ -import type { DBlobAssetId } from '~/modules/dblobs/dblobs.types'; -import { gcDBImageAssets } from '~/modules/dblobs/dblobs.images'; import { getActiveTextToImageProviderOrThrow, t2iGenerateImageContentFragments } from '~/modules/t2i/t2i.client'; import type { ConversationHandler } from '~/common/chat-overlay/ConversationHandler'; import type { TextToImageProvider } from '~/common/components/useCapabilities'; -import { createErrorContentFragment, isContentOrAttachmentFragment, isImageRefPart } from '~/common/stores/chat/chat.fragments'; -import { useChatStore } from '~/common/stores/chat/store-chats'; +import { createErrorContentFragment } from '~/common/stores/chat/chat.fragments'; + + +// NOTE: also see src/common/stores/chat/chat.gc.ts, which has cleanup code for images create here /** @@ -56,30 +56,3 @@ export async function runImageGenerationUpdatingState(cHandler: ConversationHand } } -/** - * Garbage collect unreferenced dblobs in global chats - */ -export async function gcChatImageAssets() { - - // find all the dblob references in all chats - const chatsAssetIDs: Set = new Set(); - const chatStore = useChatStore.getState(); - for (const chat of chatStore.conversations) { - for (const message of chat.messages) { - for (const fragment of message.fragments) { - if (!isContentOrAttachmentFragment(fragment) || !isImageRefPart(fragment.part)) - continue; - if (fragment.part.dataRef.reftype !== 'dblob') - continue; - chatsAssetIDs.add(fragment.part.dataRef.dblobAssetId); - } - } - } - - // sanity check: if no blobs are referenced, do nothing; in case we have a state bug and we don't wipe the db - if (!chatsAssetIDs.size) - return; - - // perform the GC (set to array) - await gcDBImageAssets('global', 'app-chat', Array.from(chatsAssetIDs)); -} diff --git a/src/common/chat-overlay/ConversationHandler.ts b/src/common/chat-overlay/ConversationHandler.ts index be3476036..2a39275fc 100644 --- a/src/common/chat-overlay/ConversationHandler.ts +++ b/src/common/chat-overlay/ConversationHandler.ts @@ -1,7 +1,6 @@ import { bareBonesPromptMixer } from '~/modules/persona/pmix/pmix'; import { SystemPurposes } from '../../data'; -import { gcChatImageAssets } from '../../apps/chat/editors/image-generate'; import { createBeamVanillaStore } from '~/modules/beam/store-beam_vanilla'; @@ -10,6 +9,7 @@ import type { DLLMId } from '~/common/stores/llms/llms.types'; import { ChatActions, getConversationSystemPurposeId, useChatStore } from '~/common/stores/chat/store-chats'; import { createDMessageEmpty, createDMessageFromFragments, createDMessagePlaceholderIncomplete, createDMessageTextContent, DMessage, DMessageGenerator, DMessageId, DMessageUserFlag, MESSAGE_FLAG_VND_ANT_CACHE_AUTO, MESSAGE_FLAG_VND_ANT_CACHE_USER, messageHasUserFlag, messageSetUserFlag } from '~/common/stores/chat/chat.message'; import { createTextContentFragment, DMessageFragment, DMessageFragmentId } from '~/common/stores/chat/chat.fragments'; +import { gcChatImageAssets } from '~/common/stores/chat/chat.gc'; import { getChatLLMId } from '~/common/stores/llms/store-llms'; import { getChatAutoAI } from '../../apps/chat/store-app-chat'; diff --git a/src/common/providers/ProviderBootstrapLogic.tsx b/src/common/providers/ProviderBootstrapLogic.tsx index 2ebf754ca..8e22cb735 100644 --- a/src/common/providers/ProviderBootstrapLogic.tsx +++ b/src/common/providers/ProviderBootstrapLogic.tsx @@ -2,12 +2,12 @@ import * as React from 'react'; import { useRouter } from 'next/router'; import { gcAttachmentDBlobs } from '~/common/attachment-drafts/attachment.dblobs'; -import { gcChatImageAssets } from '../../apps/chat/editors/image-generate'; import { estimatePersistentStorageOrThrow, requestPersistentStorage } from '~/common/util/storageUtils'; import { markNewsAsSeen, shallRedirectToNews, sherpaReconfigureBackendModels } from '~/common/logic/store-logic-sherpa'; import { navigateToNews, ROUTE_APP_CHAT } from '~/common/app.routes'; import { useNextLoadProgress } from '~/common/components/useNextLoadProgress'; +import { gcChatImageAssets } from '../stores/chat/chat.gc'; export function ProviderBootstrapLogic(props: { children: React.ReactNode }) { diff --git a/src/common/stores/chat/chat.gc.ts b/src/common/stores/chat/chat.gc.ts new file mode 100644 index 000000000..ad5ea266f --- /dev/null +++ b/src/common/stores/chat/chat.gc.ts @@ -0,0 +1,33 @@ +import type { DBlobAssetId } from '~/modules/dblobs/dblobs.types'; +import { gcDBImageAssets } from '~/modules/dblobs/dblobs.images'; + +import { isContentOrAttachmentFragment, isImageRefPart } from './chat.fragments'; +import { useChatStore } from './store-chats'; + +/** + * Garbage collect unreferenced dblobs in global chats + */ +export async function gcChatImageAssets() { + + // find all the dblob references in all chats + const chatsAssetIDs: Set = new Set(); + const chatStore = useChatStore.getState(); + for (const chat of chatStore.conversations) { + for (const message of chat.messages) { + for (const fragment of message.fragments) { + if (!isContentOrAttachmentFragment(fragment) || !isImageRefPart(fragment.part)) + continue; + if (fragment.part.dataRef.reftype !== 'dblob') + continue; + chatsAssetIDs.add(fragment.part.dataRef.dblobAssetId); + } + } + } + + // sanity check: if no blobs are referenced, do nothing; in case we have a state bug and we don't wipe the db + if (!chatsAssetIDs.size) + return; + + // perform the GC (set to array) + await gcDBImageAssets('global', 'app-chat', Array.from(chatsAssetIDs)); +} \ No newline at end of file