From 07d59b66406e4b5bfb193056f956abbbdb85c322 Mon Sep 17 00:00:00 2001 From: Ankit Matth Date: Sat, 23 Aug 2025 20:25:29 +0530 Subject: [PATCH] refactor: use list instead of string parsing --- application/retriever/classic_rag.py | 11 +---- frontend/src/components/SourcesPopup.tsx | 41 +++++++++++------- .../src/conversation/conversationHandlers.ts | 42 +++++++++---------- .../src/conversation/conversationModels.ts | 2 +- .../src/modals/ShareConversationModal.tsx | 14 +++---- frontend/src/preferences/preferenceSlice.ts | 19 +++++---- 6 files changed, 68 insertions(+), 61 deletions(-) diff --git a/application/retriever/classic_rag.py b/application/retriever/classic_rag.py index b558c8f0..82423bb5 100644 --- a/application/retriever/classic_rag.py +++ b/application/retriever/classic_rag.py @@ -46,17 +46,10 @@ class ClassicRAG(BaseRetriever): user_api_key=self.user_api_key, decoded_token=decoded_token, ) - if "active_docs" in source: + + if "active_docs" in source and source["active_docs"] is not None: if isinstance(source["active_docs"], list): self.vectorstores = source["active_docs"] - elif ( - isinstance(source["active_docs"], str) and "," in source["active_docs"] - ): - self.vectorstores = [ - doc_id.strip() - for doc_id in source["active_docs"].split(",") - if doc_id.strip() - ] else: self.vectorstores = [source["active_docs"]] else: diff --git a/frontend/src/components/SourcesPopup.tsx b/frontend/src/components/SourcesPopup.tsx index c3a61e01..f13ee25a 100644 --- a/frontend/src/components/SourcesPopup.tsx +++ b/frontend/src/components/SourcesPopup.tsx @@ -17,7 +17,7 @@ type SourcesPopupProps = { isOpen: boolean; onClose: () => void; anchorRef: React.RefObject; - handlePostDocumentSelect: (doc: Doc | null) => void; + handlePostDocumentSelect: (doc: Doc[] | null) => void; setUploadModalState: React.Dispatch>; }; @@ -149,9 +149,12 @@ export default function SourcesPopup({ if (option.model === embeddingsName) { const isSelected = selectedDocs && - Array.isArray(selectedDocs) && selectedDocs.length > 0 && - selectedDocs.some(doc => - option.id ? doc.id === option.id : doc.date === option.date + Array.isArray(selectedDocs) && + selectedDocs.length > 0 && + selectedDocs.some((doc) => + option.id + ? doc.id === option.id + : doc.date === option.date, ); return ( @@ -160,17 +163,27 @@ export default function SourcesPopup({ className="border-opacity-80 dark:border-dim-gray flex cursor-pointer items-center border-b border-[#D9D9D9] p-3 transition-colors hover:bg-gray-100 dark:text-[14px] dark:hover:bg-[#2C2E3C]" onClick={() => { if (isSelected) { - const updatedDocs = (selectedDocs && Array.isArray(selectedDocs)) - ? selectedDocs.filter(doc => - option.id ? doc.id !== option.id : doc.date !== option.date - ) - : []; - dispatch(setSelectedDocs(updatedDocs.length > 0 ? updatedDocs : null)); - handlePostDocumentSelect(updatedDocs.length > 0 ? updatedDocs : null); + const updatedDocs = + selectedDocs && Array.isArray(selectedDocs) + ? selectedDocs.filter((doc) => + option.id + ? doc.id !== option.id + : doc.date !== option.date, + ) + : []; + dispatch( + setSelectedDocs( + updatedDocs.length > 0 ? updatedDocs : null, + ), + ); + handlePostDocumentSelect( + updatedDocs.length > 0 ? updatedDocs : null, + ); } else { - const updatedDocs = (selectedDocs && Array.isArray(selectedDocs)) - ? [...selectedDocs, option] - : [option]; + const updatedDocs = + selectedDocs && Array.isArray(selectedDocs) + ? [...selectedDocs, option] + : [option]; dispatch(setSelectedDocs(updatedDocs)); handlePostDocumentSelect(updatedDocs); } diff --git a/frontend/src/conversation/conversationHandlers.ts b/frontend/src/conversation/conversationHandlers.ts index ae60b070..63557924 100644 --- a/frontend/src/conversation/conversationHandlers.ts +++ b/frontend/src/conversation/conversationHandlers.ts @@ -7,7 +7,7 @@ export function handleFetchAnswer( question: string, signal: AbortSignal, token: string | null, - selectedDocs: Doc | Doc[] | null, + selectedDocs: Doc[] | null, conversationId: string | null, promptId: string | null, chunks: string, @@ -52,15 +52,15 @@ export function handleFetchAnswer( payload.attachments = attachments; } - if (selectedDocs) { - if (Array.isArray(selectedDocs)) { + if (selectedDocs && Array.isArray(selectedDocs)) { + if (selectedDocs.length > 1) { // Handle multiple documents - payload.active_docs = selectedDocs.map(doc => doc.id).join(','); + payload.active_docs = selectedDocs.map((doc) => doc.id!); payload.retriever = selectedDocs[0]?.retriever as string; - } else if ('id' in selectedDocs) { + } else if (selectedDocs.length === 1 && 'id' in selectedDocs[0]) { // Handle single document (backward compatibility) - payload.active_docs = selectedDocs.id as string; - payload.retriever = selectedDocs.retriever as string; + payload.active_docs = selectedDocs[0].id as string; + payload.retriever = selectedDocs[0].retriever as string; } } return conversationService @@ -91,7 +91,7 @@ export function handleFetchAnswerSteaming( question: string, signal: AbortSignal, token: string | null, - selectedDocs: Doc | Doc[] | null, + selectedDocs: Doc[] | null, conversationId: string | null, promptId: string | null, chunks: string, @@ -119,15 +119,15 @@ export function handleFetchAnswerSteaming( payload.attachments = attachments; } - if (selectedDocs) { - if (Array.isArray(selectedDocs)) { + if (selectedDocs && Array.isArray(selectedDocs)) { + if (selectedDocs.length > 1) { // Handle multiple documents - payload.active_docs = selectedDocs.map(doc => doc.id).join(','); + payload.active_docs = selectedDocs.map((doc) => doc.id!); payload.retriever = selectedDocs[0]?.retriever as string; - } else if ('id' in selectedDocs) { + } else if (selectedDocs.length === 1 && 'id' in selectedDocs[0]) { // Handle single document (backward compatibility) - payload.active_docs = selectedDocs.id as string; - payload.retriever = selectedDocs.retriever as string; + payload.active_docs = selectedDocs[0].id as string; + payload.retriever = selectedDocs[0].retriever as string; } } @@ -185,7 +185,7 @@ export function handleFetchAnswerSteaming( export function handleSearch( question: string, token: string | null, - selectedDocs: Doc | Doc[] | null, + selectedDocs: Doc[] | null, conversation_id: string | null, chunks: string, token_limit: number, @@ -197,15 +197,15 @@ export function handleSearch( token_limit: token_limit, isNoneDoc: selectedDocs === null, }; - if (selectedDocs) { - if (Array.isArray(selectedDocs)) { + if (selectedDocs && Array.isArray(selectedDocs)) { + if (selectedDocs.length > 1) { // Handle multiple documents - payload.active_docs = selectedDocs.map(doc => doc.id).join(','); + payload.active_docs = selectedDocs.map((doc) => doc.id!); payload.retriever = selectedDocs[0]?.retriever as string; - } else if ('id' in selectedDocs) { + } else if (selectedDocs.length === 1 && 'id' in selectedDocs[0]) { // Handle single document (backward compatibility) - payload.active_docs = selectedDocs.id as string; - payload.retriever = selectedDocs.retriever as string; + payload.active_docs = selectedDocs[0].id as string; + payload.retriever = selectedDocs[0].retriever as string; } } return conversationService diff --git a/frontend/src/conversation/conversationModels.ts b/frontend/src/conversation/conversationModels.ts index 08743e73..2b9f6ee3 100644 --- a/frontend/src/conversation/conversationModels.ts +++ b/frontend/src/conversation/conversationModels.ts @@ -54,7 +54,7 @@ export interface Query { export interface RetrievalPayload { question: string; - active_docs?: string; + active_docs?: string | string[]; retriever?: string; conversation_id: string | null; prompt_id?: string | null; diff --git a/frontend/src/modals/ShareConversationModal.tsx b/frontend/src/modals/ShareConversationModal.tsx index 99262f01..624d64f5 100644 --- a/frontend/src/modals/ShareConversationModal.tsx +++ b/frontend/src/modals/ShareConversationModal.tsx @@ -60,7 +60,7 @@ export const ShareConversationModal = ({ const [sourcePath, setSourcePath] = useState<{ label: string; value: string; - } | null>(preSelectedDoc ? extractDocPaths([preSelectedDoc])[0] : null); + } | null>(preSelectedDoc ? extractDocPaths(preSelectedDoc)[0] : null); const handleCopyKey = (url: string) => { navigator.clipboard.writeText(url); @@ -105,14 +105,14 @@ export const ShareConversationModal = ({ return (
-

+

{t('modals.shareConv.label')}

-

+

{t('modals.shareConv.note')}

- + {t('modals.shareConv.option')} )}
- + {`${domain}/share/${identifier ?? '....'}`} {status === 'fetched' ? ( ) : (