mirror of
https://github.com/arc53/DocsGPT.git
synced 2025-11-29 08:33:20 +00:00
added support for multi select sources
This commit is contained in:
@@ -368,8 +368,8 @@ export default function MessageInput({
|
||||
className="xs:px-3 xs:py-1.5 dark:border-purple-taupe flex max-w-[130px] items-center rounded-[32px] border border-[#AAAAAA] px-2 py-1 transition-colors hover:bg-gray-100 sm:max-w-[150px] dark:hover:bg-[#2C2E3C]"
|
||||
onClick={() => setIsSourcesPopupOpen(!isSourcesPopupOpen)}
|
||||
title={
|
||||
selectedDocs
|
||||
? selectedDocs.name
|
||||
selectedDocs && selectedDocs.length > 0
|
||||
? selectedDocs.map(doc => doc.name).join(', ')
|
||||
: t('conversation.sources.title')
|
||||
}
|
||||
>
|
||||
@@ -379,8 +379,10 @@ export default function MessageInput({
|
||||
className="mr-1 h-3.5 w-3.5 shrink-0 sm:mr-1.5 sm:h-4"
|
||||
/>
|
||||
<span className="xs:text-[12px] dark:text-bright-gray truncate overflow-hidden text-[10px] font-medium text-[#5D5D5D] sm:text-[14px]">
|
||||
{selectedDocs
|
||||
? selectedDocs.name
|
||||
{selectedDocs && selectedDocs.length > 0
|
||||
? selectedDocs.length === 1
|
||||
? selectedDocs[0].name
|
||||
: `${selectedDocs.length} sources selected`
|
||||
: t('conversation.sources.title')}
|
||||
</span>
|
||||
{!isTouch && (
|
||||
|
||||
@@ -149,9 +149,10 @@ export default function SourcesPopup({
|
||||
if (option.model === embeddingsName) {
|
||||
const isSelected =
|
||||
selectedDocs &&
|
||||
(option.id
|
||||
? selectedDocs.id === option.id
|
||||
: selectedDocs.date === option.date);
|
||||
Array.isArray(selectedDocs) && selectedDocs.length > 0 &&
|
||||
selectedDocs.some(doc =>
|
||||
option.id ? doc.id === option.id : doc.date === option.date
|
||||
);
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -159,11 +160,19 @@ 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) {
|
||||
dispatch(setSelectedDocs(null));
|
||||
handlePostDocumentSelect(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 {
|
||||
dispatch(setSelectedDocs(option));
|
||||
handlePostDocumentSelect(option);
|
||||
const updatedDocs = (selectedDocs && Array.isArray(selectedDocs))
|
||||
? [...selectedDocs, option]
|
||||
: [option];
|
||||
dispatch(setSelectedDocs(updatedDocs));
|
||||
handlePostDocumentSelect(updatedDocs);
|
||||
}
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -7,7 +7,7 @@ export function handleFetchAnswer(
|
||||
question: string,
|
||||
signal: AbortSignal,
|
||||
token: string | null,
|
||||
selectedDocs: Doc | null,
|
||||
selectedDocs: Doc | Doc[] | null,
|
||||
conversationId: string | null,
|
||||
promptId: string | null,
|
||||
chunks: string,
|
||||
@@ -52,10 +52,17 @@ export function handleFetchAnswer(
|
||||
payload.attachments = attachments;
|
||||
}
|
||||
|
||||
if (selectedDocs && 'id' in selectedDocs) {
|
||||
payload.active_docs = selectedDocs.id as string;
|
||||
if (selectedDocs) {
|
||||
if (Array.isArray(selectedDocs)) {
|
||||
// Handle multiple documents
|
||||
payload.active_docs = selectedDocs.map(doc => doc.id).join(',');
|
||||
payload.retriever = selectedDocs[0]?.retriever as string;
|
||||
} else if ('id' in selectedDocs) {
|
||||
// Handle single document (backward compatibility)
|
||||
payload.active_docs = selectedDocs.id as string;
|
||||
payload.retriever = selectedDocs.retriever as string;
|
||||
}
|
||||
}
|
||||
payload.retriever = selectedDocs?.retriever as string;
|
||||
return conversationService
|
||||
.answer(payload, token, signal)
|
||||
.then((response) => {
|
||||
@@ -84,7 +91,7 @@ export function handleFetchAnswerSteaming(
|
||||
question: string,
|
||||
signal: AbortSignal,
|
||||
token: string | null,
|
||||
selectedDocs: Doc | null,
|
||||
selectedDocs: Doc | Doc[] | null,
|
||||
conversationId: string | null,
|
||||
promptId: string | null,
|
||||
chunks: string,
|
||||
@@ -112,10 +119,17 @@ export function handleFetchAnswerSteaming(
|
||||
payload.attachments = attachments;
|
||||
}
|
||||
|
||||
if (selectedDocs && 'id' in selectedDocs) {
|
||||
payload.active_docs = selectedDocs.id as string;
|
||||
if (selectedDocs) {
|
||||
if (Array.isArray(selectedDocs)) {
|
||||
// Handle multiple documents
|
||||
payload.active_docs = selectedDocs.map(doc => doc.id).join(',');
|
||||
payload.retriever = selectedDocs[0]?.retriever as string;
|
||||
} else if ('id' in selectedDocs) {
|
||||
// Handle single document (backward compatibility)
|
||||
payload.active_docs = selectedDocs.id as string;
|
||||
payload.retriever = selectedDocs.retriever as string;
|
||||
}
|
||||
}
|
||||
payload.retriever = selectedDocs?.retriever as string;
|
||||
|
||||
return new Promise<Answer>((resolve, reject) => {
|
||||
conversationService
|
||||
@@ -171,7 +185,7 @@ export function handleFetchAnswerSteaming(
|
||||
export function handleSearch(
|
||||
question: string,
|
||||
token: string | null,
|
||||
selectedDocs: Doc | null,
|
||||
selectedDocs: Doc | Doc[] | null,
|
||||
conversation_id: string | null,
|
||||
chunks: string,
|
||||
token_limit: number,
|
||||
@@ -183,9 +197,17 @@ export function handleSearch(
|
||||
token_limit: token_limit,
|
||||
isNoneDoc: selectedDocs === null,
|
||||
};
|
||||
if (selectedDocs && 'id' in selectedDocs)
|
||||
payload.active_docs = selectedDocs.id as string;
|
||||
payload.retriever = selectedDocs?.retriever as string;
|
||||
if (selectedDocs) {
|
||||
if (Array.isArray(selectedDocs)) {
|
||||
// Handle multiple documents
|
||||
payload.active_docs = selectedDocs.map(doc => doc.id).join(',');
|
||||
payload.retriever = selectedDocs[0]?.retriever as string;
|
||||
} else if ('id' in selectedDocs) {
|
||||
// Handle single document (backward compatibility)
|
||||
payload.active_docs = selectedDocs.id as string;
|
||||
payload.retriever = selectedDocs.retriever as string;
|
||||
}
|
||||
}
|
||||
return conversationService
|
||||
.search(payload, token)
|
||||
.then((response) => response.json())
|
||||
|
||||
@@ -18,11 +18,11 @@ export default function useDefaultDocument() {
|
||||
const fetchDocs = () => {
|
||||
getDocs(token).then((data) => {
|
||||
dispatch(setSourceDocs(data));
|
||||
if (!selectedDoc)
|
||||
if (!selectedDoc || (Array.isArray(selectedDoc) && selectedDoc.length === 0))
|
||||
Array.isArray(data) &&
|
||||
data?.forEach((doc: Doc) => {
|
||||
if (doc.model && doc.name === 'default') {
|
||||
dispatch(setSelectedDocs(doc));
|
||||
dispatch(setSelectedDocs([doc]));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -90,9 +90,9 @@ export function getLocalApiKey(): string | null {
|
||||
return key;
|
||||
}
|
||||
|
||||
export function getLocalRecentDocs(): string | null {
|
||||
const doc = localStorage.getItem('DocsGPTRecentDocs');
|
||||
return doc;
|
||||
export function getLocalRecentDocs(): Doc[] | null {
|
||||
const docs = localStorage.getItem('DocsGPTRecentDocs');
|
||||
return docs ? JSON.parse(docs) as Doc[] : null;
|
||||
}
|
||||
|
||||
export function getLocalPrompt(): string | null {
|
||||
@@ -108,19 +108,20 @@ export function setLocalPrompt(prompt: string): void {
|
||||
localStorage.setItem('DocsGPTPrompt', prompt);
|
||||
}
|
||||
|
||||
export function setLocalRecentDocs(doc: Doc | null): void {
|
||||
localStorage.setItem('DocsGPTRecentDocs', JSON.stringify(doc));
|
||||
export function setLocalRecentDocs(docs: Doc[] | null): void {
|
||||
if (docs && docs.length > 0) {
|
||||
localStorage.setItem('DocsGPTRecentDocs', JSON.stringify(docs));
|
||||
|
||||
let docPath = 'default';
|
||||
if (doc?.type === 'local') {
|
||||
docPath = 'local' + '/' + doc.name + '/';
|
||||
docs.forEach((doc) => {
|
||||
let docPath = 'default';
|
||||
if (doc.type === 'local') {
|
||||
docPath = 'local' + '/' + doc.name + '/';
|
||||
}
|
||||
userService
|
||||
.checkDocs({ docs: docPath }, null)
|
||||
.then((response) => response.json());
|
||||
});
|
||||
} else {
|
||||
localStorage.removeItem('DocsGPTRecentDocs');
|
||||
}
|
||||
userService
|
||||
.checkDocs(
|
||||
{
|
||||
docs: docPath,
|
||||
},
|
||||
null,
|
||||
)
|
||||
.then((response) => response.json());
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ export interface Preference {
|
||||
prompt: { name: string; id: string; type: string };
|
||||
chunks: string;
|
||||
token_limit: number;
|
||||
selectedDocs: Doc | null;
|
||||
selectedDocs: Doc[] | null;
|
||||
sourceDocs: Doc[] | null;
|
||||
conversations: {
|
||||
data: { name: string; id: string }[] | null;
|
||||
@@ -34,7 +34,7 @@ const initialState: Preference = {
|
||||
prompt: { name: 'default', id: 'default', type: 'public' },
|
||||
chunks: '2',
|
||||
token_limit: 2000,
|
||||
selectedDocs: {
|
||||
selectedDocs: [{
|
||||
id: 'default',
|
||||
name: 'default',
|
||||
type: 'remote',
|
||||
@@ -42,7 +42,7 @@ const initialState: Preference = {
|
||||
docLink: 'default',
|
||||
model: 'openai_text-embedding-ada-002',
|
||||
retriever: 'classic',
|
||||
} as Doc,
|
||||
}] as Doc[],
|
||||
sourceDocs: null,
|
||||
conversations: {
|
||||
data: null,
|
||||
|
||||
Reference in New Issue
Block a user